一.看门狗基本定义
看门狗可以检测程序的运行状态,当程序出现设计漏洞,硬件故障,电磁干扰等原因,出现卡死或跑飞等现象,看门狗能及时复位程序,避免程序长时间罢工保证安全性可靠性
看门狗本质上是一个定时器,只能固定时间范围内,程序没有执行喂狗(重置计数器)操作时,看门狗硬件电路自动执行复位信号
STM32内置两个看门狗:独立看门狗IWDG,独立工作对时间精度要求低
窗口看门狗WWDG,要求看门狗在精确计时窗口起作用
二.注意事项
1.IWDG独立看门狗
IWDG键寄存器,本质上是控制寄存器,用于控制硬件电路工作在可能受干扰的情况下,通过键寄存器写入特定值,代替控制寄存器写入一位的功能,降低硬件电路受到干扰概率
写入寄存器的值:
0xCCCC:启用独立看门狗
0xAAAA:IWDG_RLR中的值重新加载到计数器(喂狗)
0x5555:解除IWDG_PR和IWDG_RLR的写保护
0x5555之外的其它值:启动IWDG_PR和IWDG_RLR的写保护
IWDG超时时间:TIWDG=TLSI*PR预分频系数*(RL+1)
TLSI=1/FLSI
FLSI输入时钟40KHz
流程
看门狗写使能
初始化IWDG:设置预分频值,设置重装值,重装计数器喂狗,看门狗使能
2.WWDG看门狗
WWDG工作特性:
递减计数器T[6:0]的值小于0x40时,WWDG产生复位
递减计数器T[6:0]在窗口W[6:0]外被重新装载时
WWDG超时时间:TWWDG=TPCLK1*4096*WDGTB预分频器系数*(T[5:0]+1)
窗口时间 :TWIN=TPCLK1*4096*WDGTB预分频器系数*(T[5:0] - W[5:0])
TPCLK1=1/FPCLK1
流程
开启WWDG时钟
初始化WWDG:设置预分频器,设置窗口值,使能并喂狗
三.代码实现
1.IWDG独立看门狗
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "Key.h"
int main(void)
{
OLED_Init ();
Key_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 ();
}
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);//配置重装值
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.WWDG窗口看门狗
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "Key.h"
int main(void)
{
OLED_Init ();
Key_Init ();
OLED_ShowString (1,1,"WWDG TEST");
if (RCC_GetFlagStatus (RCC_FLAG_WWDGRST) == SET )//查看看门狗标志位
{
OLED_ShowString (2,1,"IWDGRST");
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);//窗口值30
WWDG_Enable(0x40 | 54);//使能并喂狗50
while(1)
{
Key_GetNum ();
OLED_ShowString (4,1,"FEED");
Delay_ms(20);
OLED_ShowString (4,1," ");
Delay_ms(20);
WWDG_SetCounter(0x40 | 54);//配置重装计数器喂狗
}
}