در قسمت هجدهم آموزش میکروکنترلرSTM8 تایمر۴ را بهشما معرفیکردیم و برنامه آن را باهم بررسیکردیم. در این قسمت از مجموعه مقالات آموزش میکروکنترلر STM8 قصد داریم ویژگی پرکاربرد PWM را بررسیکند. با ما همراه باشید.
PWM :
تایمر۲ یا بهعبارتی PWM جز ویژگیهای مهم هر میکروکنترلر است. PWM کاربردهای بسیاری ازجمله کنترل موتور، SMPSها، کنترل روشنایی، تولید صدا، تولید موج و غیره را دارد. برخلاف دیگر میکروکنترلرها که کانالهای PWM محدودی دارند، STM8 دارای چندین کانال PWM است، که تعدادی از آنها بهعنوان تایمر۲ (تایمر عمومی) هستند. بهعنوانمثال، STM8S003F دارای سه کانال PWM مستقل است.
PWMهایی که توسط تایمر عمومی تولید میشوند، PWMهای اولیه هستند. اینها میتوانند برای کارهای سادهای همچون کنترل روشنایی LED، کنترل موتور و… مورداستفاده قرارگیرند که نیازیبه ویژگیهای پیشرفته مانند dead-time brake یا تولید زمان موج را ندارد. در این بخش نحوهی استفادهاز تایمر۲ برای تولید PWMهای ساده را خواهیمدید.
توجهداشتهباشید که در میکروکنترلرهای پیشرفته STM8 ورودی/خروجیهای تایمر به عملکرد بیتهای پیکربندی بستگی دارد. قبلاز بارگذاری کد این بیتها را بررسیکنید. در برخی میکروکنترلرهای STM8 ورودی/خروجیها قابلانتقال هستند، بدینمعنی که ورودی/خروجی را میتوان در GPIO های مختلف مبادله کرد. درصورتنیاز می توانید از STM8CubeMx استفادهکنید.
اتصالات سختافزاری
نمونهکد PWM
این یک مثال بسیارساده است. در اینجا هر ۳ کانال تایمر۲ برای تغییرنور LEDهای متصلبه کانالهای تایمر استفاده میشود.
#include "STM8S.h" void clock_setup(void); void GPIO_setup(void); void TIM2_setup(void); void main(void) { int j; signed int pwm_duty = 0x0000; clock_setup(); GPIO_setup(); TIM2_setup(); while(TRUE) { for(pwm_duty = 0; pwm_duty < 1000; pwm_duty += 10) { TIM2_SetCompare1(pwm_duty); TIM2_SetCompare2(pwm_duty); TIM2_SetCompare3(pwm_duty); for(j=0;j<0x00DF;j++); } for(pwm_duty = 1000; pwm_duty > 0; pwm_duty -= 10) { TIM2_SetCompare1(pwm_duty); TIM2_SetCompare2(pwm_duty); TIM2_SetCompare3(pwm_duty); for(j=0;j<0x00DF;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_HSIDIV8); CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1); CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI, DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE); CLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI, DISABLE); CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, DISABLE); CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, DISABLE); CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU, DISABLE); CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART1, DISABLE); CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, DISABLE); CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, ENABLE); CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4, DISABLE); } void GPIO_setup(void) { GPIO_DeInit(GPIOA); GPIO_Init(GPIOA, GPIO_PIN_3, GPIO_MODE_OUT_PP_HIGH_FAST); GPIO_DeInit(GPIOD); GPIO_Init(GPIOD, ((GPIO_Pin_TypeDef)GPIO_PIN_3 | GPIO_PIN_4), GPIO_MODE_OUT_PP_HIGH_FAST); } void TIM2_setup(void) { TIM2_DeInit(); TIM2_TimeBaseInit(TIM2_PRESCALER_32, 1000); TIM2_OC1Init(TIM2_OCMODE_PWM1, TIM2_OUTPUTSTATE_ENABLE, 1000, TIM2_OCPOLARITY_HIGH); TIM2_OC2Init(TIM2_OCMODE_PWM1, TIM2_OUTPUTSTATE_ENABLE, 1000, TIM2_OCPOLARITY_LOW); TIM2_OC3Init(TIM2_OCMODE_PWM1, TIM2_OUTPUTSTATE_ENABLE, 1000, TIM2_OCPOLARITY_HIGH); TIM2_Cmd(ENABLE); }
توضیحات
این بار نیز CPU و کلاکداخلی در ۲مگاهرتز تنظیم میشوند.
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8); CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1); …. …. CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, ENABLE);
سپس باید PWM GPIOها را بهعنوان خروجی تعریفکنیم.
void GPIO_setup(void) { GPIO_DeInit(GPIOA); GPIO_Init(GPIOA, GPIO_PIN_3, GPIO_MODE_OUT_PP_HIGH_FAST); GPIO_DeInit(GPIOD); GPIO_Init(GPIOD, ((GPIO_Pin_TypeDef)GPIO_PIN_3 | GPIO_PIN_4), GPIO_MODE_OUT_PP_HIGH_FAST); }
درست مانند دیگر میکروکنترلرها، نسل PWM شامل یک تایمر است. همانطور که گفتیم TIM2 یک تایمر است. باید قبلاز اینکه کانال PWM را تنظیمکنیم، در ابتدا زمان را تنظیمکنیم.
void TIM2_setup(void) { TIM2_DeInit(); TIM2_TimeBaseInit(TIM2_PRESCALER_32, 1000); TIM2_OC1Init(TIM2_OCMODE_PWM1, TIM2_OUTPUTSTATE_ENABLE, 1000, TIM2_OCPOLARITY_HIGH); TIM2_OC2Init(TIM2_OCMODE_PWM1, TIM2_OUTPUTSTATE_ENABLE, 1000, TIM2_OCPOLARITY_LOW); TIM2_OC3Init(TIM2_OCMODE_PWM1, TIM2_OUTPUTSTATE_ENABLE, 1000, TIM2_OCPOLARITY_HIGH); TIM2_Cmd(ENABLE); }
در کدهای بالا، تایمر۲ دارای پایهی زمانی ۱۶ms یا ۶۲.۵KHz است. این پایه زمانی مجدداً توسط واحد مقایسهکننده خروجی (OC) تقسیم میشود. در اینجا پایه ۶۲.۵KHz به ۱۰۰۰ تقسیم میشود تا فرکانس PWM ۶۲.۵Hz حاصلشود. حداکثر چرخهی کاری ۱۰۰۰ است. علاوهبر این، می توانیم پلاریته PWM را تنظیمکنیم و به کانال فرمان دهیم که بهصورت معکوس عملکند یا نه.
برای تغییر وظیفه PWM باید تابعزیر را فراخوانیکنیم:
TIM2_SetCompareX(pwm_duty); where X represents channel ID (1, 2 or 3)
توجهداشتهباشید که در میکروکنترلرهای STM8 بین فرکانس کاری و فرکانس PWM تبادلی وجود دارد. اگر فرکانس کاری بزرگ باشد فرکانس PWM کوچک است و برعکس. این موضوع برای تمامی تایمرها صادق است.
در قسمت بیستم از مجموعه آموزش میکروکنترلر STM8 قسمت PWM تایمر۱ را موردبررسی قرار میدهد. با ما همراه باشید.
منبع:سیسوگ