窗口看门狗(WWDG)

1. WWDG 简介

  • 作用:在应用跑飞、死循环、长时间被中断占用等异常时,强制复位 MCU,提高系统可靠性。

  • 时钟来源:来自 APB1 时钟 (PCLK1) 的分频(与 IWDG 的 LSI 独立时钟不同)。

  • 核心特性

    • 7 位递减计数器 T[6:0]:从 0x7F 递减到 0x40,再到 0x3F 时复位。

    • 窗口值 W[6:0]:喂狗必须在“窗口”内进行(T ≤ W 且 T > 0x3F);

      • 喂早了(T > W)立刻复位

      • 喂晚了(T ≤ 0x3F)复位

    • EWI(Early Wakeup Interrupt)提前唤醒中断:当 T 递减到 0x40 时产生中断,给你“最后一次机会”喂狗。


2. 工作原理与简化框图

计数与窗口规则

T: 0x7F ──… 递减 …── 0x5F ──…── 0x40 ── 0x3F↑允许最早喂的位置=W (例如0x5F)     ↑EWI中断      ↑复位点
必须在 T∈(0x3F, W] 这个区间喂狗;早于W立即复位;晚于0x3F也复位

时钟链路与计数

PCLK1 ──÷4096──÷(1/2/4/8)──> 计数时钟tick  ──> 7位递减计数器 T[6:0]├─ T==0x40  → 触发EWI└─ T==0x3F  → 复位MCU

3. 寄存器与 HAL 函数

关键寄存器(STM32F1 系列)

  • WWDG_CR(控制/计数器寄存器)

    • WDGA(bit7):1=启动 WWDG

    • T[6:0]:当前计数值(写入相当于刷新/喂狗)

  • WWDG_CFR(配置寄存器)

    • W[6:0]:窗口值

    • WDGTB[1:0]:预分频(1/2/4/8)

    • EWI(bit9):提前唤醒中断使能

  • WWDG_SR(状态寄存器)

    • EWIF(bit0):EWI 标志位(到 0x40 时置位,软件写 0 清除)

HAL 屏蔽了直接位操作,底层完成上述写寄存器逻辑。

HAL 相关 API

  • HAL_WWDG_Init(&h):配置并启动 WWDG(设定 Counter、Window、Prescaler、EWI)。

  • HAL_WWDG_Refresh(&h)喂狗(刷新计数器)。

  • HAL_WWDG_EarlyWakeupCallback(&h)EWI 回调(T==0x40 时被调用)。

  • HAL_WWDG_IRQHandler(&h):在 WWDG_IRQHandler 里调用它,才能触发回调。

  • 复位来源判断:

    • __HAL_RCC_GET_FLAG(RCC_FLAG_WWDGRST):是否 WWDG 复位;

    • __HAL_RCC_CLEAR_RESET_FLAGS():清除复位标志。


4. 溢出时间与“喂狗窗口”计算

计数器递减 tick 周期

  • Prescaler ∈ {1,2,4,8}(HAL:WWDG_PRESCALER_1/2/4/8

  • 例:72 MHz 系统 + 默认 APB1=36 MHz,若 Prescaler=8:

代入你代码的参数

T_init=0x7FW=0x5FPrescaler=8PCLK1≈36 MHz

  • t_tick ≈ 0.910 ms

  • t_min = (0x7F-0x5F)*t_tick = 32*tick ≈ 29.1 ms

  • t_EWI = (0x7F-0x40)*t_tick = 63*tick ≈ 57.3 ms

  • t_reset = (0x7F-0x3F)*t_tick = 64*tick ≈ 58.3 ms

  • 允许喂狗窗口[29.1 ms, 58.3 ms)窗口宽度约 29.1 ms

  • 你主循环 delay_ms(50)50 ms 恰好落在窗口内,所以正常不会复位。

    • 若偶尔卡住,EWI 在 ~57.3 ms 触发回调,回调里你又 wwdg_feed(),可兜底避免复位。

5. 配置步骤(HAL 版)

  1. 打开 WWDG 时钟 + 中断(在 HAL_WWDG_MspInit 里)

__HAL_RCC_WWDG_CLK_ENABLE();
HAL_NVIC_SetPriority(WWDG_IRQn, 2, 2);
HAL_NVIC_EnableIRQ(WWDG_IRQn);

2.初始化并启动

wwdg_handle.Instance      = WWDG;
wwdg_handle.Init.Counter  = 0x7F;                 // 初值(7位)
wwdg_handle.Init.Window   = 0x5F;                 // 窗口
wwdg_handle.Init.Prescaler= WWDG_PRESCALER_8;     // 预分频
wwdg_handle.Init.EWIMode  = WWDG_EWI_ENABLE;      // 开EWI
HAL_WWDG_Init(&wwdg_handle);

3.中断服务与回调

void WWDG_IRQHandler(void){ HAL_WWDG_IRQHandler(&wwdg_handle); }void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *h){wwdg_feed();          // 最后时刻兜底喂狗led2_toggle();        // 观测EWI是否发生
}

