سیسوگ در قسمت سیزدهم آموزش میکروکنترلر STM8 به ویژگی کاربردی تایمر نگهبان آنالوگ (Analog Watchdog) پرداخت. در این قسمت از مجموعه مقالات آموزش میکروکنترلر STM8 قصد دارد تایمر نگهبانی را که در اکثر میکروکنترلرها وجود دارد به شما آموزش دهد. با سیسوگ همراه باشید تا تایمر نگهبان (IWDG) را فرا گیرید.
تایمر نگهبان (IWDG)
IWDG یک تایمر نگهبان معمولی است که در اکثر میکروکنترلرهای مدرن دیده میشود. هدف این تایمر این است که از میکروکنترلر در مقابل رویدادهای غیرمنتظره که به دلایل غیر متعارف رخ میدهد محافظت کند. همانطور که از نام آن مشخص است، این تایمر چیزی را با سخت افزارهای جانبی داخلی به اشتراک نمیگذارد و تنها با فرکانس (LSI (128KHz کار میکند. بنابراین، با کلاکهای اصلی (HSE یا HSI) کار نمیکند.
IWDG به صورت شمارش معکوس کار میکند. هنگامی که شمارنده به صفر برسد، فرمان ریست صادر میشود. معمولاً ما میخواهیم که فرمان ریست هرگز اتفاق نیفتد بنابراین شمارنده به صورت دورهای به روز میشود. اگر به هر دلیلی، شمارنده به روز نشود، ریست اتفاق میافتد و MCU را از یک وضعیت فاجعه بار! نجات میدهد.
پیکربندی IWDG با SPL بسیار ساده است. مراحل خاصی برای پیگیری وجود دارد، اما SPI آنها را به صورت داخلی مدیرت میکند. نیاز داریم که IWDG را پیکربندی کنیم و قبل از اتمام زمان آن را مجدداً بارگیری کنیم.
فرمول مورد نیاز برای محاسبه وقفه در زیر داده شده است:
مقادیر معمول از زمان وقفه در زیر نشان داده شده است:
اتصالات سخت افزاری
نمونه کد IWDG
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | #include "STM8S.h" void clock_setup(void); void GPIO_setup(void); void IWDG_setup(void); void main(void) { unsigned int t = 0; clock_setup(); GPIO_setup(); GPIO_WriteLow(GPIOD, GPIO_PIN_3); for(t = 0; t < 60000; t++); IWDG_setup(); while(TRUE) { GPIO_WriteReverse(GPIOD, GPIO_PIN_3); for(t = 0; t < 1000; t++) { if(GPIO_ReadInputPin(GPIOB, GPIO_PIN_5) == FALSE) { IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); IWDG_ReloadCounter(); IWDG_WriteAccessCmd(IWDG_WriteAccess_Disable); } } }; } void clock_setup(void) { CLK_DeInit(); CLK_HSECmd(DISABLE); CLK_LSICmd(ENABLE); while(CLK_GetFlagStatus(CLK_FLAG_LSIRDY) == FALSE); CLK_HSICmd(ENABLE); while(CLK_GetFlagStatus(CLK_FLAG_HSIRDY) == FALSE); CLK_ClockSwitchCmd(ENABLE); CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8); 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, DISABLE); 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(GPIOB); GPIO_DeInit(GPIOD); GPIO_Init(GPIOB, GPIO_PIN_5, GPIO_MODE_IN_PU_NO_IT); GPIO_Init(GPIOD, GPIO_PIN_3, GPIO_MODE_OUT_PP_LOW_FAST); } void IWDG_setup(void) { IWDG_Enable(); IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); IWDG_SetPrescaler(IWDG_Prescaler_128); IWDG_SetReload(0x99); IWDG_WriteAccessCmd(IWDG_WriteAccess_Disable); } |
توضیحات
در این مثال، به کلاک خارجی و کلاک CPU کاری نداریم چرا که IWDG به آنها وابسته نیست. میتوانیم ببینیم که CPU با کلاک 500 کیلوهرتز کار میکند، در حالیکه کلاک خارجی 2 مگاهرتز است.
1 2 | CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8); CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV4); |
برای راه اندازی IWDG ابتدا باید آن را فعال کرد و سپس Write Access Protection را اعمال نمود (0x55). فقط باید مقدار precaler و مقدار شمارنده را تنظیم کنیم. شمارنده معکوس از این شماره شروع میکند و تا صفر میشمارد، مگر اینکه در این بین رفرش شود. در این مثال، precaler روی مقدار 128 تنظیم شده و مقدار بارگذاری مجدد روی 153 (0x99) تنظیم شده است. بنابراین، ما زمانی حدود 300ms را دریافت میکنیم. پس از اینکه این مقادیر را وارد کردیم باید از تغییرات تصادفی در سیستم عامل جلوگیری کرد و بنابراین باید دسترسی به نوشتن غیرفعال شود.
1 2 3 4 5 6 7 8 | void IWDG_setup(void) { IWDG_Enable(); IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); IWDG_SetPrescaler(IWDG_Prescaler_128); IWDG_SetReload(0x99); IWDG_WriteAccessCmd(IWDG_WriteAccess_Disable); } |
در ابتدا قبل از اینکه IWDG پیکربندی شود، LED روشن میشود که نشان دهنده شروع به کار سیستم عامل است. در حلقه اصلی، با یک تأخیر زمانی در حلقه “for” تغییر وضعیت میدهد. در داخل حلقه، وضعیت کلید نیز مورد نظر است. اگر کلید پایین نگهداشته شود به معنای حالت منطقی پایین خواهد بود و IWDG مجدداً بارگذاری میشود. اگر وضعیت به حالت منطقی بالا تغییر کند و 300ms سپری شود، ریست اتفاق میافتد.
1 2 3 4 5 6 7 8 9 10 | GPIO_WriteReverse(GPIOD, GPIO_PIN_0); for(t = 0; t < 1000; t++) { if(GPIO_ReadInputPin(GPIOB, GPIO_PIN_7) == FALSE) { IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); IWDG_ReloadCounter(); IWDG_WriteAccessCmd(IWDG_WriteAccess_Disable); } } |
توجه داشته باشید که ممکن است LSI کالیبراسیون شود. البته این اتفاق به ندرت پیش میآید.
در قسمت پانزدهم آموزش میکروکنترلر STM8 سیسوگ قصد دارد تایمر نگهبان محدوده ای (WWDG) را آموزش دهد. با سیسوگ همراه باشید.
لینکهای دانلود
مطالب مرتبط
- قسمت اول − میکروکنترلر STM8 چیست و از کجا آمده است؟
- قسمت دوم − معرفی بردهای Discovery میکروکنترلر STM8
- قسمت سوم − کامپایلر و پروگرامر
- قسمت چهارم − STM8CubeMX
- قسمت پنجم − آماده سازی ابزارهای نرمافزاری برای STM8
- قسمت ششم − چگونه برنامه خود را روی STM8 آپلود کنیم؟
- قسمت هفتم− LED چشمکزن
- قسمت هشتم − کلاک سیستم (CLK)
- قسمت نهم − وقفه خارجی (EXTI)
- قسمت دهم − Beeper
- قسمت یازدهم − LCD کاراکتری
- قسمت دوازدهم − مبدل آنالوگ به دیجیتال (ADC)
- قسمت سیزدهم − تایمر نگهبان آنالوگ (AWD)
- قسمت چهادهم − تایمر نگهبان (IWDG)
- قسمت پانزدهم − تایمر نگهبان محدوده ای (WWDG)
- قسمت شانزدهم− اصول اولیه تایمرها
- قسمت هفدهم− تایمر 2
- قسمت هجدهم −تایمر 4
- قسمت نوزدهم −PWM
- قسمت بیستم − PWM تایمر 1
- قسمت بیست و یکم − بررسی اجمالی ارتباطات
- قسمت بیست و دوم − رابط سریال (UART)
- قسمت بیست و سوم − رابط کاربری سریال (SPI)
- قسمت بیست و چهارم − رابط I2C
- دوره رایگان آموزش میکروکنترلر STM8 – سیسوگ
ممنون
آیا امکانش هست پروژه های پیشرفته تری مثل کار با ماژول های مختلف رو با این میکرو آموزش بدید.
متاسفانه محدودیت زمان داریم
سلام وقت بخیر
1. این کد در قسمت main قبل شروع حلقه while برای چه منظوری نوشته شده؟ for(t = 0; t < 60000; t++); همچین کدهایی رو زیاد استفاده می کنید ولی دلیلش رو نمیدونم.
2. در جدولی که عکسش رو گذاشتین لطفا در مورد نحوه محاسبه timeout یک توضیح مختصری بدید
ممنون
سلام دوست عزیز
۱. این کار برای ایجاد تاخیر هست
۲. فرمولش بالاتر هست – ببینید واچ داگ داخلی از نوسان ساز LSI که فرکانس ثابتی داره و معادل ۱۲۸ کیلوهرتز است تغزیه میشه و ما میتونیم این سورس کلاک رو به اعداد خاصی که توی دیتاشیت ذکر شده تقسیم کنیم، با تقسیم اون زمان های ذکر شده ایجاد خواهند شد.