STM32F103 看门狗实战:IWDG 防死机 + WWDG 抓跑飞,双狗守护全流程拆解

发布时间:2026/10/19 3:57:09

STM32F103 看门狗实战:IWDG 防死机 + WWDG 抓跑飞,双狗守护全流程拆解 给一台工业控制器做现场维护客户报「设备偶尔死机断电重启就好」。第一版方案简单粗暴装独立看门狗主循环末尾喂狗卡死就自动复位——问题确实解决了。但后来另一台设备出现更隐蔽的现象程序没死指示灯乱跳输出随机变化IWDG 却一次都没触发——因为主循环还活着只是状态机被干扰跑飞了。这版换上了窗口看门狗程序「跑太快、跑太慢」都会被它抓住。本文把两只狗的原理、配置、喂狗设计一次讲透。一、两只狗IWDG 防「死」WWDG 防「乱」F103 内置两只看门狗分工完全不同配图说明左卡 IWDGLSI 独立时钟、12 位计数器、防主时钟失效右卡 WWDGPCLK1 时钟、7 位窗口计数器、抓程序节奏。IWDG 独立看门狗挂在 LSI 上——一个标称 40kHz 的内部 RC 振荡器主时钟挂了它也照常计数所以它能兜住「晶振停振、程序跑飞」这类最恶劣的故障。12 位递减计数器减到 0 就整片复位。代价是 LSI 精度差实际 30~60kHz 波动超时时间只能估算。WWDG 窗口看门狗挂在 APB1 上时钟停了它也停——它不负责兜底负责抓节奏。7 位计数器在窗口内喂狗才有效喂早了复位程序跑太快、喂晚了复位程序跑太慢只认「按计划干活」。选型一句话只要防死 → IWDG要抓「该干活时没按节奏干」→ WWDG关键设备两个一起上。双狗的经典组合是窗口内喂 IWDG主循环正常节奏里同时喂两只狗WWDG 负责盯节奏IWDG 负责兜底——程序节奏乱了WWDG 先发难程序真死了IWDG 兜住。两个看门狗互为对方的「证据」杜绝了「只装一只时另一只被假喂」的盲区。二、IWDG1 秒超时是怎么算出来的IWDG 的配置核心是键寄存器 KR 的三把钥匙以及一条超时公式配图说明LSI 40kHz → PR 分频 ÷32 → 1.25kHz 计数 → RLR 重装载 1250 拍 → 1 秒归零复位三密钥 0xCCCC 启动 / 0xAAAA 喂狗 / 0x5555 解锁。Tout (4 × 2^prer) × (rlr 1) / 40kHzprer 是预分频值0~6 对应 ÷4~÷256rlr 是 12 位重装载值0~4095。以 1 秒超时为例prer3÷32、rlr1249 → 32 × 1250 / 40000 1000ms。÷4 分频最短 0.1ms÷256 分频最长约 26 秒。注意 LSI 在 30~60kHz 之间波动1 秒的「标称超时」实际可能在 0.7~1.3 秒——所以喂狗周期取超时的三分之一到二分之一别卡临界点。voidIWDG_Init(void){/* ① 0x5555 解锁之后才能写 PR 和 RLR */IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);/* ② 分频 ÷32prer3 */IWDG_SetPrescaler(IWDG_Prescaler_32);/* ③ 重装载值 124932 × 1250 / 40kHz 1s 超时 */IWDG_SetReload(1249);/* ④ 预装载 RLR等同步完成 */IWDG_ReloadCounter();/* ⑤ 0xCCCC 启动启动后只能靠复位关闭 */IWDG_Enable();}/* 喂狗 写 0xAAAA把 RLR 重装进计数器 */#defineFEED_DOG()IWDG_ReloadCounter()喂狗即IWDG_ReloadCounter()等价于写 0xAAAA。注意修改 PR/RLR 前必须写 0x5555 解锁且改完要等 SR 寄存器的 PVU/RVU 位清零再操作——代码里IWDG_ReloadCounter()预装载一次就是规避这个同步等待。三、WWDG喂早了也复位窗口就是规矩WWDG 的计数器只有 7 位从初值通常 0x7F递减喂狗必须落在窗口内——这是它和 IWDG 最大的不同配图说明计数器 0x7F 递减窗口 0x40~0x50绿色CNT W 喂狗复位早喂区减到 0x3F 不复位也复位晚喂区EWI 中断在 0x40 触发。窗口上限 W 可配必须 0x40 W 0x7F下限 0x40 固定。喂狗条件是0x40 ≤ CNT ≤ W计数器还大于 W 时重装 → 立即复位减到 0x40 以下还没喂 → 减到 0x3F 时复位。「太早」和「太晚」都是故障——窗口机制要抓的就是程序节奏乱了。超时按T (4096 × 2^WDGTB) / 36MHz × (初值 − 0x40)算WDGTB÷8、初值 0x7F 时每计数 0.91ms全段约 57ms——窗口短只适合主循环周期稳定的场合。voidWWDG_Init(void){/* ① 开 WWDG 时钟挂 APB1 */RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE);/* ② 分频 ÷80.91ms/计数——必须先于启动配置 */WWDG_SetPrescaler(WWDG_Prescaler_8);/* ③ 窗口上限 W0x500x40~0x50 之间喂狗有效 */WWDG_SetWindowValue(0x50);/* ④ 初值 0x7F WDGA 启动T6 必须为 1防启动即复位 */WWDG_Enable(0x7F);/* ⑤ 清残留中断标志再开 EWI 提前唤醒中断 */WWDG_ClearFlag(WWDG_FLAG_EWIF);WWDG_EnableIT();NVIC_EnableIRQ(WWDG_IRQn);}/* 喂狗重装回初值 0x7F喂狗相位由主循环节奏决定见下 */voidWWDG_Feed(void){WWDG_SetCounter(0x7F);}配置顺序是硬规矩分频、窗口、初值必须在 WDGA 启动之前配好——启动后计数器大于 W 时改 CFR 配置寄存器会立即触发复位。窗口设计有个容易忽略的点喂狗节奏必须匹配窗口相位。窗口是 0x40~0x5047 拍 ≈ 42.8ms 到 63 拍 ≈ 57.3ms喂狗动作必须落在这个时间段里——主循环 10ms 一圈每 5 圈50ms喂一次喂狗时刻 CNT ≈ 0x48正好在窗口内如果改成每圈都喂10ms 就喂一次喂狗时刻 CNT ≈ 0x74大于 W喂早了立即复位——这就是「窗口」抓跑快的机理程序节奏乱了、提前执行到喂狗代码计数器还停在窗口外一次就露馅。EWI 中断在计数器减到 0x40 时触发相当于「死缓通知」从 0x40 到 0x3F 复位只差一拍÷8 时 0.91ms中断里要么立刻喂狗要么只做紧急保存别干重活voidWWDG_IRQHandler(void){if(WWDG_GetFlagStatus(WWDG_FLAG_EWIF)SET){/* 0x40 触发主循环节奏已经乱了最多再活 1 拍 */Save_Emergency_State();/* 只做最紧急的现场保存 */WWDG_SetCounter(0x7F);/* 立刻喂狗仍在窗口内争取一次机会 */WWDG_ClearFlag(WWDG_FLAG_EWIF);/* 清 EWIF否则中断反复进 */}}「EWI 里喂狗」是策略选择默认只保存现场、不喂让复位发生用复位标志记账——比在中断里救一个已经乱掉的程序更可靠。只有在「复位代价大于救活代价」的场景比如断电丢失累计数据才选择喂。四、喂狗节奏在哪喂决定能保护谁IWDG 超时设 1s、主循环周期 10ms计数器每 20 次循环喂一次——喂狗周期 200ms是超时的五分之一配图说明正常行每 200ms 喂一次绿超时线 1s跑飞行任务段卡死在 600ms无喂狗 → 超时复位。/* 主循环IWDG 每 20 圈≈200ms喂一次WWDG 每 5 圈≈50ms喂一次 */staticuint32_tloop_cnt0,ww_cnt0;while(1){Task_ScanKey();/* 按键扫描 */Task_StateMachine();/* 状态机WWDG 窗口守护的就是这里 */Task_Report();/* 数据上报 */if(ww_cnt5){ww_cnt0;WWDG_Feed();}/* 50ms窗口内 */if(loop_cnt20){loop_cnt0;FEED_DOG();}}喂狗位置决定保护范围。主循环末尾喂任何任务段卡死循环停转看门狗照常复位——裸机最简单可靠的方案。定时器中断里喂是反例主程序跑飞但中断还正常看门狗被喂得饱饱的永不复位——装了等于没装比不装更危险。RTOS 下用分级喂狗每个任务周期汇报「我活着」一个喂狗任务汇总后统一喂任一任务卡死都会让看门狗超时。注意 IWDG 和 WWDG 的喂狗节奏完全不同IWDG 超时 1s、每 200ms 喂一次是宽松节奏WWDG 窗口只有 57ms 宽喂狗必须踩在窗口相位上——两只狗各自按自己的节拍喂互不干扰这就是「双狗」的正确用法。喂狗周期怎么定先按超时的三分之一到二分之一取比如超时 1s 就每 200~300ms 喂一次然后做一次「最坏情况测试」人为让最慢的任务段跑满比如 Flash 写页、外设重连量出最坏循环时间确认喂狗点离超时线还有两倍以上余量。调试期可以先设长超时比如 10s验证逻辑功能稳定后再收紧到目标值——一上来就 1s 超时遇到正常的慢路径首次上电、校准耗时误复位反而分不清是程序问题还是配置问题配图说明A 主循环喂裸机首选、B 定时器中断喂假活反例中断正常时看门狗失聪、C RTOS 分级喂每任务报活 汇总喂双狗组合 WWDG 抓节奏 IWDG 兜底。五、醒过来先问一句谁把我复位的看门狗复位和上电复位对程序是两回事——上电要全量初始化看门狗复位则意味着「上次运行死了带着现场信息重新来」。区分方法在 RCC 的 CSR 寄存器intmain(void){uint8_tboot_reasonBOOT_POWER_ON;if(RCC_GetFlagStatus(RCC_FLAG_IWDGRST)SET)boot_reasonBOOT_IWDG_RESET;/* 上次被 IWDG 复位 */if(RCC_GetFlagStatus(RCC_FLAG_WWDGRST)SET)boot_reasonBOOT_WWDG_RESET;/* 上次被 WWDG 复位 */RCC_ClearFlag();/* 清标志下次才判得准 *//* 按 boot_reason 分流正常启动 / 进安全模式 / 保留现场告警 */...}RCC_FLAG_IWDGRST/RCC_FLAG_WWDGRST分别对应 CSR 寄存器的 bit29/bit30。清标志要写 RMVF 位RCC_ClearFlag()否则下次复位的原因会被上一次污染。工程里这个标志通常伴随上电日志连续多次 IWDG 复位就该告警「程序长期不稳定」而不是默默重启了事。更进一步可以把复位次数记进备份寄存器Standby 下唯一活着的地方低功耗篇讲过连续复位超过阈值就进安全模式——关掉故障功能、只保留最小通信等工程师介入而不是无限重启循环。六、六个最容易翻车的点LSI 波动当精确定时实际 30~60kHz标称 1s 可能只有 0.7s——喂狗周期取超时的 1/3~1/2。中断里喂狗「假活」主程序跑飞但中断正常看门狗被定时喂饱永不复位——喂狗必须挂在主程序呼吸上。WWDG 窗口外喂狗CNT W 时重装 立即复位——喂狗前先确认在窗口内。启动后再改配置WWDG 启动后 CNT W 时写 CFR 也复位——分频/窗口/初值必须在 WDGA 前配好IWDG 改 PR/RLR 忘写 0x5555 解锁则写不进去。复位后不查复位标志上电、IWDG 复位、WWDG 复位全按普通启动跑——main 开头查标志记日志、进安全模式。EWI 中断里干重活0x40 到 0x3F 只差 0.91ms÷8 时——只做紧急保存 立即喂狗。小结两只狗的本质区别IWDG 听心跳WWDG 看节拍。裸机主循环末尾喂 IWDG是最低成本的防死机方案要抓状态机跑飞这类「没死但乱了」的故障上 WWDG 窗口关键设备双狗齐上IWDG 兜底 WWDG 抓节奏互为备份。别忘了复位标志——看门狗每复位一次都是系统在说话听懂它比一味加狗更重要。下一站回到内核看门狗在 RTOS 下的多任务喂狗设计分级喂狗、喂狗任务与死锁检测是 uC/OS-II 系列的内容。而下篇先讲 K1 任务堆栈实战——栈会不会爆、爆了怎么救一次讲透。
延伸阅读