4.周期性喂狗(窗口内)

HAL_WWDG_Refresh(&wwdg_handle);

5.复位来源识别

if(__HAL_RCC_GET_FLAG(RCC_FLAG_WWDGRST)) { /* ... */ }
__HAL_RCC_CLEAR_RESET_FLAGS();

调试注意:单步/断点会让时间停住。建议在调试时冻结 WWDG:
DBGMCU->APB1FZ |= DBGMCU_APB1_FZ_DBG_WWDG_STOP;(CubeMX 可勾选)

6.HAL 可选值速查

  • wwdg_handle.Init.Prescaler

    • WWDG_PRESCALER_1 / _2 / _4 / _8

  • wwdg_handle.Init.EWIMode

    • WWDG_EWI_DISABLE / WWDG_EWI_ENABLE

  • 复位标志(__HAL_RCC_GET_FLAG()):

    • RCC_FLAG_WWDGRST / IWDGRST / PINRST / PORRST / SFTRST

  • 计数/窗口范围

    • CounterWindow 都是 7 位有效0x40 ~ 0x7F

7. IWDG vs WWDG(差异对照)

特性

IWDG(独立看门狗)WWDG(窗口看门狗)
时钟源LSI(约40kHz,独立)APB1(PCLK1)/4096/Presc
能否停表一旦启动不可停可在调试时冻结(DBGMCU)
喂狗限制只要周期内喂即可必须在窗口内喂(太早/太晚都复位)
预警EWI(T==0x40)
典型用途无人值守、兜底安全需要“节拍约束”的系统(防止过早喂狗掩盖问题)

main.c

#include "sys.h"       // 系统时钟初始化函数
#include "delay.h"     // 延时函数
#include "led.h"       // LED 控制
#include "uart1.h"     // 串口1
#include "wwdg.h"      // 窗口看门狗驱动int main(void)
{HAL_Init();                         /* 初始化 HAL 库(NVIC 分组、SysTick 定时器等) */stm32_clock_init(RCC_PLL_MUL9);     /* 设置系统时钟为 72MHz(HSE=8MHz * 9) */led_init();                         /* 初始化 LED GPIO */uart1_init(115200);                 /* 初始化串口1,波特率 115200 *//* 初始化窗口看门狗* 参数1 tr:计数器初值(0x40 ~ 0x7F,最高7位有效)* 参数2 wr:窗口值(0x40 ~ 0x7F),喂狗时计数器必须 <= wr 才有效* 参数3 psc:分频器* 本例:Counter=0x7F (127),Window=0x5F (95),Prescaler=8*/wwdg_init(0x7f, 0x5f, WWDG_PRESCALER_8);printf("hello world!\r\n");/* 判断上次复位原因 */if(__HAL_RCC_GET_FLAG(RCC_FLAG_WWDGRST) != RESET){printf("窗口看门狗复位!\r\n");__HAL_RCC_CLEAR_RESET_FLAGS();  /* 清除复位标志 */}elseprintf("外部复位!\r\n");while(1){ delay_ms(50);          /* 延时 50ms */wwdg_feed();           /* 喂狗(刷新计数器) */led1_toggle();         /* 翻转 LED1,观察程序是否在运行 */}
}

wwdg.c

