一、WDG简介
1、WDG(Watchdog)看门狗
(1)看门狗可以监控程序的运行状态,当程序因为设计漏洞、硬件故障、电磁干扰等原因,出现卡死或跑飞现象时,看门狗能及时复位程序,避免程序陷入长时间的罢工状态,保证系统的可靠性和安全性
(2)看门狗本质上是一个定时器,当指定时间范围内,程序没有执行喂狗(重置计数器)操作时,看门狗硬件电路就自动产生复位信号
(3)STM32内置两个看门狗
独立看门狗(IWDG):独立工作,对时间精度要求较低(开门狗的时钟是专门用的LSI,不要超过喂狗的最晚界限就行)
窗口看门狗(WWDG):要求看门狗在精确计时窗口起作用(喂狗的时间有个最晚界限,和最早的界限,必须在这个界限的窗口内喂狗,使用APB1时钟)
2、IWDG框图
3、IWDG键寄存器
(1)键寄存器本质上是控制寄存器,用于控制硬件电路的工作
(2)在可能存在干扰的情况下,一般通过在整个键寄存器写入特定值来代替控制寄存器写入一位的功能,以降低硬件电路受到干扰的概率
4、IWDG超时时间
超时时间:= × PR预分频系数 × (RL + 1)
其中: = 1 / (输入时钟40kHz)
5、WWDG框图
6、WWDG工作特性
(1)递减计数器T[6:0]的值小于0x40时,WWDG产生复位
(2)递减计数器T[6:0]在窗口W[6:0]外被重新装载时,WWDG产生复位
(3)递减计数器T[6:0]等于0x40时可以产生早期唤醒中断(EWI),用于重装载计数器以避免WWDG复位
(4)定期写入WWDG_CR寄存器(喂狗)以避免WWDG复位
7、WWDG超时时间
超时时间(喂狗最晚时间):
= × 4096 × WDGTB预分频系数 × (T[5:0] + 1)
窗口时间(喂狗最早时间):
= × 4096 × WDGTB预分频系数 × (T[5:0] - W[5:0])
其中: = 1 /
8、IWDG和WWDG对比
二、独立看门狗
1、按照以下接线方式连接,并将STLINK插到电脑上
2、IWGD库函数功能
3、RCC库函数相关功能
4、mian.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "button.h"
int main(void)
{
OLED_Init();
Button_Init();
OLED_ShowString(1,1,"IWDG TEST");
if(RCC_GetFlagStatus(RCC_FLAG_IWDGRST) ==SET)//查看独立看门狗复位的标志位
{
OLED_ShowString(2,1,"IWDGRST");
Delay_ms(500);
OLED_ShowString(2,1," ");
Delay_ms(100);
RCC_ClearFlag();//清除标志位因为这个标志位不会自动清0
}
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);//配置预分频 超时时间为1000ms
IWDG_SetReload(2499);//配置重装值,0~4096之间
IWDG_ReloadCounter();//喂狗,CNT的值为2499
IWDG_Enable();//启动看门狗
while(1)
{
Button_GetNum();
IWDG_ReloadCounter();//喂狗,CNT的值为2499
OLED_ShowString(4,1,"FEED");
Delay_ms(200);//985不复位
OLED_ShowString(4,1," ");
Delay_ms(600);//985不复位
}
}
5、实现效果
三、窗口看门狗
1、WWGD库函数功能
2、mian.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "button.h"
int main(void)
{
OLED_Init();
Button_Init();
OLED_ShowString(1,1,"WWDG TEST");
if(RCC_GetFlagStatus(RCC_FLAG_WWDGRST) ==SET)//查看窗口看门狗复位的标志位
{
OLED_ShowString(2,1,"WWDGRST");
Delay_ms(500);
OLED_ShowString(2,1," ");
Delay_ms(100);
RCC_ClearFlag();//清除标志位因为这个标志位不会自动清0
}
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);//配置预分频 超时时间为50ms,窗口时间为30ms
WWDG_SetWindowValue(0x40 | 21);//设置窗口值,W[5:0]=21,W6=1
WWDG_Enable(0x40 | 54);//使能,启动看门狗,T[5:0]=54,T6=1
while(1)
{
Button_GetNum();
OLED_ShowString(4,1,"FEED");
Delay_ms(20);
OLED_ShowString(4,1," ");
Delay_ms(20);//31就过早喂狗,50就过迟喂狗,复位
WWDG_SetCounter(0x40 | 54);//喂狗,CNT的值为0x40 | 54
}
}
3、实现效果