更多相关文章

2026/10/18 20:06:06

深度拆解:论文问卷设计怎么避坑?5个维度

导语 论文问卷设计总踩坑:维度划分没依据、题目表述有歧义、信效度检验被导师一轮轮打回……其实问卷设计是有章法的,多数返工都集中在 5 个维度上:理论依据、题项编制、信度检验、效度检验、预测试与样本管理。本文把这 5 个维度逐一拆透&am…

2026/10/17 10:29:45

Claude SDK Hooks机制详解:从事件回调到自动化工作流

这次我们不聊模型榜单,也不聊提示词技巧,直接进入工程化能力:Claude 的 SDK Hooks。这是“Zero to Claude Certified Architect — Complete Beginner’s Guide”系列的第六部分,也是从“会调接口”走向“能设计自动化流程”的转折…

2026/10/16 18:41:36

深度学习花书中文PDF+项目源码:理论与实战双线学习指南

简介:深度学习领域经典著作《深度学习》(“花书”)的中文PDF配套源码包,面向希望将理论落地到代码的AI学习者与科研人员。压缩包共3个文件,包含inscode工程配置、index.html展示页面及gitignore规则文件,整…

2026/10/19 3:55:08

批量点转栅格实操指南:GDAL参数详解与踩坑排查

最近好几个项目都卡在同一个环节上——手里攒了几十万个点,分布在不同分区,业务方开口就是要“转成栅格,做成标准切片,最好一键能出全图”。单个点文件转栅格,很多教程都有,真到了“批量点转栅格”这一步&a…

