3、看门狗定时器原理:定时器工作原理、喂狗机制、超时处理流程

看门狗这东西,说白了就是一个「倒计时炸弹」。你必须在它炸掉之前,给它一个信号——「我还活着」。这个信号,就是我们常说的「喂狗」。

我刚开始做运动控制那会儿,总觉得看门狗就是个简单的定时器,没什么好研究的。直到有一次,一台六轴机器人半夜突然「死机」,第二天查了一上午才发现是看门狗配置不当导致的。嗯,从那以后,我再也不敢小看这个小小的定时器了。

3.1 定时器工作原理

看门狗定时器的核心,就是一个递减计数器。它从预设值开始,每个时钟周期减1。减到0的时候,就会触发复位信号。

你想想看,这个机制其实很简单:

  • 预设值:你设定的超时时间,比如100ms
  • 时钟源:通常是独立的RC振荡器,或者主时钟分频
  • 递减过程:每个时钟周期,计数器减1
  • 触发条件:计数器减到0,立即产生复位

我在项目中遇到过一个问题:有些芯片的看门狗时钟源和主时钟是同一个。这意味着如果主时钟挂了,看门狗也跟着失效。所以,我个人习惯选用有独立时钟源的看门狗,比如STM32的独立看门狗(IWDG)。

关键参数:看门狗的超时时间 = 预设值 × 时钟周期。举个例子,如果时钟频率是40kHz(周期25μs),预设值是4000,那么超时时间就是100ms。

3.2 喂狗机制

喂狗,就是在计数器减到0之前,重新写入预设值。说白了,就是告诉看门狗:「程序还在跑,别复位我」。

喂狗的方式通常有两种:

  1. 硬件喂狗:通过专用的引脚,给一个脉冲信号
  2. 软件喂狗:在程序中写入特定的寄存器值

我建议在运动控制系统中,喂狗操作要放在主循环的「关键路径」上。什么叫关键路径?就是程序必须经过的地方。比如:

void main_loop(void)
{
    while(1)
    {
        // 读取编码器数据
        read_encoder();
        
        // 计算控制量
        calculate_pid();
        
        // 输出PWM
        output_pwm();
        
        // 喂狗——放在这里
        feed_the_dog();
        
        // 处理通信
        handle_communication();
    }
}

为什么要放在中间?因为如果放在开头,万一后面的代码卡死了,看门狗也救不了你。我曾经见过一个同事,把喂狗放在循环的第一行,结果通信模块死锁了,看门狗还在不停地被喂——程序永远不复位,机器就这么僵在那里。

小技巧:喂狗的位置,应该放在你确认「程序健康」的那个点之后。比如,你可以先检查一下关键变量的范围,再喂狗。这样能避免「假健康」的情况。

3.3 超时处理流程

当看门狗超时了,会发生什么?这取决于你的配置。常见的处理方式有三种:

处理方式 说明 适用场景
系统复位 直接复位整个MCU 大多数嵌入式系统
中断+复位 先触发中断,再延时复位 需要记录错误信息的系统
仅中断 只触发中断,不复位 非关键系统(不推荐)

我个人强烈推荐使用「中断+复位」的方式。为什么?因为你可以利用中断服务程序,把现场信息保存下来。比如:

void WDG_IRQHandler(void)
{
    // 保存错误信息
    save_error_log("Watchdog timeout!");
    
    // 保存关键寄存器值
    save_cpu_registers();
    
    // 保存堆栈信息
    save_stack_trace();
    
    // 然后等待复位
    // 硬件会自动复位
}

这样复位之后,你就能通过日志分析出问题出在哪里。否则,你只能看到「系统重启了」,但不知道为什么重启。

注意:中断服务程序里不要做太多事情。看门狗超时说明系统已经不稳定了,你只有很短的时间来保存关键信息。我一般只保存几个关键寄存器和错误码,不超过100个字节。

3.4 看门狗工作流程图

下面这张图,是我画的一个看门狗工作流程。它展示了从启动到超时处理的完整过程:

看门狗工作流程图 系统启动 初始化看门狗 进入主循环 是否喂狗? (程序正常) 喂狗(重置计数器) 返回主循环 超时处理(中断/复位) 系统复位

从这张图你可以看到,看门狗的工作其实就是一个「检查-喂狗-检查」的循环。如果程序卡在某个地方,没有及时喂狗,计数器就会一直减到0,然后触发复位。

经验之谈:看门狗的超时时间,一般设置为主循环周期的2-3倍。比如你的主循环是50ms,那看门狗就设100-150ms。太短容易误触发,太长又起不到保护作用。

好了,关于看门狗定时器的原理,我就讲到这里。记住一句话:看门狗不是用来「看门」的,而是用来「看程序」的。它确保你的程序在正确的时间、正确的位置,做正确的事情。