#include "wwdg.h"
#include "led.h"WWDG_HandleTypeDef wwdg_handle = {0};   // 窗口看门狗句柄/* 初始化窗口看门狗* tr: Counter 初值 (0x40 ~ 0x7F)* wr: Window 窗口值 (0x40 ~ 0x7F)* psc: 预分频系数*/
void wwdg_init(uint8_t tr, uint8_t wr, uint32_t psc)
{wwdg_handle.Instance = WWDG;             // 指定实例 = 窗口看门狗外设wwdg_handle.Init.Counter = tr;           // 设置计数器初值wwdg_handle.Init.Window = wr;            // 设置窗口值wwdg_handle.Init.Prescaler = psc;        // 设置分频系数wwdg_handle.Init.EWIMode = WWDG_EWI_ENABLE; // 使能提前唤醒中断(EWI)HAL_WWDG_Init(&wwdg_handle);             // 初始化硬件
}/* MSP 初始化:底层硬件配置 */
void HAL_WWDG_MspInit(WWDG_HandleTypeDef *hwwdg)
{__HAL_RCC_WWDG_CLK_ENABLE();   // 打开 WWDG 时钟/* 配置中断优先级 */HAL_NVIC_SetPriority(WWDG_IRQn, 2, 2);  // 抢占优先级2,子优先级2HAL_NVIC_EnableIRQ(WWDG_IRQn);          // 使能 WWDG 中断
}/* 窗口看门狗中断服务函数 */
void WWDG_IRQHandler(void)
{HAL_WWDG_IRQHandler(&wwdg_handle);  // 调用 HAL 库中断处理
}/* 提前唤醒回调函数* 当计数器降到 0x40 时产生 EWI 中断* 在这里可以做一些预处理(比如打印信息、刷新寄存器等)*/
void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg)
{wwdg_feed();       // 喂狗(刷新计数器)led2_toggle();     // 翻转 LED2,表示进入了回调
}/* 喂狗函数:刷新 WWDG 计数器 */
void wwdg_feed(void)
{HAL_WWDG_Refresh(&wwdg_handle);
}

实验现象

  1. 程序启动时

    • 串口打印 "hello world!"。

    • 判断复位来源,如果是看门狗复位,会打印“窗口看门狗复位!”。

  2. 正常情况(延时 50ms < 看门狗溢出时间)

    • 主循环中不断 wwdg_feed(),LED1 每 50ms 翻转一次。

    • 程序一直运行,LED1 闪烁。

  3. 提前唤醒中断现象

    • 当计数器下降到 0x40,触发 EWI 中断,执行 HAL_WWDG_EarlyWakeupCallback

      • 喂狗(防止复位)

      • LED2 翻转,表示进入了回调。

  4. 异常情况(如果不喂狗,或者喂狗太早/太晚)

    • WWDG 会复位 MCU,串口下次启动会打印“窗口看门狗复位!”。

 和独立看门狗 (IWDG) 不同,WWDG 多了“窗口限制”:喂狗必须在合适的范围内,太早/太晚都不行

可选参数

A. wwdg_handle.Init.Counter

  • 范围:0x40 ~ 0x7F(7 位有效)

  • 功能:设置计数器初值,从该值递减计数,减到 0x3F 时复位。

B. wwdg_handle.Init.Window

  • 范围:0x40 ~ 0x7F

  • 功能:定义一个“窗口值”。

    • 喂狗必须在计数器 ≤ Window 时才有效。

    • 如果喂狗时计数器 > Window → 立即复位!

C. wwdg_handle.Init.Prescaler

可选值(分频系数):

  • WWDG_PRESCALER_1

  • WWDG_PRESCALER_2

  • WWDG_PRESCALER_4

  • WWDG_PRESCALER_8

作用:控制计数器递减的速度。

D. wwdg_handle.Init.EWIMode

  • WWDG_EWI_DISABLE:不启用提前唤醒中断

  • WWDG_EWI_ENABLE:启用 EWI,当计数器降到 0x40 时产生中断(可在中断中喂狗)。

E. 复位标志

通过 __HAL_RCC_GET_FLAG() 获取:

  • RCC_FLAG_WWDGRST → 窗口看门狗复位

  • RCC_FLAG_IWDGRST → 独立看门狗复位

  • RCC_FLAG_PINRST → 外部复位

  • RCC_FLAG_PORRST → 上电复位

  • RCC_FLAG_SFTRST → 软件复位


 总结

  • WWDG 与 IWDG 的区别

    • IWDG:只要定期喂狗就行,没有窗口要求,独立时钟(LSI),一旦开启不可关闭。

    • WWDG:有窗口限制,喂狗太早/太晚都复位,用系统时钟分频,支持提前唤醒中断。

  • 本实验现象

    • LED1 周期闪烁,LED2 在回调中翻转;

    • 如果关闭喂狗 → MCU 重启 → 串口提示“窗口看门狗复位!”。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/96375.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/96375.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/96375.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PyTorch API 6