2026/10/19 3:55:08

操作系统概论:从资源管理到并发共享的核心逻辑

1. 操作系统到底在管什么:从开机那一刻说起很多人学操作系统,第一反应就是背概念:进程、线程、死锁、分页。背完考完,过两个月全忘光。我自己当年也是这样,直到有一次帮朋友排查一台老机器开机特别慢的问题&#xff0c…

2026/10/19 3:55:08

开源代码审查CLI工具:本地化、Git原生、零数据上传

1. 项目概述:一个真正能落地的开源代码审查 CLI 工具“open-code-review” 这个名字乍看平平无奇,但拆开来看——open不是泛指“开源”,而是强调开放可审计、开放可定制、开放可集成;code review也不是简单地把 PR 描述丢给大模型…

2026/10/19 3:55:08

Simulink模型生成DLL全流程:配置、编译与跨语言调用

简介:面向需要将Simulink算法封装为动态链接库、并集成到外部应用程序中的中高级工程师与研究人员,这份资料覆盖从模型配置、代码生成、DLL编译到S-Function调用的完整链路。内容包括Simulink代码生成配置、库输出类型选择、自定义编译器标志、S-Functio…

2026/10/19 3:50:07

Java+SSM+Django驾校预约系统毕设实战:并发冲突、状态机与部署排查

