这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » STM32 » 【转载】STM32看门狗与系统故障保护——产品可靠性不能只靠运气----from

共1条 1/1 1 跳转至页

【转载】STM32看门狗与系统故障保护——产品可靠性不能只靠运气----from阿水

工程师
2026-10-19 18:14:16     打赏

做消费类产品的朋友应该都有体会:实验室里跑得好好的,一到客户手上就出问题。电磁干扰、电源毛刺、静电ESD……这些现场环境的东西你实验室里根本模拟不出来。所以产品的可靠性设计特别重要,而看门狗就是可靠性设计的底线。

今天聊聊STM32的看门狗怎么用,以及一些故障保护的思路。

一、STM32的三种”看门狗”

STM32F1其实有三种watchdog机制:

1. 独立看门狗(IWDG)

• 用LSI(约40kHz)驱动,精度不高但独立于主时钟

• 就算主时钟挂了它还在跑

• 12位递减计数器,预分频和重载值可编程

• 超时后产生复位

2. 窗口看门狗(WWDG)

• 用PCLK2驱动,精度取决于系统时钟

• 不仅可以检测”太慢”(超时),还能检测”太快”(提前喂狗)

• 所以叫”窗口”看门狗——你只能在规定的窗口时间内喂狗

3. SysTick看门狗(软件看门狗)

• STM32没有硬件实现,用软件模拟

• 在SysTick中断里计数,主循环定期清零

• 最灵活,可以做成多级看门狗

二、独立看门狗配置实战

#include "stm32f10x_iwdg.h"

void IWDG_Init(uint32_t prescaler, uint32_t reload_value)
{
    // 1. 使能LSI(独立看门狗的时钟源)
    RCC_LSICmd(ENABLE);
    while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);

    // 2. 使能寄存器访问(写IWDG_PR和IWDG_RLR前要先开访问权限)
    IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);

    // 3. 配置预分频器和重载值
    // LSI约40kHz,预分频64后 = 40000/64 = 625Hz,每个计数周期 = 1.6ms
    // 重载值499 -> 超时时间 = (499+1) * 1.6ms = 800ms
    IWDG_SetPrescaler(prescaler);
    IWDG_SetReload(reload_value);

    // 4. 重载计数器(写入重载值后计数器立即重置)
    IWDG_ReloadCounter();

    // 5. 使能看门狗
    IWDG_Enable();
}

void IWDG_Feed(void)
{
    IWDG_ReloadCounter();
}

三、窗口看门狗的妙用

窗口看门狗比独立看门狗高级在它可以检测”喂狗太快”的情况。正常逻辑是:

时间轴:|—窗口开启—|—喂狗窗口—|—窗口关闭—|

• 窗口开启后到窗口关闭前:可以喂狗

• 窗口关闭后到下次窗口开启:如果这时候喂狗会立即复位

适用场景:某个关键任务有严格的执行时间要求,你希望它必须在规定的时间内执行,不能太快也不能太慢。

void WWDG_Init(uint8_t window_value)
{
    // 1. 使能WWDG时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);

    // 2. 配置窗口值和分频器
    // PCLK2 = 72MHz, 分频器8 -> 9MHz计数时钟
    // 窗口值 = 0x60 (二进制01100000),计数器初始值也要>窗口值
    WWDG_SetWindowValue(window_value);
    WWDG_Enable(0x7F);  // 初始计数值,必须大于窗口值

    // 3. 使能WWDG中断(在超时前N个时钟产生预警中断,给你机会喂狗)
    WWDG_EnableIT();
}

void WWDG_IRQHandler(void)
{
    // 预警中断:在计数器即将超时前触发
    // 这里可以做些紧急处理,然后喂狗
    WWDG_SetCounter(0x7F);  // 喂狗(重置计数器)
    WWDG_ClearFlag();
}

四、实际项目中的看门狗设计策略

我在项目里一般这么设计:

1. 主循环喂狗:在main的while(1)循环里定期调用喂狗函数。如果主循环卡死了,看门狗会复位系统。

2. 关键任务独立看门狗:对于特别关键的任务(比如电机控制),用窗口看门狗监控,确保它在规定时间内执行。

3. 软件看门狗做健康检查:用一个变量记录各模块的状态,主循环定期检查所有模块是否正常。如果某个模块异常,记录错误日志后系统复位。

4. 上电自检:复位后先做硬件自检(RAM测试、外设检测),通过后才正常运行。自检失败就闪灯报警。

五、故障恢复策略

光有看门狗还不够,复位之后怎么办也很重要:

// 检查复位源
uint32_t reset_source = RCC->SR;

if(reset_source & RCC_SR_IWDGRSTF)
{
    // 独立看门狗复位
    // 清除标志
    RCC->SR &= ~RCC_SR_IWDGRSTF;
    // 读取Flash里的错误日志,分析原因
    // 可以闪红灯报警
}
else if(reset_source & RCC_SR_WWDGRSTF)
{
    // 窗口看门狗复位
    RCC->SR &= ~RCC_SR_WWDGRSTF;
    // 处理...
}
else if(reset_source & RCC_SR_PORSPDRSTF)
{
    // 上电复位
    // 做初始化...
}

注意

1. 看门狗的超时时间不要设太短。我见过有人设1ms的超时,结果中断优先级高被抢了没时间喂狗就直接复位了。一般设100ms~1s比较合理。

2. 喂狗函数里不要做耗时操作,就是写个寄存器而已,几微秒就完了。

3. 调试的时候可以把看门狗关掉,方便打断点。上线前一定要记得打开。

4. 建议在Flash或EEPROM里存个错误计数器,每次看门狗复位就加1。如果连续复位超过阈值,说明有硬件问题,停止尝试进入安全模式。

5. 最后说一句:看门狗不是万能的。它只能帮你从软件死锁里恢复,解决不了硬件问题。EMC设计、电源滤波、ESD防护这些该做还是要做。

来源: 整理文章为传播相关技术,网络版权归原作者所有,如有侵权,请联系删除。




共1条 1/1 1 跳转至页

回复

匿名不能发帖!请先 [ 登陆 注册 ]