2、硬件看门狗(WDT)原理:独立看门狗与窗口看门狗的区别,喂狗机制与溢出时间计算,硬件电路设计要点。

各位工程师朋友,咱们接着聊。上一章讲了系统级故障的宏观分类,这一章咱们扎进一个具体但极其关键的模块——硬件看门狗。

说实话,我见过太多产品因为看门狗设计不当,在现场频繁复位,客户投诉不断。你想想看,一个本该在无人值守环境下稳定运行几年的设备,结果三天两头死机重启,这谁受得了?所以,把看门狗吃透,是工业MCU设计的必修课。

2.1 独立看门狗(IWDG)与窗口看门狗(WWDG)的区别

很多初学者会问:都是看门狗,干嘛还分两种?其实它们的定位完全不同。

独立看门狗(IWDG),说白了就是一个独立的、由内部低速RC振荡器驱动的计数器。它不依赖主时钟,即使主时钟挂了,它照样跑。我习惯叫它“最后的防线”。

  • 时钟源:独立的LSI(低速内部振荡器),约40kHz(具体看芯片手册)。
  • 特点:一旦启动,无法关闭(除非复位)。
  • 应用场景:防止程序跑飞、死循环等严重故障。

窗口看门狗(WWDG),则更“智能”一些。它要求你在一个特定的时间窗口内喂狗——不能太早,也不能太晚。太早喂狗,说明程序执行节奏太快,可能跳过了某些关键步骤;太晚喂狗,说明程序卡住了。

  • 时钟源:来自主时钟(APB1),与系统时钟同步。
  • 特点:有上下限窗口,喂狗时机必须精确。
  • 应用场景:对程序执行时序有严格要求的场合,比如电机控制、通信协议栈。

核心区别一句话总结:IWDG是“你必须在超时前喂我”,WWDG是“你必须在超时前且不能太早喂我”。

2.2 喂狗机制与溢出时间计算

喂狗,就是定期给看门狗计数器“清零”,防止它溢出复位。但怎么喂、什么时候喂,这里头有讲究。

独立看门狗的喂狗与时间计算

IWDG的溢出时间由预分频器和重装载寄存器决定。公式很简单:

溢出时间 = (重装载值 + 1) × (4 × 2^预分频系数) / LSI频率

举个例子,STM32F103的LSI典型值是40kHz。我设预分频系数为4(即64分频),重装载值为625:

溢出时间 = (625 + 1) × (4 × 2^4) / 40000
         = 626 × 64 / 40000
         ≈ 1.0016 秒

嗯,差不多1秒。我在项目中一般习惯留20%~30%的余量,比如程序主循环周期是500ms,我会把看门狗溢出时间设在600ms~700ms左右。为什么?因为极端情况下,中断响应、任务切换可能会引入额外延迟。

我的个人习惯:喂狗点不要放在中断服务函数里。我曾经见过一个项目,把喂狗放在定时器中断中,结果主程序死循环了,中断还在跑,看门狗永远不复位——这等于把看门狗废了。喂狗一定要放在主循环的关键路径上。

窗口看门狗的喂狗与时间计算

WWDG的计算稍微复杂一点。它有一个7位的递减计数器(T[6:0]),还有一个窗口寄存器(W[6:0])。喂狗必须在计数器值大于窗口值且小于等于0x40时进行。

喂狗允许范围:窗口值 < 计数器值 ≤ 0x40

溢出时间计算公式:

溢出时间 = (计数器值 + 1) × (4096 × 2^预分频系数) / PCLK1频率

假设PCLK1=36MHz,预分频系数为8,计数器初始值设为0x7F(127),窗口值设为0x5F(95):

最大溢出时间 = (127 + 1) × (4096 × 8) / 36000000
             = 128 × 32768 / 36000000
             ≈ 0.1165 秒

喂狗必须在计数器值从127递减到95之间的这段时间内完成。说白了,窗口只有32个计数值的时间,大约29ms。这个窗口很窄,对程序实时性要求很高。

