در قسمت دوازدهم از آموزش میکروکنترلر STM8 مبحث مهم و کاربردی مبدل آنالوگ به دیجیتال (ADC) را آموزشداد. در این قسمت از مجموعه مقالات قصد داریم شما را با ویژگی کاربردی تایمر نگهبان آنالوگ (Analog Watchdog) آشنا کنیم. با ما همراه باشید.
تایمر نگهبان آنالوگ (AWD)
AWD یکیاز ویژگیهای اضافی است که اکثر میکروکنترلرهای موجود در بازار این ویژگی را ندارند. AWD بسیار شبیهبه مقایسهکننده است با این تفاوت که میتوان حد بالا و پایین مقایسه را متناسب با نیاز خود تنظیمکنیم، درصورتیکه دیگر میکروکنترلرها دارای حدود بالا و پایین ثابتی هستند. محدوده بین حدود بالا و پایین منطقه حفاظتشده نامیده میشود. فراتر از منطقه حفاظتشده AWD شروعبهکار میکند.
واحد AWD درشرایطیکه بخواهیم برروی خروجی یک حسگر نظارت داشتهباشیم و اقداماتسریع انجامدهیم بسیار مناسب است. بهعنوانمثال، یک کنترلکننده دما را درنظر بگیرید. میخواهیم کنترلکننده بدون محاسبات پیچیده در زمانی که دمای محیط پایینتر از حد تعیینشده است سیستم گرمایش را روشن و زمانی که دما به حد بالای خود رسید سیستم گرمایش را خاموشکند. در میکروکنترلرهای دیگر این کار ساده بااستفادهاز دستورات شرطی IF-ELSE انجام میشود.
اتصالات سختافزاری
نمونهکد AWD
#include "STM8S.h" #include "STM8S_LCD.h" void clock_setup(void); void GPIO_setup(void); void ADC1_setup(void); void lcd_print(unsigned char x_pos, unsigned char y_pos, unsigned int value); void main() { int j; unsigned int a1 = 0x0000; clock_setup(); GPIO_setup(); ADC1_setup(); LCD_init(); LCD_clear_home(); LCD_goto(4, 0); LCD_putstr("STM8 AWD"); LCD_goto(4, 1); LCD_putstr("A1"); while (TRUE) { ADC1_ClearFlag(ADC1_FLAG_EOC); ADC1_StartConversion(); while(ADC1_GetFlagStatus(ADC1_FLAG_EOC) == 0); a1 = ADC1_GetConversionValue(); lcd_print(8, 1, a1); if(ADC1_GetFlagStatus(ADC1_FLAG_AWD)) { GPIO_WriteReverse(GPIOD, GPIO_PIN_3); ADC1_ClearFlag(ADC1_FLAG_AWD); } else { GPIO_WriteHigh(GPIOD, GPIO_PIN_3); } for(j=0;j<0x0FFF;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_HSIDIV2); CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV4); 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, ENABLE); CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU, DISABLE); CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART1, DISABLE); CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, DISABLE); CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, DISABLE); CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4, DISABLE); } void GPIO_setup(void) { GPIO_DeInit(GPIOD); GPIO_Init(GPIOD, GPIO_PIN_2, GPIO_MODE_IN_FL_NO_IT); GPIO_Init(GPIOD, GPIO_PIN_3, GPIO_MODE_OUT_PP_HIGH_FAST); } void ADC1_setup(void) { ADC1_DeInit(); ADC1_Init(ADC1_CONVERSIONMODE_SINGLE, ADC1_CHANNEL_3, ADC1_PRESSEL_FCPU_D10, ADC1_EXTTRIG_GPIO, DISABLE, ADC1_ALIGN_RIGHT, ADC1_SCHMITTTRIG_CHANNEL3, DISABLE); ADC1_AWDChannelConfig(ADC1_CHANNEL_3, ENABLE); ADC1_SetHighThreshold(800); ADC1_SetLowThreshold(400); ADC1_Cmd(ENABLE); } void lcd_print(unsigned char x_pos, unsigned char y_pos, unsigned int value) { char chr = 0x00; chr = ((value / 1000) + 0x30); LCD_goto(x_pos, y_pos); LCD_putchar(chr); chr = (((value / 100) % 10) + 0x30); LCD_goto((x_pos + 1), y_pos); LCD_putchar(chr); chr = (((value / 10) % 10) + 0x30); LCD_goto((x_pos + 2), y_pos); LCD_putchar(chr); chr = ((value % 10) + 0x30); LCD_goto((x_pos + 3), y_pos); LCD_putchar(chr); }
توضیحات
کد AWD درست مانند کد ADC بیانشده در قسمت دوازدهم است. با اینتفاوت که در اینجا از کانال ۳ استفاده کردهایم. راهاندازی AWD ساده است. فقط کافیاست محدودیتها را تعیینکنیم و مشخصکنیم کدام کانال باید نظارتشود و AWD را فعالکنیم.
ADC1_AWDChannelConfig(ADC1_CHANNEL_3, ENABLE); ADC1_SetHighThreshold(800); ADC1_SetLowThreshold(400);
در اینجا ما مقدار ۶۰۰ و ۲۰۰ را بهترتیب برای حدود بالا و پایین ADC تنظیمکردیم.
در تابع اصلی، ما بهسادگی وضعیت AWD را بررسی میکنیم. اگر AWD در پین PD2 رخ میدهد (خارجشدن از منطقه مرزی) LED در PD3 شروعبه چشمکزدن میکند. اگر PD2 مقداری بین ۴۰۰ تا ۸۰۰ ADC را بدستآورد، LED روشن میشود، که نشاندهنده منطقهی محافظتشده است.
if(ADC1_GetFlagStatus(ADC1_FLAG_AWD)) { GPIO_WriteReverse(GPIOD, GPIO_PIN_3); ADC1_ClearFlag(ADC1_FLAG_AWD); } else { GPIO_WriteHigh(GPIOD, GPIO_PIN_3); }
در قسمت چهاردهم آموزش میکروکنترلر STM8 قصد داریم تایمر نگهبان IWDG را آموزش دهیم. مثل همیشه با ما همراه باشید.
منبع: سیسوگ