文章目录torch.onnx概述基于 TorchDynamo 的 ONNX 导出器基于TorchScript的ONNX导出器贡献与开发torch.optim如何使用优化器构建优化器每个参数的选项执行优化步骤optimizer.step()optimizer.step(closure)基类算法如何调整学习率如何利用命名参数加载优化器状态字典权重平均法…

2025年09月计算机二级MySQL选择题每日一练——第二期

计算机二级中选择题是非常重要的&#xff0c;所以开始写一个每日一题的专栏。 答案及解析将在末尾公布&#xff01; 今日主题&#xff1a;SQL 交互操作基础 1、有如下创建表的语句&#xff1a; CREATE TABLE tb_gs( gno CHAR(10) NOT NULL, sno CHAR(10) NOT NULL, gjob CH…

MySQL诊断系列(5/6):表结构与元数据查询——快速掌握数据库“DNA”

&#x1f517; 接上一篇《MySQL性能瓶颈定位》&#xff0c;今天我们来学习如何像查字典一样&#xff0c;快速、精准地了解任何数据库的内部结构。 当你接手一个新项目&#xff0c;或者需要排查一个不熟悉的模块时&#xff0c;你最需要的是什么&#xff1f; 不是代码&#xff0…

精准评估新纪元:AI得贤招聘官AI面试智能体6.3,重新定义AI面试

随着生成式AI技术爆发式发展&#xff0c;人力资源管理正经历从“信息化”到“智能化”的跃迁。据Gartner预测&#xff0c;2025年60%的企业将使用AI完成HR基础事务性工作。在这场变革中&#xff0c;AI得贤招聘官以其卓越的技术实力和产品能力&#xff0c;已成为行业智能化转型的…

MinerU:重新定义PDF智能提取的开源利器

MinerU&#xff1a;重新定义PDF智能提取的开源利器 ——告别传统工具的“鸡肋”体验&#xff0c;让文档处理真正高效智能 在数字化时代&#xff0c;PDF、Word等文档已成为信息传递的主要载体&#xff0c;但如何从这些格式中精准提取数据&#xff0c;却成了困扰无数人的难题。…

电脑芯片其实更偏向MPU不是CPU,GPU CPU NPU MPU MCU的区别

现代电脑的处理器&#xff08;如 Intel i5&#xff09;本质上是 MPU&#xff0c;因为它集成了 CPU 核心、缓存、定时器等&#xff0c;但我们日常仍习惯称其为 “CPU”电脑里的芯片&#xff08;如 Intel i5、AMD Ryzen&#xff09;通常被通俗地称为 “CPU”&#xff0c;但严格来…

Python爬虫XPath实战:电商商品ID的精准抓取策略

1. 引言 在电商数据爬取过程中&#xff0c;商品ID&#xff08;Product ID&#xff09;是最关键的字段之一&#xff0c;它通常用于唯一标识商品&#xff0c;并可用于构建商品详情页URL、价格监控、库存查询等场景。然而&#xff0c;不同电商网站的HTML结构差异较大&#xff0c;…

Web3:重构互联网秩序的下一代范式革命

Web3&#xff08;即 Web 3.0&#xff09;作为互联网发展的第三代形态&#xff0c;并非简单的技术迭代&#xff0c;而是一场围绕 “数据主权” 与 “价值分配” 的底层逻辑重构。它以区块链为核心骨架&#xff0c;融合分布式存储、密码学、人工智能等技术&#xff0c;旨在打破 W…

DeepSeek R2难产:近期 DeepSeek-V3.1 发布,迈向 Agent 时代的第一步

DeepSeek R2难产&#xff1a;近期 DeepSeek-V3.1 发布&#xff0c;迈向 Agent 时代的第一步 要说 AI 模型的江湖&#xff0c;这一年简直就是 「大模型修罗场」。 前脚 R2 传出难产的风声&#xff0c;后脚 DeepSeek 就甩出了一张大招牌&#xff1a;DeepSeek-V3.1。 这波操作不…

element-plus:el-tree ref初始化异常记录

