با سلام، در این قسمت از آموزشها میریم سراغ WDT در این میکروکنترلر این قسمت از آموزش بسیار ساده است، تا آخر آموزش با ما همراه باشید.
واچ داگ تایمری هست که با کلاکی مستقل از پردازنده وظیفه نگهبانی از پردازنده رو داره، کل کارش اینه که میگه اگر تا زمانی که تعیین کردید مقدار کانتر منو صفر یا ریست نکنید، من شما رو ریست میکنم که اگر یه زمانی پردازنده قادر به انجام روتینش نبود و هنگ کرده بود و نتونست واچ داگ رو ریست بکنه، کل پردازنده توسط واچ داگ ریست میشه.
در این میکرو مشابه STM32 و خیلی از میکرو های Arm دو نوع واچ داگ وجود داره یکیش مستقل هست و یکی پنجرهای که حالا توضیح و فرق جفتشونو میگیم:
عملکرد مستقل: این نوع تایمر بهصورت مستقل از دیگر تایمرها و عملکردهای سیستم کار میکند. این بدین معناست که IWDT میتواند در صورت بروز خطا حتی زمانی که بخشهای دیگر سیستم قفل شدهاند، سیستم را ریست کند.
پیکربندی ساده: معمولاً پیکربندی و استفاده از IWDT سادهتر از WWDT است. این تایمر به طور پیوسته و بدون نیاز به تنظیمات خاصی عمل میکند.
بدون پنجره زمانی: در IWDT، تایمر به طور پیوسته نظارت میکند و نیازی به تنظیم بازههای زمانی خاصی ندارد که سیستم باید در آنها پاسخ دهد.
پنجره زمانی: WWDT دارای یک پنجره زمانی مشخص است که در آن سیستم باید تایمر را ریست کند. اگر سیستم زودتر از موعد تعیین شده یا دیرتر از موعد این کار را انجام دهد، تایمر عمل کرده و سیستم را ریست میکند. این ویژگی کمک میکند تا سیستم در بازههای زمانی مشخص بهدرستی عمل کند.
انعطافپذیری بیشتر: باوجود پیچیدگی بیشتر در تنظیمات، WWDT انعطافپذیری بیشتری در نظارت و کنترل سیستم ارائه میدهد.
کاربردهای پیشرفته: این تایمر بیشتر در کاربردهای پیشرفتهتر و جایی که نیاز به نظارت دقیقتر بر عملکرد سیستم وجود دارد، استفاده میشود.
به طور خلاصه، IWDT سادهتر و مستقل است و برای کاربردهای عمومی مناسب است، در حالی که WWDT با داشتن پنجره زمانی انعطافپذیری بیشتری ارائه میدهد و برای کاربردهای پیشرفتهتر و نیاز به نظارت دقیقتر مناسبتر است.
خب پس از آشنایی با عملکردشون باید دیاگرام داخلیشون هم با هم ببینیم:
خب پس از آشنایی با خودشون بریم محاسباتشونو انجام بدیم که بتونیم ازشون درست استفاده کنیم.
برای محاسبه زمان Timeout تایمر مستقل میتونید از فرمول زیر استفاده کنید:
برای WWDT هم میتونید از فرمولی که خودش داده استفاده کنید:
خب پس از محاسبه بریم سراغ کد تست هر دو تایمر:
برای مستقل:
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 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | /********************************** (C) COPYRIGHT ******************************* * File Name : main.c * Author : WCH * Version : V1.0.0 * Date : 2021/06/06 * Description : Main program body. ********************************************************************************* * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. * Attention: This software (modified or not) and binary are used for * microcontroller manufactured by Nanjing Qinheng Microelectronics. *******************************************************************************/ /* *@Note USART Print debugging routine: USART1_Tx(PA9). This example demonstrates using USART1(PA9) as a print debug port output. */ #include "debug.h" /* Global typedef */ /* Global define */ /* Global Variable */ /********************************************************************* * @fn main * * @brief Main program. * * @return none */ int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); SystemCoreClockUpdate(); Delay_Init(); USART_Printf_Init(115200); printf("SystemClk:%d\r\n",SystemCoreClock); printf( "ChipID:%08x\r\n", DBGMCU_GetCHIPID() ); printf("This is printf example\r\n"); IWDG_Enable(); IWDG_SetPrescaler(IWDG_Prescaler_64); IWDG_SetReload(IWDG_Prescaler_8); IWDG_ReloadCounter(); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitTypeDef GPIO_KEY_STCT; GPIO_KEY_STCT.GPIO_Mode = GPIO_Mode_IPU; //INPUT PULL UP GPIO_KEY_STCT.GPIO_Pin = 0; GPIO_Init(GPIOA,&GPIO_KEY_STCT); while(1) { while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==0) { ////One loop with out WDT Reset } IWDG_ReloadCounter(); } } |
برای اینکه تایمر میکرو رو ریست نکنه قبل از سرریزشدن با استفاده از تابع IWDG_ReloadCounter() مقدارشو ریست کنید.
این برنامه زمانی که GPIOA.0 زمین بشه مانع ریست واچ داگ میشه و میکرو ریست میشه.
برای تایمر پنجرهای:
برای اینکه تایمر میکرو رو ریست نکنه باید در زمان مجازی ک حساب کردید ریستش کنید هم کمترش مجاز نیست هم بیشترش، تا میکرو ریست نشه.
این برنامه زمانی که GPIOA.0 زمین بشه مانع ریست واچ داگ میشه و میکرو ریست میشه.
برای تایمر پنجرهای:
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 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | /********************************** (C) COPYRIGHT ******************************* * File Name : main.c * Author : WCH * Version : V1.0.0 * Date : 2021/06/06 * Description : Main program body. ********************************************************************************* * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. * Attention: This software (modified or not) and binary are used for * microcontroller manufactured by Nanjing Qinheng Microelectronics. *******************************************************************************/ /* *@Note USART Print debugging routine: USART1_Tx(PA9). This example demonstrates using USART1(PA9) as a print debug port output. */ #include "debug.h" /* Global typedef */ /* Global define */ /* Global Variable */ uint8_t WWDG_GetCounter(void) { return (WWDG->CTLR & WWDG_CTLR_T); } /********************************************************************* * @fn main * * @brief Main program. * * @return none */ int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); SystemCoreClockUpdate(); Delay_Init(); USART_Printf_Init(115200); printf("SystemClk:%d\r\n",SystemCoreClock); printf( "ChipID:%08x\r\n", DBGMCU_GetCHIPID() ); printf("This is printf example\r\n"); //////////////////////////////////////////////////////////////////////////WWDG RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); WWDG_SetPrescaler(WWDG_Prescaler_8); WWDG_SetWindowValue(0x7F); WWDG_SetCounter(0x7F); WWDG_Enable(0x7F); //////////////////////////////////////////////////////////////////////////GPIOA RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitTypeDef GPIO_KEY_STCT; GPIO_KEY_STCT.GPIO_Mode = GPIO_Mode_IPU; //INPUT PULL UP GPIO_KEY_STCT.GPIO_Pin = 0; GPIO_Init(GPIOA,&GPIO_KEY_STCT); while(1) { while (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0) { } if (WWDG_GetCounter() < 0x50) { WWDG_SetCounter(0x7F); } } } |
تا قسمت بعدی شما را به خدا میسپارم.
نویسنده شو !
سیسوگ با افتخار فضایی برای اشتراک گذاری دانش شماست. برای ما مقاله بنویسید.