“驾校预约管理系统”这个标题我太熟了。这几年带过不少毕设项目,光这一类的预约管理系统,从JavaSSM到Django版本都摸过一遍。很多同学拿到这种题目第一反应是“又是套路化的CRUD”,但实际上预约类业务和普通的学生管理系统、商城系统有本质区…

2026/10/18 0:01:50

金融AI落地指南:从调研报告到技术选型与工程实践

简介:这份PDF报告聚焦2025年金融服务业中国AI现状与趋势,面向金融科技从业者、AI战略规划人员及关注行业数字化转型的研究者,帮助读者把握生成式AI在银行、支付、交易等场景中的落地路径与投资方向。资源包内含1个PDF文件,大小约1…

2026/10/19 0:04:56

悟空开源无代码平台实战:从实体建模到应用设计避坑指南

简介:基于悟空开源无代码平台的多种应用设计源码,面向希望在不编写代码的情况下快速搭建CRM、HRM、财务系统、ERP、SRM等业务应用的企业与技术人员,通过拖放式界面和内置模板即可完成应用定制与部署。压缩包共697个文件,约10.74MB…

2026/10/19 0:04:56

基于.NET9的多租户权限系统:数据权限与动态API落地实践

简介:这份资源是一套面向 .NET 与 Vue 全栈开发者的中台权限管理系统,后端基于 .Net9,前端采用 Vue3 Element Plus,并配套 uniapp uviewui 移动端方案,实现前后端分离。系统覆盖多租户隔离、数据权限、动态 Api、任务…

2026/10/19 0:04:56

场地预约小程序毕设实战:SSM+微信小程序+MySQL数据库设计到避坑

简介:面向毕业设计场景的场地预约小程序完整项目,基于微信小程序SSMMySql技术栈开发,适合计算机相关专业学生作为选题参考、功能扩展或二次开发起点。系统实现场地类型管理、场地管理、预约管理、取消申请与押金退回等功能,分为管…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