目录
- [stm32 WDG看门狗](#stm32 WDG看门狗)
stm32 WDG看门狗
一、WDG基础知识
1)WDG(Watchdog)看门狗简介
- 看门狗可以监控程序的运行状态,当程序因为设计漏洞、硬件故障、电磁干扰等原因,出现卡死或跑飞现象时,看门狗能及时复位程序,避免程序陷入长时间的罢工状态,保证系统的可靠性和安全性
- 看门狗本质上是一个定时器,当指定时间范围内,程序没有执行喂狗(重置计数器)操作时,看门狗硬件电路就自动产生复位信号
- STM32内置两个看门狗
- 独立看门狗(IWDG):独立工作,对时间精度要求较低
- 窗口看门狗(WWDG):要求看门狗在精确计时窗口起作用
- 独立看门狗框图
- 看门狗功能处于VDD供电区,即在停机和待机模式时仍能正常工作
二、IWDG独立看门狗
1)IWDG键寄存器
- 键寄存器本质上是控制寄存器,用于控制硬件电路的工作
- 在可能存在干扰的情况下,一般通过在整个键寄存器写入特定值来代替控制寄存器写入一位的功能,以降低硬件电路受到干扰的概率
2)IWDG超时时间
- 超时时间:TIWDG = TLSI x PR预分频系数 x (RL + 1)
- 其中:TLSI = 1 / FLSI
三、WWDG窗口看门狗
1)WWDG框图

2)WWDG工作特性
- 递减计数器T[6:0]的值小于0x40时,WWDG产生复位
- 递减计数器T[6:0]在窗口W[6:0]外被重新装载时,WWDG产生复位
- 递减计数器T[6:0]等于0x40时可以产生早期唤醒中断(EWI)(死前中断),用于重装载计数器以避免WWDG复位
- 定期写入WWDG_CR寄存器(喂狗)以避免WWDG复位
3)WWDG超时时间
- 超时时间:TIWDG = TPCLK1 x 4096 x WDGTBB预分频系数 x (T[5:0] + 1)
- 窗口时间:TWIN = TPCLK1 x 4096 x WDGTBB预分频系数 x (T[5:0] - W[5:0])
- 其中:TPCLK1 = 1 / FPCLK1
4)IWDG和WWDG对比

- 其他详细信息见STM32Fx手册
四、实验
1)独立看门狗
-
关键代码:
int main(void){ OLED_Init(); Key_Init(); OLED_ShowString(1, 1, "IWDG Test"); if(RCC_GetFlagStatus(RCC_FLAG_IWDGRST) == SET) { OLED_ShowString(2, 1, "IWDGSET"); Delay_ms(500); OLED_ShowString(2, 1, " "); Delay_ms(100); RCC_ClearFlag(); } else { OLED_ShowString(3, 1, "RST"); Delay_ms(500); OLED_ShowString(3, 1, " "); Delay_ms(100); } IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); IWDG_SetPrescaler(IWDG_Prescaler_16); IWDG_SetReload(2499); //1000ms IWDG_ReloadCounter(); IWDG_Enable(); while (1) { Key_GetNum(); IWDG_ReloadCounter(); OLED_ShowString(4, 1, "FEED"); Delay_ms(200); OLED_ShowString(4, 1, " "); Delay_ms(600); } }
2)窗口看门狗
-
关键代码:
int main(void){ OLED_Init(); Key_Init(); OLED_ShowString(1, 1, "WWDG Test"); if(RCC_GetFlagStatus(RCC_FLAG_WWDGRST) == SET) { OLED_ShowString(2, 1, "WWDGSET"); Delay_ms(500); OLED_ShowString(2, 1, " "); Delay_ms(100); RCC_ClearFlag(); } else { OLED_ShowString(3, 1, "RST"); Delay_ms(500); OLED_ShowString(3, 1, " "); Delay_ms(100); } RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); WWDG_SetPrescaler(WWDG_Prescaler_8); WWDG_SetWindowValue(0x40 | 21); WWDG_Enable(0x40 | 54); while (1) { Key_GetNum(); OLED_ShowString(4, 1, "FEED"); Delay_ms(20); OLED_ShowString(4, 1, " "); Delay_ms(20); WWDG_SetCounter(0x40 | 54); } }