二、看门狗工作原理:定时器、计数器、喂狗、超时复位机制
看门狗(Watchdog Timer, WDT)的核心是一个独立于CPU主程序运行的硬件定时器/计数器。它通过“倒计时”机制监控系统是否“活着”。一旦系统因软件跑飞、死锁或硬件故障而停止正常“喂狗”,看门狗便会触发系统复位,将设备拉回已知的初始状态。
2.1 核心组件与工作流程
看门狗电路由以下四个关键环节构成闭环工作流:
- 定时器/计数器:一个递减(或递增)的硬件寄存器,由独立时钟源驱动。
- 喂狗(Kicking the Dog):主程序在正常循环中,定期向看门狗写入特定值(如0x55AA),将计数器重置为初始值。
- 超时阈值:预设的计数上限(如1.6秒)。
- 复位机制:当计数器递减至0时,看门狗输出复位脉冲,强制MCU复位。
📐 看门狗工作状态机(SVG)
▲ 看门狗状态转换图:计数器递减至0触发复位,喂狗则重置计数器
2.2 定时器与计数器的工作细节
看门狗定时器通常基于一个独立RC振荡器或低频晶振(如32.768kHz)运行,即使主时钟失效,看门狗仍能工作。其核心是一个N位计数器,超时时间计算公式如下:
📊 超时时间计算公式
Tout = (2N × Tclk) = (2N) / fclk 其中: N = 计数器位数(常见:12位、16位、20位) fclk = 看门狗时钟频率(典型值:32kHz ~ 100kHz) Tclk = 时钟周期 = 1 / fclk
例:12位计数器,fclk=40kHz → Tout = 4096 / 40000 ≈ 102.4ms
2.3 喂狗操作详解
“喂狗”是主程序向看门狗寄存器写入特定密钥序列的过程。为防止程序跑飞时意外喂狗,通常要求写入两个连续字节:
| 操作步骤 | 写入值 | 说明 |
|---|---|---|
| 1 | 0x55 |
解锁看门狗寄存器(第一密钥) |
| 2 | 0xAA |
确认喂狗,重置计数器(第二密钥) |
💻 典型喂狗代码示例(C语言)
/* 喂狗函数 - 适用于STM32系列MCU */
void IWDG_Feed(void)
{
/* 向密钥寄存器写入0x5555以启用写访问 */
IWDG->KR = 0x5555;
/* 重新加载计数器值为初始值(RLR寄存器设定) */
IWDG->KR = 0xAAAA;
/* 注:0xCCCC用于启动看门狗,仅在初始化时使用 */
}
/* 主循环中调用 */
int main(void)
{
/* 初始化看门狗:分频系数64,重载值1250 → 超时约1秒 */
IWDG_Init(IWDG_PRESCALER_64, 1250);
while(1)
{
/* 执行用户任务... */
ProcessSensors();
UpdateDisplay();
/* 在任务完成后喂狗 */
IWDG_Feed();
/* 喂狗间隔必须小于看门狗超时时间 */
Delay(500); // 假设延时500ms
}
}
⚠️ 喂狗点应放在主循环末尾,确保所有关键任务均已完成。
2.4 超时复位机制
当计数器递减至0时,看门狗硬件自动执行以下动作:
- 复位脉冲生成:输出一个持续至少几个时钟周期的低电平复位信号(通常为4~8个看门狗时钟周期)。
- 强制复位:该信号连接到MCU的复位引脚(RST),将CPU、外设寄存器、程序计数器等强制初始化。
- 复位标志位:大多数MCU在复位状态寄存器中设置“看门狗复位”标志位,供软件区分复位来源(上电复位 vs 看门狗复位)。
- 计数器冻结:复位期间看门狗计数器停止计数,复位释放后重新加载初始值。
⏱️ 超时复位时序图(SVG)
▲ 计数器递减至0时,RST引脚输出低电平复位脉冲,持续约4~8个时钟周期后释放
2.5 关键设计参数总结
| 参数 | 典型范围 | 设计建议 |
|---|---|---|
| 超时时间 | 1ms ~ 10s | 取主循环周期的2~5倍 |
| 计数器位数 | 12 / 16 / 20 bit | 位数越高,超时范围越宽 |
| 时钟精度 | ±10% ~ ±30% | RC振荡器精度较低,需留余量 |
| 复位脉冲宽度 | 4 ~ 8 时钟周期 | 确保MCU可靠复位 |
💡 设计要点提醒
- 喂狗间隔必须 小于 看门狗超时时间,建议留出30%以上的余量。
- 不要在中断服务函数中喂狗,否则主循环死锁时中断仍可能喂狗,导致看门狗失效。
- 调试阶段可暂时禁用看门狗,但量产固件必须开启。
- 注意区分“窗口看门狗”(WWDT)与“独立看门狗”(IWDT),前者有上下限窗口限制。