历史上的今天
今天是:2024年08月29日(星期四)
2019年08月29日 | STM32F429 >> 16. WWDG_窗口看门狗
2019-08-29 来源:eefocus
窗口看门狗和独立看门狗最大的不同就是,独立看门狗的喂狗限制是在计数器递减为零前,而窗口看门狗的喂狗限制则是在一个窗口期内,即喂狗时间必须在一个时间段内,在狗饱腹时和饥饿时喂狗都会触发复位
这个窗口期的下限为0x40,上限小于或等于0x7F

RLR 是重装载寄存器,用来设置独立看门狗的计数器的值。TR 是窗口看门狗的计数器的值,由用户独立设置,WR 是窗口看门狗的上窗口值,由用户独立设置。
WWDG 功能框图

①. 窗口看门狗时钟
窗口看门狗时钟来自 PCLK1,PCLK1 最大是 45M,由 RCC 时钟控制器开启。
②. 计数器时钟
计数器时钟由 CK 计时器时钟经过预分频器分频得到,分频系数由配置寄存器 CFR 的位8:7 WDGTB[1:0]配置,可以是[0,1,2,3],其中 CK 计时器时钟=PCLK1/4096,除以 4096是固定死的。所以计数器的时钟 CNT_CK=PCLK1/4096/(2^WDGTB),这就可以算出计数器减一个数的时间 T= 1/CNT_CK = Tpclk1 * 4096 * (2^WDGTB)。
③. 计数器
窗口看门狗的计数器是一个递减计数器,共有 7 位,其值存在控制寄存器 CR 的位 6:0,即 T[6:0],当 7 个位全部为 1 时是 0X7F,这个是最大值,当递减到 T6 位变成 0 时,即从0X40 变为 0X3F 时候,会产生看门狗复位。
这个值 0X40 是看门狗能够递减到的最小值,所以计数器的值只能是:0X40~0X7F 之间,实际上用来计数的是 T[5:0]。
当递减计数器递减到 0X40 的时候,还不会马上产生复位,如果使能了提前唤醒中断:CFR 位 9 EWI 置 1,则产生提前唤醒中断,如果真进入了这个中断的话,就说明程序肯定是出问题了,那么在中断服务程序里面我们就需要做最重要的工作,比如保存重要数据,或者报警等,这个中断我们也叫它死前中断。
④. 窗口值
窗口看门狗必须在一个窗口期内才可以喂狗,其中下窗口的值是固定的 0X40,上窗口的值可以改变,具体的由配置寄存器 CFR 的位 6:0 W[6:0]设置。
其值必须大于或等于 0X40,小于或等于 0X7F。
如果我们要监控的程序段 A 运行的时间为 Ta,当执行完这段程序之后就要进行喂狗,如果在窗口时间内没有喂狗的话,那程序就肯定是出问题了。一般计数器的值 TR 设置成最大 0X7F,窗口值为 WR,计数器减一个数的时间为 T,那么时间:(TR-WR)*T 应该稍微大于 Ta 即可,这样就能做到刚执行完程序段 A 之后喂狗,起到监控的作用,这样也就可以算出 WR 的值是多少。
计算看门狗超时时间

