در قسمت نوزدهم آموزش میکروکنترلرSTM8 راهاندازی PWM با تایمر۲ در میکروکنترلر STM8 را توضیح دادیم و نتیجه عملکرد آنرا با ۳عدد LED چشمکزن تستکردیم. در این قسمت آموزش میکروکنترلر STM8 قصد داریم راهاندازی PWM با تایمر۱ را موردبررسی قراردهیم. با ما همراه باشید.
PWM تایمر۱ :
تایمر۱ یک تایمر پیشرفته است، بنابراین PWMهایی که با این تایمر تولید میشوند دارای ویژگیهای اضافی نسبتبه دیگر تایمرها هستند. بهعنوانمثال، امکان تولید PWMهای مکمل با TIM1 وجود دارد. بیشاز ۳مجموعه PWM مکمل در میکروکنترلرSTM8 میتوان تولید کرد. بهعنوانمثال، PWMهای مورداستفاده در طراحی مبدل سه فاز، یکسوکنندهها و… . PWMهای تولیدشده با TIM1 برای برنامههای کنترل موتور بسیارمفید هستند. همچنین میتوان dead_time و brake را نیز اضافهنمود. علاوهبر اینها، TIM1 میتواند PWMهایی را مانند PWMهای ساختهشده توسط تایمر GP ایجاد کند. در اینحالت، خروجیهای PWM بهصورت آزاد دردسترس نیست و تا چهار کانال PWM مستقل میتواند دردسترس قرارگیرد.
در این مثال، خواهیمدید که چگونه میتوان PWMهای مکمل را در کانال 1 TIM1 PWM ایجادکرد.
اتصالات سختافزاری
نمونهکد PWM تایمر۱
#include "STM8S.h" #include "stm8s_it.h" void clock_setup(void); void GPIO_setup(void); void TIM1_setup(void); void main(void) { int j; signed int i = 0; clock_setup(); GPIO_setup(); TIM1_setup(); while(TRUE) { for(i = 0; i < 1000; i += 1) { TIM1_SetCompare1(i); for(j=1;j<0x5FFF;j++); } for(i = 1000; i > 0; i -= 1) { TIM1_SetCompare1(i); for(j=1;j<0x5FFF;j++); } }; } void clock_setup(void) { CLK_DeInit(); CLK_HSECmd(DISABLE); CLK_LSICmd(DISABLE); CLK_HSICmd(ENABLE); while(CLK_GetFlagStatus(CLK_FLAG_HSIRDY) == FALSE); CLK_ClockSwitchCmd(ENABLE); CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1); CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI, DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE); CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, DISABLE); CLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI, DISABLE); CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, DISABLE); CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU, DISABLE); CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART1, DISABLE); CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, ENABLE); CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, DISABLE); CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4, DISABLE); } void GPIO_setup(void) { GPIO_DeInit(GPIOC); GPIO_Init(GPIOC, GPIO_PIN_3|GPIO_PIN_6, GPIO_MODE_OUT_PP_HIGH_FAST); } void TIM1_setup(void) { TIM1_DeInit(); TIM1_TimeBaseInit(16, TIM1_COUNTERMODE_UP, 1000, 1); TIM1_OC1Init(TIM1_OCMODE_PWM1, TIM1_OUTPUTSTATE_ENABLE, TIM1_OUTPUTNSTATE_ENABLE, 1000, TIM1_OCPOLARITY_LOW, TIM1_OCNPOLARITY_LOW, TIM1_OCIDLESTATE_RESET, TIM1_OCNIDLESTATE_RESET); TIM1_CtrlPWMOutputs(ENABLE); TIM1_Cmd(ENABLE); }
توضیحات
اینبار از تمام ۱۶مگاهرتز سرعت HSI برای کلاک داخلی و CPU استفاده میکنیم:
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1); …. …. CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, ENABLE);
مانند مثالهای قبل، پینهای GPIO خروجی PWM بهعنوان خروجی تنظیم میشوند.
void GPIO_setup(void) { GPIO_DeInit(GPIOC); GPIO_Init(GPIOC, GPIO_PIN_3 |GPIO_PIN_6 , GPIO_MODE_OUT_PP_HIGH_FAST); }
تنظیم اولیه کانال TIM1 و OC درست همانند مثالقبلی با برخی تفاوتهای جزئی است. بهنظرمیرسد که بخش تولید زمان نیازبه استدلالهای اضافی دارد. به ایندلیل است که:
برخلاف تایمرهای دیگر، مقدار precaler TIM1 مقدارثابتی نیست و میتواند ضریبیاز ۲ باشد.
شمارنده علاوهبر شمارش روبهبالا، شمارش بهصورت معکوس را نیز دارد.
تایمر۱ شمارنده تکرارشونده نیز دارد.
بهجز تایمر اصلی تمامی تایمرهای STM8 دارای ۱۶بیت هستند.
اگر فایل هدر تایمر۱ را باز کنید، توابع بسیاری را خواهید دید. بسیاریاز این فانکشنها منحصراً برای تایمر۱ هستند که بیانگر قدرت این تایمر پیشرفته است.
بههمینترتیب، برخیاز اطلاعات اضافی که درهنگام تنظیم کانالهای OC موردنیاز است وجوددارد. حتی اگر از کانالهای مکمل استفادهنکنیم به اطلاعات آنها نیاز داریم. میتوان پلاریته را برای PWM درحالت پیشفرض قرار داد.
void TIM1_setup(void) { TIM1_DeInit(); TIM1_TimeBaseInit(16, TIM1_COUNTERMODE_UP, 1000, 1); TIM1_OC1Init(TIM1_OCMODE_PWM1, TIM1_OUTPUTSTATE_ENABLE, TIM1_OUTPUTNSTATE_ENABLE, 1000, TIM1_OCPOLARITY_LOW, TIM1_OCNPOLARITY_LOW, TIM1_OCIDLESTATE_RESET, TIM1_OCNIDLESTATE_RESET); TIM1_CtrlPWMOutputs(ENABLE); TIM1_Cmd(ENABLE); }
برای تغییر چرخه کار کانال، باید این تابع را فراخوانی کنیم:
TIM1_SetCompareX(duty_cycle); // where X represents channel ID (1, 2, 3 or 4)
خروجیها بهصورت جفتی اتفاق میافتند و آنها کاملاً بههم وابسته هستند. بههمیندلیل هیچ عملکرد جداگانهای برای خروجی با برچسب N وجود ندارد.
در قسمت بیستویکم از مجموعه آموزش میکروکنترلر STM8 قصد داریم به بررسی اجمالی ارتباطات بپردازیم. با ما همراه باشید.
منبع: سیسوگ