
STM32 独立看门狗, 由专门的低速时钟 (LSI) 驱动,即便是主时钟发生故障它仍能够有效,所以此狗狗可以工作在与主时钟无关的要求下,或者待机模块下等,所以它叫独立看门狗,注意一旦开启此看门狗则只能由 MCU 复位后才清除,让它不再工作。 它的时钟是一个内部 RC 时钟,它会在 30KHZ 到 60KHZ 之间变化,并非是精确的 40KHZ,而只是一般计算时取 40KHZ。 独立看门狗需设置四个寄存器如下: ![]() 其中, 预分频寄存器 (IWDG_PR),最低三位 PR [2:0](Prescaler divider) 有效,可设置有 8 种不同的计数器时钟预分频因子。 重装载寄存器 (IWDG_RLR) 低 12 位 RL [11:0]: 看门狗计数器重装载值 (Watchdog counter reload value) 有效,用来设置计数器的重装载值。 注意要设置以上两个寄存器的值需满足两个条件,详见如下: 键寄存器 (IWDG_KR),用来控制去除 IWDG_PR 和 IWDG_RLR 写保护功能以便正常写值,向此寄存器写入 0x5555 则暂时去除 IWDG_PR 和 IWDG_RLR 的写保护功能才可向两个寄存器中写值。当向此寄存器写入 0xAAAA 则 IWDG_RLR 的值会重装载,防止 MCU 复位,向入 0xCCCC 是开启狗立看门狗动作。 状态寄存器 (IWDG_SR) 最低两位有效 RVU: 看门狗计数器重装载值更新 (Watchdog counter reload value update) 标识位和 PVU: 看门狗预分频值更新 (Watchdog prescaler value update) 标识位,分别用来指示此时是否可向 IWDG_RLR 和 IWDG_PR 写值,此寄存器由硬件置 1 与清 0,只有当为 0 时才可向上面两个寄存器写值。 它的初始化过程大致如下 :
喂狗可通过调用如下函数进行:
以上参考正点原子相关代码,朋友们可以跳到库函数代码中自己研究下,控制比较简单,不再赘述。另外要注意不要使用硬件时钟中断喂狗,因为硬件时钟中断一般都有较高优先级且独立于主控程序,这样有时会出现主控程序虽然跑飞了,但仍能够正常喂狗的现象。 独立看门狗能够在一定程度上监控着程序正常运行,然而我认为更加强大,应用更灵活及更能保证程序稳定运行的还属窗口看门狗,虽然它开始时不太好理解。 STM32 窗口看门狗 共三个寄存器,如下图: ![]() 看似简单,但设置及应用起来有不少玄机。 控制寄存器 (WWDG_CR) 中的值必须在 0xFF 与 0xC0 之间, 因为它的第 0 至第 6 位为递减计数器 CNT,在它的第 6 位变为 0 时将产生复位,所以在初始化时需要为 1,第 7 位 WDGA 是用来设置启动或禁止窗口看门狗的,当为 1 进才会启动窗口看门狗,所以第 6 和第 7 位都需为 1,即 WWDG_CR 的值需要大于等于 0xC0 。 配置寄存器 (WWDG_CFR) 第 0 至第 6 位 是设置窗口边界值用的,只有当递减计数器 CNT 的值小于边界值时才可以喂狗,过早不行,狗还不饿,撑死了。并且 7 位递减计数器 CNT 减少到 0x3F 时即 T6 位变为 0,此时 MCU 也会复位,过晚了,狗饿死了。所以必须在指定的时间范围喂狗,过早或过晚都将产生复位,而这样设计可以减少软件跑飞了却仍能够歪打正着地喂狗的发生概率。 状态寄存器 (WWDG_CFR) 只用到了第 0 位,EWIF (Early wakeup interrupt flag ) 是提前唤醒中断标识,当递减计数器 CNT 的值到达 0X40 (若再减少一次则 T6 位变为 0,产生复位) 时此位由硬件置 1,且需用软件清 0,注意无论中断是否使能此位都会被硬件置 1。而提前唤醒中断使能设置是在配置寄存器 (WWDG_CFR) 第 9 位 EWI (Early wakeup interrupt),此位需由软件置 1,则会在当递减计数器 CNT 的值到达 0X40 时产生中断,并且与 EWIF 不同,此位是由硬件清 0。 另外控制寄存器 (WWDG_CR) 中第 7 位 WDGA (Activation bit) 激活位,需用软件来置 1,以启动窗口看门狗,并且一旦启动后,只能在复位或重启后由硬件来清 0。 配置寄存器 (WWDG_CFR) 的第 8 位和第 7 位 WDGTB [1:0] 用来设置时基 (Timer base) 预分频数。 以上描述可参考下图以更清晰的理解: ![]() 窗口看门狗应用时还要注意算准最小与最大喂狗时间,以便正确地喂狗,如下: ![]() 在 PCLK1 频率为 36MHz 时,则 上窗口时间:T_min = 4096 * (2^WDGTB)*(WWDG_CR [6:0] - WWDG_CFR [6:0])/36 (us) 下窗口时间: T_max = 4096 * (2^WDGTB)*(WWDG_CR [6:0] - 0x40)/36 (us) 。 喂狗动作需在这段时间之间进行,而喂狗动作为向控制寄存器 (WWDG_CR) 中写值,值的范围上文已经说过。 窗口看门狗中断函数 void WWDG_IRQHandler (void);是用来做什么的呢。窗口看门狗中断函数是在递减计数器减少到 0x40 是被调用,因为它本身计数就比较慢,所以离数到 0x3F 复位还有一段时间,我认为这样设计是为 MCU 复位之前留下一点时间,能够使工程设计人员根据需要在中断函数保存一些重要的数据,这样在复位后 MCU 可知道系统因异常复位的某此状态,以使系统有更高稳定性。 并且我觉得在窗口看门狗中断函数中喂狗没有什么意义,程序本来已经不按正常运行了,还在中断函数中喂狗防止复位只会错上加错,不好好利用它干点正事, 更是浪费资源。 这点上我个人认为不要被点原子示例代码误导哦,但其还是有部分借鉴意义的,以下为初始化相关代码:
转载自:以太快跑 |
STM32 GUI LTDC 最大像素时钟评估方法
【2025·STM32峰会】GUI解决方案实训分享1-对LVGL咖啡机例程的牛刀小试以及问题排查
OpenBLT移植到STM32F405开发板
为什么要先开启STM32外设时钟?
【STM32MP157】从ST官方例程中分析RPMsg-TTY/SDB核间通信的使用方法
【经验分享】STM32实例-RTC实时时钟实验④-获取RTC时间函数与中断服务函数
STM32 以太网 MAC Loopback 的实现
STM32功能安全设计包,助力产品功能安全认证
基于STM32启动过程startup_xxxx.s文件经验分享
HRTIM 指南