窗口看门狗介绍
Q: 什么是窗口看门狗?
A: 窗口看门狗用于监测单片机程序运行时效是否精准,主要检测软件异常(独立看门狗检测的是硬件异常),一般用于需要精准检测(独立看门狗不太精准)程序运行时间的场合。
窗口看门狗的本质
窗口看门狗的本质是一个能产生系统复位信号和提前唤醒中断的6位计数器。
产生复位条件:
1. 当递减计数器值从 0x40 减到 0x3F 时复位(即T6位跳变到0)
2. 计数器的值大于 W[6:0] 值时喂狗会复位。
产生中断条件:
1. 当递减计数器等于 0x40 时可产生提前唤醒中断 (EWI)。
窗口看门狗工作原理
在窗口期内重装载计数器的值,防止复位,也就是所谓的喂狗。
寄存器
控制寄存器
配置寄存器
状态寄存器
超时时间计算 :
Tout 是WWDG超时时间(没喂狗)
Fwwdg 是WWDG的时钟源频率(最大36M)
4096 是WWDG固定的预分频系数
2^WDGTB 是WWDG_CFR寄存器设置的预分频系数值
T[5:0] 是WWDG计数器低6位,最多63
(T[5:0]+1)就是计数次数;剩下部分是记一次数用的时间,相乘就是超时时间
窗口看门狗实验
需求
开启窗口看门狗,计数器值设置为 0X7F ,窗口值设置为 0X5F ,预分频系数为 8(WDGTB=3)。程序启动时点 亮 LED1 ,300ms 后熄灭。在提前唤醒中断服务函数进行喂狗,同时翻转 LED2 状态。
此时Tout1 = (4096*8*64)/36000(ms) 约等于58.25ms
Tout2 = (4096*8*42)/36000(ms) 约等于29.13ms
CubeMX
1. 惯例配置+两盏LED的GPIO配置
2. 点击左侧的WWDG并激活
3. 在下方设置对应参数
4. 打开中断
Keil
1. 在main.c的main函数下,可以看到窗口看门狗的初始化
同时,通过stm32f1xx_it.c --> WWDG_IRQHandler() --> HAL_WWDG_IRQHandler() --> HAL_WWDG_EarlyWakeupCallback(),这就是提前唤醒中断的处理函数,需要在Main.c中重写:
2. 写代码:
注意,这部分的代码不再是完全写在系统提示的用户代码区间,因为项目要求在启动时点亮LED1 300ms,而这句话如果写在看门狗的初始化的后面,显然会导致直接Time out复位,所以LED1点亮的代码不得不写在窗口看门狗初始化函数的前面。
但是在之后代码的编写中,还是要注意尽量把代码都写在系统提示的用户代码区间。
void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg)
{
HAL_WWDG_Refresh(hwwdg); //喂狗
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_9);
}
int main(void)
{
MX_GPIO_Init();
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);
HAL_Delay(300);
MX_WWDG_Init();
while (1)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);
HAL_Delay(40);
}
}
实现效果
可见,程序开始运行时,LED1亮一下,然后LED2不断闪烁,表现在代码中就是窗口看门狗不断向下计数,每当快要复位时触发提前唤醒中断,进行喂狗并翻转LED状态