一.窗口看门狗的原理:
简单来讲:就是有个递减计数器:
从(0x7f)127开始递减——>64(0x40).
并有一个窗口值来划分:递减到喂狗的有效区域。(值:0x7f~0x40)
其中FPCK1:
二.程序:
/* WWDG 配置函数
* tr :递减计时器的值, 取值范围为:(127)0x7f~0x40(64),超出范围会直接复位
* wr :窗口值,取值范围为:0x7f~0x40
* prv:预分频器值,取值可以是
* @arg WWDG_PRESCALER_1: WWDG counter clock = (PCLK1(42MHz)/4096)/1
约10254hz -> 98us
* @arg WWDG_PRESCALER_2: WWDG counter clock = (PCLK1(42MHz)/4096)/2
约5127Hz 195us
* @arg WWDG_PRESCALER_4: WWDG counter clock = (PCLK1(42MHz)/4096)/4
约3296Hz 390us
* @arg WWDG_PRESCALER_8: WWDG counter clock = (PCLK1(42MHz)/4096)/8
约1648Hz (1/1648)*1000= 781us
*
* 例:tr = 127(0x7f,tr的最大值)
* wr = 80(0x50, 0x40为最小wr最小值)
* prv = WWDG_PRESCALER_8
* 窗口时间为781 * (127-80) us= 36.7ms < 刷新窗口 < 781*( 127-64)us = 49.2ms
* 也就是说调用WWDG_Config进行这样的配置,若在之后的36.7ms前喂狗,
* 系统会复位,在49.2ms后没有喂狗,系统也会复位。
* 需要在刷新窗口的时间内喂狗,系统才不会复位。
*/
void WWDG_Config(uint8_t tr, uint8_t wr, uint32_t prv)
{
WWDG_HandleTypeDef WWDG_Handle;
// 开启 WWDG 时钟
__WWDG_CLK_ENABLE();
// 配置WWDG中断优先级
WWDG_NVIC_Config();
// 配置WWDG句柄即寄存器基地址
WWDG_Handle.Instance = WWDG;
// 设置预分频器值
WWDG_Handle.Init.Prescaler = prv;
// 设置上窗口值
WWDG_Handle.Init.Window = wr;
// 设置计数器的值
WWDG_Handle.Init.Counter = tr;
// 使能提前唤醒中断
WWDG_Handle.Init.EWIMode = WWDG_EWI_ENABLE;
// 初始化WWDG
HAL_WWDG_Init(&WWDG_Handle);
}
// 喂狗
void WWDG_Feed(void)
{
// 喂狗,刷新递减计数器的值,设置成最大WDG_CNT=0X7F
HAL_WWDG_Refresh(&WWDG_Handle);
}
//对应窗口看门狗的回调任务,内部进行喂狗操作
void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef* hwwdg)
{
//串口看门狗,喂狗是精准喂狗,
//喂早喂完都会引起系统复位。时间(42000000/4096)/8, 780us
// (127-64)*780us << 喂狗 <<(127-64)*780us , 5ms内进行喂狗就不会复位,
// 当系统卡死,如串口有大量数据导致死机,此时喂狗如不能在5ms内喂狗,就会产生复位。
//可通过:输出打印喂狗信息来判断系统是否死机。若死机则不能喂狗,会后系统初始化信息输出。
WWDG_Feed();
}
只要在main函数中调用WWDG_Config(uint8_t tr, uint8_t wr, uint32_t prv),即可开启窗口看门狗