顾名思义就是看门的dog,不过这可不是用来看家的,而是用来看单片机的,
在由单片机构成的微型计算机系统中单片机的工作常常会受到来自外界电磁场的干扰,造成程序的跑飞,而陷入死循环;或者因为用户配置代码出现BUG,导致芯片无法正常工作,出于对单片机运行状态进行实时监测的考虑,便产生了一种专门用于监测单片机程序运行状态的模块或者芯片,俗称“看门狗”(watchdog) 。
简单说:看门狗的本质就是定时计数器,计数器使能之后一直在累加 而喂狗就是重新写入计数器的值,时计数器重新累加。
如果在一定时间内没有接收到喂狗信号(表示MCU已经挂了),便实现处理器的自动复位重启(发送复位信号)
STM32内置两个看门狗,提供了更高的安全性、时间的精确性和使用的灵活性。两个看门狗设备(独立看门狗、窗口看门狗)可以用来检测和解决由软件错误引起的故障。当计数器达到给定的超时值时,触发一个中断(仅适用窗口看门狗)或者产生系统复位。
原理:
独立看门狗的工作原理就是一个递减计数器不断的往下递减计数,当减到 0 之前如果没有喂狗的话,产生复位。窗口看门狗跟独立看门狗一样,也是一个递减计数器不断的往下递减计数,当减到一个固定值 0X40 时还不喂狗的话,产生复位,这个值叫窗口的下限,是固定的值,不能改变。这个是跟独立看门狗类似的地方,不同的地方是窗口看门狗的计数器的值在减到某一个数之前喂狗的话也会产生 复位,这个值叫窗口的上限,上限值由用户独立设置。窗口看门狗计数器的值必须在上窗口和下窗口之间才可以喂狗,这就是窗口看门狗中窗口两个字的含义
RLR 是重装载寄存器,用来设置独立看门狗的计数器的值。 TR 是窗口看门狗的计数器的值,由用户独立设置, WR 是窗口看门狗的上窗口值,由用户独立设置。
位31:16 | 保留,始终读为0。 |
---|---|
位15:0 w | 软件必须以一定的间隔写入0xAAAA(喂狗),否则,当计数器为0时,看门狗会产生复位。 |
位15:0 w | 写入0x5555表示允许访问IWDG_PR和IWDG_RLR寄存器。 |
位15:0 w | 写入0xCCCC,启动看门狗工作。 |
2. 预分频寄存器(IWDG_PR)
位31:12 | 保留,始终读为0。 |
---|---|
位11:0 rw | 看门狗计数器重装载值(625) |
IWDG配置分析
独立看门狗工作频率:40khz / 64分频 = 625hz
递减计数器减1的周期:1 / 625hz
独立看门狗的复位时间:625 * (1 / 625hz) = 1s
WWDG_CR 只有低八位有效,T[6:0]用来存储看门狗的计数器值, 随时更新的,每个窗口看门狗计数周期(4096×2^ WDGTB)减 1。当该计数器的值从 0X40 变 为 0X3F 的时候,将产生看门狗复位。
WDGA 位则是看门狗的激活位,该位由软件置 1,以启动看门狗,并且一定要注意的是该 位一旦设置,就只能在硬件复位后才能清零了。
配置寄存器(WWDG_CFR)
该位中的 EWI位是提前唤醒中断位,也就是在快要产生复位的前一段时间(T[6:0]=0X40)来提醒我们,需要进行喂狗了,否则将复位!
因此,我们一般用该位来设置中断,当窗口看门狗的计数器值减到 0X40 的时候,如果该位设置,并开启了中断,则会产生中断,我们可以在中断里面向 WWDG_CR 重新写入计数器的值,来达到喂狗的目的。注意这里在进入中断后,必须在不大于 1 个窗口看门狗计数周期的时间(在 PCLK1 频率为 36M 且 WDGTB 为 0 的条件下, 该时间为 113us)内重新写 WWDG_CR,否则,看门狗将产生复位!
状态寄存器(WWDG_SR)
该寄存器用来记录当前是否有提前唤醒的标志。该寄存器仅有位 0 有效,其他都是保留位。当计数器值达到 40h 时,此位由硬件置 1。 它必须通过软件写 0 来清除。对此位写 1 无效。即使中断未被使能,在计数器的值达到 0X40的时候,此位也会被置 1。
计数器时钟
计数器时钟由 CK 计时器时钟经过预分频器分频得到,分频系数由配置寄存器 CFR 的位8:7 WDGTB[1:0] 配置,可以是 [0,1,2,3],其中 CK 计时器时钟 =PCLK1/4096,除以 4096 是手册规定的,没有为什么。所以计数器的时钟 CNT_CK=PCLK1/4096/(2^WDGTB),这就可以算出计数器减一个数的时间 T= 1/CNT_CK = Tpclk1 * 4096 *(2^WDGTB)。
1设置RCC
2配置IWDG
超出(溢出)时间计算:
Tout=((4×2^PRER) ×RLR)/LSI时钟频率
对应不同预分频系数的PRER值:
3时钟源设置
4项目文件设置
创建工程文件
然后点击GENERATE CODE 创建工程
看门狗初始化函数
HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg)
喂狗函数:
HAL_IWDG_Refresh(IWDG_HandleTypeDef *hiwdg)
举例: HAL_IWDG_Refresh(&hiwdg); //看门狗喂狗
使用该函数定时喂狗即可。
窗口看门狗的定义
窗口看门狗跟独立看门狗一样,也是一个递减计数器不断的往下递减计数,当减到一个固定值 0x3F 时还不喂狗的话,产生复位,这个值叫窗口的下限,是固定的值,不能改变。
窗口看门狗之所以称为窗口,就是因为其喂狗时间是在一个有上下限的范围内(计数器减到某个值~计数器减到0x3F),在这个范围内才可以喂狗,可以通过设定相关寄存器,设定其上限时间(但是下限是固定的0x3F)
窗口看门狗计数器的值只有在2和3 之间(上窗口和下窗口之间)才可以喂狗。
窗口看门狗中断:
并且窗口看门狗还可以使能中断,如果使能了提前唤醒中断,系统出现问题,喂狗函数没有生效,那么在计数器由减到0x40 (0x3f+1) 的时候,便会先进入中断,之后才会复位,你也可以在中断里面喂狗
看门狗初始化:
HAL_WWDG_Init(WWDG_HandleTypeDef *hwwdg)
喂狗:
HAL_WWDG_Refresh(WWDG_HandleTypeDef *hwwdg)
看门狗中断处理函数:
HAL_WWDG_IRQHandler(WWDG_HandleTypeDef *hwwdg)
功能: 判断中断是否正常,并进入中断回调函数
看门狗中断回调函数:
__weak HAL_WWDG_EarlyWakeupCallback(hwwdg);
在HAL库中,每进行完一个中断,并不会立刻退出,而是会进入到中断回调函数中,
看门狗中断运行完成之后,便会进入看门狗的中断回调函数
本例程实现LED点亮延时300ms闪烁。
在main.c下方添加中断回调函数
void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(hwwdg);
HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_15); //LED翻转 --闪烁表示喂狗成功
HAL_WWDG_Refresh(hwwdg); //喂狗
}