注意:WWDG的计数器一旦启动,不能像IWDG那样通过软件停止。而且,如果喂狗时计数器值已经小于窗口值,会立即产生复位。所以,用WWDG时,一定要确保喂狗代码的执行时间抖动在可控范围内。

2.3 硬件电路设计要点

看门狗虽然是MCU内部模块,但硬件电路设计同样不能马虎。我踩过不少坑,这里分享几个关键点。

2.3.1 外部复位电路与看门狗的关系

很多MCU的看门狗复位输出会连接到外部复位芯片或RC复位电路。这里有个容易忽略的问题:如果外部复位电路的时间常数太大,看门狗复位脉冲可能被“吃掉”,导致MCU无法正常复位。

我建议:

  • 看门狗复位输出直接连接到MCU的复位引脚,中间不要加太大的电容。
  • 如果必须使用外部复位芯片,选择带有看门狗输入功能的型号(如MAX706、TPS3823等)。

2.3.2 电源去耦与看门狗稳定性

看门狗对电源噪声很敏感。尤其是独立看门狗,它的LSI振荡器对电源纹波容忍度较低。我在一个项目中遇到过:设备在电机启动瞬间,电源跌落导致看门狗误复位。

解决办法:

  • 在MCU电源引脚附近放置0.1μF+10μF的去耦电容。
  • 如果条件允许,给看门狗模块单独加一个LC滤波器。
  • PCB布局时,看门狗相关的走线远离大电流回路。

2.3.3 外部看门狗芯片的选型与设计

有些高可靠性场合,MCU内部看门狗还不够,需要外加独立看门狗芯片。比如:

芯片型号 超时时间 特点
MAX706 1.6s 带手动复位输入,低功耗
TPS3823 1.6s 带看门狗使能引脚
ADM706 1.6s 工业级温度范围

外部看门狗的设计要点:

  • 喂狗信号(WDI)必须用开漏输出,加上拉电阻。
  • 看门狗超时时间要大于MCU内部看门狗,形成“双重保护”。
  • 复位输出通常为低有效,直接连到MCU复位引脚。

避坑指南:我曾经在一个项目中,外部看门狗的喂狗引脚和MCU的GPIO之间没有加限流电阻。结果GPIO配置为推挽输出时,与看门狗芯片的内部上拉电阻形成冲突,导致电平异常。后来我在中间串了一个1kΩ电阻,问题解决。

2.4 实际项目中的喂狗策略

理论讲完了,咱们聊聊实战。喂狗策略直接决定了看门狗的有效性。

策略一:主循环喂狗

最简单的方式,在主循环末尾喂狗。但问题在于:如果某个子函数陷入死循环,主循环根本跑不到喂狗点。

策略二:多任务喂狗

在RTOS中,每个关键任务都设置一个标志位,只有所有标志位都置位了,才允许喂狗。这样,任何一个任务卡死,看门狗都会复位。

void Watchdog_Feed(void)
{
    if (Task1_Flag && Task2_Flag && Task3_Flag)
    {
        HAL_IWDG_Refresh(&hiwdg);
        Task1_Flag = 0;
        Task2_Flag = 0;
        Task3_Flag = 0;
    }
}

策略三:分层喂狗

对于复杂系统,我习惯用两级看门狗:内部IWDG作为第一级,外部看门狗作为第二级。内部看门狗超时时间短(几百毫秒),用于快速响应;外部看门狗超时时间长(几秒),用于兜底。

我的经验:喂狗代码不要写得太复杂。我见过有人把喂狗函数里塞了各种状态判断、日志打印,结果喂狗本身就成了故障点。喂狗就是喂狗,越简单越好。

好了,这一章的内容就到这里。看门狗设计看似简单,但真正做好并不容易。下一章咱们聊聊电压监测与掉电保护,这也是工业现场常见的故障场景。到时候见。