文章目录描述问题解决记录一个tsx 下el-tree的小问题描述 <Dialog v-model"showEdit" :title"t(button.edit)" width"900" :maxHeight"650"><el-form :model"nowdata" class"dialog"><el-form-ite…

Linux软件安装(JDK,Mysql,Nginx)

安装方式介绍一、安装JDKtar -zxvf jdk-17.0.10_linux-x64_bin.tar.gz -C /usr/localexport JAVA_HOME/usr/local/jdk-17.0.10export PATH$JAVA_HOME/bin:$PATHsource /etc/profile1、操作步骤二、mysql黑马视频已经安装好了我们只需开放指定端口就可以在navicat中连接了&#…

公有地址和私有地址

在计算机网络中&#xff0c;私有地址和公有地址是IP地址的两大重要分类&#xff0c;二者在网络通信中承担着不同角色。下面从定义、联系、区别和应用四个维度进行详细说明&#xff1a; 一、定义 1. 公有地址&#xff08;Public IP Address&#xff09; 公有地址是全球唯一且可在…

分治思想在系统分流削峰中的实践与Golang前沿实现

分治思想在系统分流削峰中的实践与Golang前沿实现 1. 分治思想概述 分治(Divide and Conquer)是计算机科学中一种重要的算法设计思想&#xff0c;其核心在于"分而治之"——将复杂问题分解为若干个规模较小的相同或相似子问题&#xff0c;递归地解决这些子问题&#x…

移动端视口终极解决方案:使用 Visual Viewport封装一个优雅的 React Hook

前言 在移动端开发中&#xff0c;视口高度一直是一个令人头疼的问题。尤其是在 iOS Safari 浏览器中&#xff0c;还有三星手机的导航遮挡&#xff0c;当虚拟键盘弹出时&#xff0c;视口高度的变化会导致固定定位元素错位、全屏布局异常等问题。本文将深入分析这个问题的本质&a…

react中key的作用

在 React 中&#xff0c;key 是一个特殊的属性&#xff08;prop&#xff09;&#xff0c;它的主要作用是帮助 React 识别哪些元素发生了变化、被添加或被移除&#xff0c;从而高效地更新和重新渲染列表中的元素。以下是 key 的具体作用和注意事项&#xff1a;1. 高效更新虚拟 D…

Lua学习记录 - 自定义模块管理器

为人所知的是lua自带的require函数加载脚本只会加载一次(就像unity里面的资源管理和AB包管理)&#xff0c;而主播调试习惯是用Odin插件的Button在unity编辑器模式里调试而非进入播放模式后调试&#xff0c;今天主播在做热更新相关的时候企图多次调用脚本打印以调试功能&#xf…

MongoDB 分片集群复制数据库副本

文章目录一、登录MongoDB查询数据库及集合分片情况二、登录MongoDB先创建副本数据库并设置数据库及集合分片功能三、登录MongoDB查询emop_slinkmain数据库main_repetition集合和四、使用mongodump压缩备份emop_slinkmain数据库中的main_repetition集合和shard_repetition 集合五…

SQLite 加密与不加密性能对比与优化实践

在项目中&#xff0c;为了保证数据安全&#xff0c;我们可能会对 SQLite 数据库进行加密&#xff08;例如使用 SQLiteMC/SQLCipher&#xff09;。然而&#xff0c;加密数据库在带来安全性的同时&#xff0c;也会带来显著的性能损耗。本文结合实测与源码分析&#xff0c;介绍 SQ…

Azure官网为何没直接体现专业服务

微软Azure官网没有直接、醒目地展示其专业服务&#xff08;如迁移、定制化解决方案咨询等&#xff09;&#xff0c;确实容易让人疑惑。这背后其实是微软Azure特定的市场策略和商业模式。下面我为你解释原因&#xff0c;并告诉你怎么找到这些服务。&#x1f9e9; 核心原因&#…

人体生理参数信号采集项目——心电信号

1.硬件——焊接调试趣事&#xff1a;由于测量手法问题&#xff0c;以及对示波器不太熟悉&#xff0c;差点以为没信号&#xff0c;都打算重焊一块板子了&#xff0c;但&#xff0c;实际上&#xff0c;信号输出是相对完美的&#xff1b;遇到的疑难杂症&#xff1a;1&#xff09;5…