STM32 看门狗(WDG)
WDG简介
-
WDG(Watchdog)看门狗 在程序卡死的情况下,自动帮我们复位
- 简单来说就是程序运行的一个保障措施,我们得在程序中定期地进行喂狗,如果程序出问题卡死了,没有在规定的时间里喂狗,那么看门狗硬件电路就会自动帮我们复位一下,防止程序长时间卡死。就像是写了个程序,然后突然没动静了,我们就会习惯性地去按一下复位,或者说手机、电脑、卡死不动了,我们也会习惯性地重启来解决。
-
看门狗可以监控程序的运行状态,当程序因为设计漏洞、硬件故障、电磁干扰等原因,出现卡死或跑飞现象时,看门狗能及时复位程序,避免程序陷入长时间的罢工状态,保证系统的可靠性和安全性
-
看门狗本质上是一个定时器,当指定时间范围内,程序没有执行喂狗(重置计数器)操作时,看门狗硬件电路就自动产生复位信号
-
STM32内置两个看门狗
- 独立看门狗(IWDG):独立工作,对时间精度要求较低
- 独立看门狗的时钟是专用的LSI,内部低速时钟,即使主时钟出现问题了,看门狗也能正常工作。独立看门狗只有一个最晚时间界限,喂狗间隔只要不超过这个最晚界限就行了。
- 窗口看门狗(WWDG):要求看门狗在精确计时窗口起作用,使用的是APB1的时钟,没有专用的时钟。
- 喂狗的时间有个最晚的界限,也有个最早的界限,必须在这个界限的窗口内喂狗。
- 对于独立看门狗来说,可能程序就卡死在喂狗的部分了,或者程序跑飞,但是喂狗代码也意外执行了,或者程序有时候很快喂狗,有时候又比较慢喂狗,这些状态独立看门狗就检测不到了,但是窗口看门狗是可以检测到这些问题的,因为它对喂狗的时间窗口卡的很死。
- 独立看门狗(IWDG):独立工作,对时间精度要求较低
IWDG框图
- 输入时钟,是LSI,内部低速时钟,时钟频率为40KHz。
- 之后,时钟进入预分频器进行分频,这个预分频器只有8位,所以最大只能进行256分频。预分频寄存器IWDG_PR可以配置分频系数。
- 经过预分频器分频之后,时钟经过递减计数器,每来一个时钟,自减一个数,这个计数器是12位的,所以最大值是212-1=4095,当自减到0之后,产生IWDG复位。
- 正常运行时,为了避免复位,我们可以提前在重装载寄存器IWDG_RLR写一个值,当我们预先写好值之后,在运行过程中,我们在键寄存器(IWDG_KR)里写一个特定数据,控制电路进行喂狗,这时重装值,就会复制到当前的计数器中,这样计数器就会回到重装值,重新自减运行了。
- 状态寄存器IWDG_SR,就是标志电路运行的状态
- 上面这些寄存器位于1.8V供电区,下面主要的工作电路,都位于VDD供电区。看门狗功能处于VDD供电区,即在停机模式和待机模式仍能正常运行。独立看门狗也是唤醒待机模式的四个条件之一。
IWDG键寄存器
-
键寄存器本质上是控制寄存器,用于控制硬件电路的工作
-
在可能存在干扰的情况下,一般通过在整个键寄存器写入特定值来代替控制寄存器写入一位的功能,以降低硬件电路受到干扰的概率
- 独立看门狗运行在程序可能跑飞、可能收到电磁干扰的环境,在这种环境下,程序作出任何操作都是有可能的,如果只在寄存器中设置一个位,那这一位就有可能在误操作中,变成1或者变成0,这个概率是比较大的。所以单独设置1位来进行控制,在这里比较危险。这时,我们就可以在整个寄存器写入一个特定值,来代替写入一个位的操作。
写入键寄存器的值 | 作用 |
---|---|
0xCCCC | 启用独立看门狗 |
0xAAAA | IWDG_RLR中的值重新加载到计数器(喂狗) |
0x5555 | 解除IWDG_PR和IWDG_RLR的写保护 |
0x5555之外的其他值 | 启用IWDG_PR和IWDG_RLR的写保护 |
IWDG超时时间
-
超时时间:TIWDG = TLSI × PR预分频系数 × (RL + 1)
-
其中:TLSI = 1 / FLSI
WWDG框图
- 时钟来源是PCLK1,也就是APB1的时钟,这个时钟默认是36MHz,进来之后,先经过一个预分频器进行分频。
- 分频之后的时钟,驱动计数器进行计数,这个计数器也是一个递减计数器,每来一个时钟,自减一次。这个计数器只有T5~T0,这6位是有效的计数值,最高位T6,这里用来当作溢出标志位。T6位等于1时,表示计数器没溢出,T6位等于0时,表示计数器溢出。
- 不过对于硬件电路来说,T6位其实也是计数器的一部分,只不过T6位被单独拎出来,当作标志位了而已。比如这个计数器的初始值,我们给111 1111,那么来一个计数脉冲,值减1变为111 1110,再来一个变为111 1101,依次类推,不断自减。直到减为100 0000,减到这个数时,是一个关键节点,此时包括T6位在内的数,是100 0000,转为16进制是0x40。也就是说,此时如果把T6位也当作计数器的一部分,那计数器的值实际上才减一半,但是如果我们把T6位剥离出去,当作溢出标志位,低6位,当作计数器,那此时的状态就是,标志位为1,计数器为00 0000,已经减到0了,再减依次,下一个值是011 1111,这时最高位T6,由1变为0,即代表计数器溢出,这时,最高位T6,就会通过电路,产生复位信号。
- 如果你把T6位看作是计数器的一部分,那就是整个计数器,值减到0x40之后溢出;而如果把T6位当成溢出标志位,低6位,当作计数器,那就是,低6位的计数值减到0之后溢出。
- WDGA,窗口看门狗的激活位,也就是使能,WDGA写入1,启用窗口看门狗,使能位作用于与门。
- 与门的作用类似于一个开关,左边是控制信号,右边是输入,上边是输出,控制信号给1,则输出等于输入,开关导通;控制信号给0,则输出等于0,与输入无关,开关断开。
- 复位信号有两个来源,用或门连接
- 溢出标志位T6 当计数器溢出时,T6等于0,输入进来,这里输入有个小圆圈,代表输入取反,所以0变为1,或门有效,输出1,当最后这个使能位给1,开启看门狗后,这个溢出信号就直接通向复位了。
- T6位一旦等于0,就表示计数器溢出,产生复位信号。在程序正常运行状态下,必须时钟保证T6位为1,这样才能避免复位。
- 写入WWDG_DR和T6:0与W6:0的比较结果 首先,我们需要计算一个最高界限的计数值,写入到W6~W0,这些值,写入之后是固定不变的。之后一旦我们执行写入CR操作时,与之相连的与门开关打开,写入CR,其实就是写入计数器,也就是喂狗。在喂狗时,这个比较器开始工作,一旦它比较我们当前的计数器T6:0(计数器还未更新)>窗口值W6:0,比较结果就等于1,这个1通过或门,也可以申请复位。
- 喂狗最早时间窗口的实现流程,就是喂狗的时候,把当前计数值和我预设的窗口值进行比较,如果发现狗的余粮还很充足,喂得太频繁了,就给你复位一下,不让你太早喂狗。
- 溢出标志位T6 当计数器溢出时,T6等于0,输入进来,这里输入有个小圆圈,代表输入取反,所以0变为1,或门有效,输出1,当最后这个使能位给1,开启看门狗后,这个溢出信号就直接通向复位了。
喂狗太晚,6位计数器减到0时,复位。
喂狗太早,计数器的值超过窗口值了,复位
WWDG工作特性
-
递减计数器T[6:0]的值小于0x40时,WWDG产生复位
- T[6:0]包含T6位,所以是值减到0x50之后,再减一次就复位。
-
递减计数器T[6:0]在窗口W[6:0]外被重新装载时,WWDG产生复位
- 不能过早喂狗
-
递减计数器T[6:0]等于0x40时可以产生早期唤醒中断(EWI),用于重装载计数器以避免WWDG复位
- 0x40,这时T6还是1,还没有溢出,再减一个数,变成0x3F,才溢出。这里的意思就是减到0x40时,产生中断,然后再减一个数,到0x3F时,产生复位。这样这个中断其实就是在溢出前的前一刻发生,这个中断也可以叫“死前中断”。马上就要溢出复位了,再提醒一下你,要不要干点什么。
- 所以在这个早期唤醒中断里,我们一般可以用来执行一些紧急操作,比如保存重要数据、关闭危险设备等,或者,就是虽然超时喂狗了,但是我们可以在中断里执行一些代码进行解决,或者这个任务不是很危险,就只想做一些提示,不想让它复位了,这样,我们就可以在这个早期唤醒中断里,直接进行喂狗,阻值系统复位。
-
定期写入WWDG_CR寄存器(喂狗)以避免WWDG复位
纵轴是T[6:0],包含T6位的CNT,递减计数器,喂狗之后,计数器递减,如果这个计数器还很大,高于W[6:0]窗口值了,你就不能着急喂狗,之后当计数值小于窗口值了,进入到刷新窗口,可以喂狗,当然喂狗也不能太晚,要在减到0x3F之前喂狗,3F这个值,就是T6刚等于0的时刻。所以下面这里,T6位在这个时刻变成0,同时复位信号也在这个时刻产生。
WWDG超时时间
多乘一个4096,是因为PCLK1进来之后,其实是先执行了一个固定的4096分频,因为36M频率太快了,先来一个固定分频,降低一下。
-
超时时间:
- TWWDG = TPCLK1 × 4096 × WDGTB预分频系数 × (T[5:0] + 1)
-
窗口时间:
- TWIN = TPCLK1 × 4096 × WDGTB预分频系数 × (T[5:0] - W[5:0])
-
其中:TPCLK1 = 1 / FPCLK1
IWDG和WWDG对比
IWDG独立看门狗 | WWDG窗口看门狗 | |
---|---|---|
复位 | 计数器减到0后 | 计数器T[5:0]减到0后、过早重装计数器 |
中断 | 无 | 早期唤醒中断 |
时钟源 | LSI(40KHz) | PCLK1(36MHz) |
预分频系数 | 4、8、32、64、128、256 | 1、2、4、8 |
计数器 | 12位 | 6位(有效计数) |
超时时间 | 0.1ms~26214.4ms | 113us~58.25ms |
喂狗方式 | 写入键寄存器,重装固定值RLR | 直接写入计数器,写多少重装多少 |
防误操作 | 键寄存器和写保护 | 无 |
写入键寄存器,重装固定值RLR | 直接写入计数器,写多少重装多少 | |
防误操作 | 键寄存器和写保护 | 无 |
用途 | 独立工作,对时间精度要求较低 | 要求看门狗在精确计时窗口起作用 |