已知看门狗当值到达0x40,然后再减一为0x3F 时即触发复位,
故其计数器计数时长最短为0x40-0x3F = 1;
其计数器计数时长最长为0x7F-0x3F = 0x40 = 64;
故上表中当预分频器为1时最小超时即通过Tpclk1 * 4096 * (2^WDGTB) = 1/30 * 4096 *2^0 = 136.53us 计算而得;
最大超时即通过Tpclk1 * 4096 * (2^WDGTB) * 64= 1/30 * 4096 *2^0 = 8.74ms 计算而得。
在窗口看门狗的配置当中,比独立看门狗多了一个可选配置项“遗嘱中断”,即唤醒中断WWDG Early Wakeup interrupt(EWI),可在计数器递减到0x40 即将复位时触发一个中断,在这个中断中可做一些较为重要的事情,如保存发送数据等。
bsp_wwdg.h
/**
******************************************************************************
* @file bsp_wwdg.h
* @author Waao
* @version V1.0.0
* @date 15-Feb-2019
* @brief This file contains some board support package's definition for the WWDG.
*
******************************************************************************
* @attention
*
* None
*
******************************************************************************
*/
#ifndef __BSP_WWDG_H_
#define __BSP_WWDG_H_
#include #include #define WWDG_CLK RCC_APB1Periph_WWDG #define WWDG_IRQChannel WWDG_IRQn void WWDG_Config(void); void NVIC_WWDG_Config(void); void Feed_WWDG(void); #endif bsp_wwdg.c /** ****************************************************************************** * @file bsp_wwdg.c * @author Waao * @version V1.0.0 * @date 15-Feb-2019 * @brief This file contains some board support package's functions for the WWDG. * ****************************************************************************** * @attention * * None * ****************************************************************************** */ #include #include /** * @brief Configure the WWDG * @param None * @retval None */ void WWDG_Config(void) { //We must to enable the clock of the WWDG before using the WWDG. RCC_APB1PeriphClockCmd(WWDG_CLK, ENABLE); NVIC_WWDG_Config(); WWDG_SetPrescaler(WWDG_Prescaler_8); WWDG_SetWindowValue(0x7F); WWDG_EnableIT(); WWDG_Enable(0x7F); } /** * @brief Configure the NVIC * @param None * @retval None */ void NVIC_WWDG_Config(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQChannel; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } /** * @brief Set the counter of the WWDG * @param None * @retval None */ void Feed_WWDG(void) { WWDG_SetCounter(0x7F); } stm32f4xx_it.c /** * @brief Configure the WWDG Early Wakeup interrupt(EWI) * @param None * @retval None */ void WWDG_IRQHandler(void) { //You should do something most important in this function... WWDG_ClearFlag(); LED_BLUE; } main.c #include #include #include #include int main(void) { u8 WWDG_Window_Value = 0; USART_GPIO_Config(); USART1_Config(); SysTick_Init(); LED_GPIO_Config(); LED_RED; //Delay 0.5s Delay(50000); LED_GREEN; /* Since the Official Function Lib doesn't provide the function to get the value of the counter, * So we can only get the counter value through operating the register. */ WWDG_Window_Value = WWDG->CFR & 0x7F; while(1) { //If you feed the dog here, the program will reset. //Feed_WWDG(); while((WWDG->CR & 0x7F) < WWDG_Window_Value) { Feed_WWDG(); } } }
史海拾趣
|
我有一个多普达828的主板,系统是WM6.1 CPU是PXA272 ROM是128M RAM是64M,手机\\PDA功能都正常.这个主板有三个UART,其中一个STUART应该接红外端口用来进行红外数据传输.我把红外的驱动卸载了(也就是把驱动用的DLL改了名)然后,对这个RXD ...… 查看全部问答> |
|
跪求eeworld的朋友们给我一个步进电机的嵌入式驱动程序,或者给我一个可以学习和参考的内容.我的一个设计是关于步进电机的嵌入式驱动程序的.请赐教. 电子邮件:blueink_200451@hotmail.com qq:279697361 请写:步进电机 或 嵌入式驱动程序 和任何和 ...… 查看全部问答> |
|
各位达人,你们好!我是一名大三的学生,我的专业是电子信息工程,读大二的时候因为没有用心好好学数电,模电,特别是高频,现在我参加了单片机培训,对单片机比较感兴趣,想扎实学好单片机这门技术,学校也开了数字信号处理,老师说非常重要,因为 ...… 查看全部问答> |
|
各位大虾: 现在小弟急用关于单片机的英文资料,在网上找了半天没找到! 希望大家帮帮忙啊!能有对应的中文翻译更好!英文大概5000字符的,多了当然更好! 谢谢了!! 我的邮箱:s1029384756@163.com QQ:3052847 ...… 查看全部问答> |




