为什么要有看门狗呢?
因为程序在运行过程中是会跑飞的。我们也不知道飞了,就加一个狗狗看着,相当于一个倒计时,在一定时间内如果没有接收到喂狗信号(倒计时重新开始),就意味着程序可能跑飞了。这时候处理器就会自动复位,重新开始运行啦。
一、独立看门狗
独立看门狗是从一个计数值,减小到0,若在这个过程中没有喂狗,说明程序跑飞,处理器自动复位。
实现功能:
正常情况下是灯一直闪烁,按下按键,即喂狗后 ,灯一直亮。
各种bug,整了一下午,心塞塞。
主函数while前
HAL_Delay(500);
HAL_GPIO_WritePin(LED_G_GPIO_Port, LED_G_Pin, GPIO_PIN_RESET);
由于一直复位,所以灯闪烁。
while中
while (1)
{
//按键消抖
if(HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin)==GPIO_PIN_SET)
{
HAL_Delay(10);
if(HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin)==GPIO_PIN_SET)
{
HAL_IWDG_Refresh(&hiwdg);//喂狗
}
}
HAL_Delay(10);
}
这里看门狗设置的时间是大约1s,预分频系数64,重装载值是625。
配置看门狗后,一直按键,不停喂狗,就不再复位。灯就不灭了。
二、窗口看门狗
相比于独立看门狗,窗口看门狗有上限和下限。
上限最大为0x7f,下限为0x40,所以计数值在0x40-0x7f之间。只有在窗口之间喂狗才不会复位。
窗口看门狗可以产生中断,当使能提前唤醒中断时,一旦进入中断,说明程序真的出现了问题,所以要在中断处理函数中处理一些比较重要的事,比如保存数据、报警等,也称死前中断。
实现功能:
红灯亮300ms,然后绿灯闪烁,大概1s闪烁5下
main函数中
//main函数中
HAL_GPIO_WritePin(LED_R_GPIO_Port, LED_R_Pin, GPIO_PIN_RESET);
HAL_Delay(300);
while (1)
{
HAL_GPIO_WritePin(LED_R_GPIO_Port, LED_R_Pin, GPIO_PIN_SET);
}
中断处理函数
void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg)
{
HAL_WWDG_Refresh(hwwdg);//喂狗
HAL_GPIO_TogglePin(LED_G_GPIO_Port, LED_G_Pin);//绿灯翻转
}
WWDG的计数值为0x7f,上窗口值为0x5f,分频系数为8分频。
代码的运行时间决定了上窗口的值(稍稍比程序运行时间多一点点)。在这个窗口时间内没有喂狗的话,说明程序故障,提前唤醒中断,系统复位。
总之,现在看门狗差不多算是理解了。还是得多练练,前前后后怕是有2天?开始写独立看门狗的时候一直出bug,归根到底还是没理解透,昨晚上又看一遍,查查资料,看看网课,窗口看门狗就顺利得多。嘻嘻,真开心!