看门狗可以有效解决程序的跑飞,在使用过程中比较常见,是防止芯片故障的有效外设。在由单片机构成的微型计算机系统中,单片机的工作常常会受到来自外界电磁场的干扰,造成程序的跑飞,而陷入死循环;或者因为用户配置代码出现BUG,导致芯片无法 正常工作,出于对单片机运行状态进行实时监测的考虑,便产生了一种专门用于监测单片机程序运行状态的模块或者芯片,俗称“看门狗”(watchdog) 。
简单说:看门狗的本质就是定时计数器,计数器使能之后一直在累加 而喂狗就是重新写入计数器的值,时计数器重新累加,
如果在一定时间内没有接收到喂狗信号(表示MCU已经挂了),便实现处理器的自动复位重启(发送复位信号)。
看到此处大概明白了吧,看门狗其实就是一种产生一定的频率信号,这个信号不能中断,一旦中断就意味着程序运行出现了问题,需要对系统进行复位。
看门狗的种类
看门狗有两种,一种是硬件上的看门狗,第二种是软件上的看门狗,前者是在单独的一个硬件部分,独立于CPU外部,或者也可以集成在CPU内部,而软件看门狗则是软件层面的(此处要特殊说明,针对带多核心、带有操作系统的芯片,软件看门狗不能放置于进程/线程中,需要放置在驱动层),两者的区别来讲,硬件看门狗更稳定一些。
回到STM32,我们本次使用的芯片是STM32F407ZGT6,包含两个看门狗,独立看门狗+窗口看门狗,这两个看门dog的最大区别:
独立看门狗IWDG--独立于系统之外,因为有独立时钟,所以不受系统影响的系统故障探测器,主要用于监视硬件错误。
窗口看门狗WWDG----系统内部的故障探测器,时钟与系统相同。如果系统时钟不走了,这个狗也就失去了作用了,主要用于监视软件错误。
简单的讲,看门狗就是检测系统故障的,如果因为系统故障而没有及时喂狗,则引发复位重启。
对于一般的看门狗,程序可以在它产生复位前的任意时刻刷新看门狗,但是这样有一个隐患,有可能程序跑乱了又跑回正常的地方,或者跑乱的程序正好执行了刷新看门狗 操作,这样的情况下一按的看门狗就检测不出来故障了;但是如果使用窗口看门狗,程序员可以根据程序正常执行的时间设置刷新看门狗的一个时间窗口,保证不会提前刷新看门狗,也不会滞后刷新看门狗,这样可以检测出程序没有按照正常的路径运行,非正常地跳过了某些程序段的情况。
WWDG与IWDG的主要区别是有一个窗口控制,WWDG的中断不是用于日常喂狗的,如果用于日常喂狗动作,那WWDG的相对于IWDG,功能也就没什么特别了。WWDG的中断是给程序员最后一次喂狗的机会,一般进入这个中断时,表示你在其他地方安排的喂狗 操不能凑效了,而发生这种现象时,肯定是系统有问题了,或者程序有Bug或者干扰,在这种情况下,这个中断时为了让你的程序在发生真正的看门狗复位前,有一个紧急处理的机会,如保存重要数据,或者系统刹车,说白了,就是让CPU写“遗嘱”;
由此看出,简单的在WWDG中断中喂狗,既没有发挥WWDG相对于IWDG的优势,又因为在中断中喂狗,而为以后的产品留下了隐患。
下面分别介绍一下如何使用STM32中的独立看门狗IWDG和窗口看门狗WWDG。
一、独立看门狗
1、IWDG主要特性
以下是独立看门狗框图
![](https://public.fangzhenxiu.com/fixComment/commentContent/imgs/1687277173207_n2wfj1.jpg?imageView2/0)
当通过对关键字寄存器 (IWDG_KR) 写入值 0xCCCC 启动独立看门狗时,计数器开始从复位值 0xFFF 递减计数。当计数器计数到终值 (0x000) 时会产生一个复位信号( IWDG 复位)。
任何时候将关键字 0xAAAA 写到 IWWDG_KR 寄存器中, IWDG_RLR 的值就会被重载到计数器,从而避免产生看门狗复位
寄存器访问保护
IWDG_PR 和 IWDG_RLR 寄存器具有写访问保护。若要修改寄存器,必须首先对 IWDG_KR寄存器写入代码 0x5555。而写入其他值则会破坏该序列,从而使寄存器访问保护再次生效。这意味着重装载操作(即写入 0xAAAA)也会启动写保护功能。
2、寄存器介绍:
2.1关键字寄存器 (IWDG_KR)
![](https://public.fangzhenxiu.com/fixComment/commentContent/imgs/1687277169956_emxg59.jpg?imageView2/0)
位 15:0 KEY[15:0]:键值 (Key value)(只写位,读为 0000h)
必须每隔一段时间便通过软件对这些位写入键值 AAAAh,否则当计数器计数到 0 时,看门狗会产生复位。
写入键值 5555h 可使能对 IWDG_PR 和 IWDG_RLR 寄存器的访问
写入键值 CCCCh 可启动看门狗(选中硬件看门狗选项的情况除外)
2.2预分频器寄存器 (IWDG_PR)
![](https://public.fangzhenxiu.com/fixComment/commentContent/imgs/1687277172985_n09ttr.jpg?imageView2/0)
位 2:0 PR[2:0]:预分频器 (Prescaler divider)
这些位受写访问保护,。通过软件设置这些位来选择计数器时钟的预分频
因子。若要更改预分频器的分频系数, IWDG_SR 的 PVU 位必须为 0。
000:4 分频
001:8 分频
010:16 分频
011:32 分频
100:64 分频
101:128 分频
110:256 分频
111:256 分频
注意:读取该寄存器会返回 VDD 电压域的预分频器值。如果正在对该寄存器执行写操作,则读取的值可能不是最新的/ 有效的。因此,只有在 IWDG_SR 寄存器中的 PVU 位为 0时,从寄存器读取的值才有效
2.3 重载寄存器 (IWDG_RLR)
![](https://public.fangzhenxiu.com/fixComment/commentContent/imgs/1687277173487_7es90b.jpg?imageView2/0)
位 11:0 RL[11:0]:看门狗计数器重载值 (Watchdog counter reload value)
这些位受写访问保护,这个值由软件设置,每次对 IWDR_KR 寄存器写入值 AAAAh 时,这个值就会重装载到看门狗计数器中。之后,看门狗计数器便从该装载的值开始递减计数。超时周期由该值和时钟预分频器共同决定。
若要更改重载值, IWDG_SR 中的 RVU 位必须为 0。
2.4 状态寄存器 (IWDG_SR)
![](https://public.fangzhenxiu.com/fixComment/commentContent/imgs/1687277170449_l2v7rj.jpg?imageView2/0)
位 1 RVU:看门狗计数器重载值更新 (Watchdog counter reload value update)
可通过硬件将该位置 1 以指示重载值正在更新。当在 VDD 电压域下完成重载值更新操作后(需要多达 5 个 RC 40 kHz 周期),会通过硬件将该位复位。
重载值只有在 RVU 位为 0 时才可更新。
位 0 PVU:看门狗预分频器值更新 (Watchdog prescaler value update)
可通过硬件将该位置 1 以指示预分频器值正在更新。当在 VDD 电压域下完成预分频器值更新操作后(需要多达 5 个 RC 40 kHz 周期),会通过硬件将该位复位。
预分频器值只有在 PVU 位为 0 时才可更新。
注意:如果应用使用多个重载值或预分频器值,则必须等到 RVU 位被清零后才能更改重载值,而且必须等到 PVU 位被清零后才能更改预分频器值。但是,在更新预分频器和/或重载值之后,则无需等到 RVU 或 PVU 复位后再继续执行代码(即便进入低功耗模式,也会继续执行写操作至完成)
3、IWDG软件编程步骤
第一步,写入数值,解除IWDG_KR写保护,(IWDG_Init(4,500); //预分频数为64,重载值为500,溢出时间为1s)
第二步,设置分频系数,设置寄存器初值和重装载值;
第三步,使能看门狗;
第四步,编写喂狗函数;
![](https://public.fangzhenxiu.com/fixComment/commentContent/imgs/1687277172459_qelmth.jpg?imageView2/0)
二、窗口看门狗
窗口看门狗通常被用来监测,由外部干扰或不可预见的逻辑条件造成的应用程序背离正常的运行序列而产生的软件故障。除非递减计数器的值在 T6 位变成 0 前被刷新,看门狗电路在达到预置的时间周期时,会产生一个 MCU 复位。如果在递减计数器达到窗口寄存器值之前刷新控制寄存器中的 7 位递减计数器值,也会产生 MCU 复位。这意味着必须在限定的时间窗口内刷新计数器。
1、WWDG主要特性
-当递减计数器小于0x40时复位(看门狗已激活)
-窗口之外重载递减计数器时复位(看门狗已激活)
2、WWDG 功能说明
如果激活看门狗( WWDG_CR 寄存器中的 WDGA 位置 1),则当 7 位递减计数器( T[6:0]位)从 0x40 滚动到 0x3F( T6 已清零)时会引发复位。当计数器值大于窗口寄存器中所存储的值时,如果软件重载计数器,则会产生复位。
![](https://public.fangzhenxiu.com/fixComment/commentContent/imgs/1687277171296_3auzzq.jpg?imageView2/0)
应用程序在正常运行过程中必须定期地写入 WWDG_CR 寄存器以防止 MCU 发生复位。只有当计数器值低于窗口寄存器值时,才能执行此操作。存储在WWDG_CR 寄存器中的值必须介于 0xFF 和 0xC0 之间:
在系统复位后,看门狗总是处于关闭状态。可通过设置 WWDG_CR 寄存器中的 WDGA 位来使能看门狗,之后除非执行复位操作,否则不能再次关闭。
控制递减计数器
递减计数器处于自由运行状态:即使禁止看门狗,递减计数器仍继续递减计数。当使能看门狗时,必须将 T6 位置 1,以防止立即复位。
T[5:0] 位包含了看门狗产生复位之前的计时数目;复位前的延时时间在一个最小值和一个最大值之间变化,这是因为写入 WWDG_CR 寄存器时,预分频值是未知的。配置寄存器 (WWDG_CFR) 包含窗口的上限:为防止发生复位,当递减计数器的值低于窗口寄存器值且大于 0x3F 时必须重载。
![](https://public.fangzhenxiu.com/fixComment/commentContent/imgs/1687277171555_xu4xv7.jpg?imageView2/0)
![](https://public.fangzhenxiu.com/fixComment/commentContent/imgs/1687277170683_427if6.jpg?imageView2/0)
当我们使用STM32F4xx时,PCLK1=APB1CLK=42MHZ,根据公式计算得出
twwdg最大50ms(1/42*4096*2^3*64),最小97us(1/42*4096*2^1*1).
3、寄存器介绍
3.1控制寄存器WWDG_CR
![](https://public.fangzhenxiu.com/fixComment/commentContent/imgs/1687277171979_tird0d.jpg?imageView2/0)
位 7 WDGA:激活位 (Activation bit)
此位由软件置 1,只有复位后才由硬件清零。当 WDGA = 1 时,看门狗可产生复位。
0:禁止看门狗
1:使能看门狗
位 6:0 T[6:0]:7 位计数器 (MSB 到 LSB)
这些位用来存储看门狗计数器的值。它每隔 (4096 x 2WDGTB) PCLK1 个周期递减一次。当它从 0x40 滚动到 0x3F( T6 清零)时会产生复位。
3.2配置寄存器 (WWDG_CFR)
![](https://public.fangzhenxiu.com/fixComment/commentContent/imgs/1687277170195_8g4cwk.jpg?imageView2/0)
位 9 EWI:提前唤醒中断 (Early wakeup interrupt)
置 1 后,只要计数器值达到 0x40 就会产生中断。此中断只有在复位后才由硬件清零。
位 8:7 WDGTB[1:0]:定时器时基 (Timer base)
可按如下方式修改预分频器的时基:
00:CK 计数器时钟 (PCLK1 div 4096) 分频器 1
01:CK 计数器时钟 (PCLK1 div 4096) 分频器 2
10: CK 计数器时钟 (PCLK1 div 4096) 分频器 4
11: CK 计数器时钟 (PCLK1 div 4096) 分频器 8
位 6:0 W[6:0]:7 位窗口值 (7-bit window value)
这些位包含用于与递减计数器进行比较的窗口值。
3.3 状态寄存器 (WWDG_SR)
![](https://public.fangzhenxiu.com/fixComment/commentContent/imgs/1687277172708_6hzmmm.jpg?imageView2/0)
位 0 EWIF:提前唤醒中断标志 (Early wakeup interrupt flag)
当计数器值达到 0x40 时此位由硬件置 1。它必须由软件通过写入 0 来清零。写入 1 不起作用。如果不使能中断,此位也会被置 1。
4、WWDG软件编程步骤
第一步,使能WWDG时钟;(WWDG_Init(0X7F,0X4F,3); //预分频数为3,重载值为0X7F,溢出时间为50ms)
第二步,设置计数器,分频系数,窗口值,计数器值;
第三步,可以设置提前唤醒中断(延时最长的时间喂狗),需要设置中断分组;
第四步,编写中断服务函数,在中断函数中重新设置WWDG_CNT计数器的值,并清除标志位;
![](https://public.fangzhenxiu.com/fixComment/commentContent/imgs/1687277171016_jme3xs.jpg?imageView2/0)