STM32 HAL库开发学习12. WWDG外设

一、WWDG功能介绍

1. WWDG简介

WWDG是STM32的窗口看门狗,与IWDG不同,WWDG专用于监测软件异常(如循环、阻塞),它使用6位递减计数器,从0x7F递减到0x40时触发复位;
WWDG必须在指定时间窗口内刷新,在计数器的值大于W[6:0]值时喂狗也会复位;
WWDG的时钟源来自APB1(PCLK1)经过预分频。

在递计数器等于0x40时可以产生提前唤醒中断。

2. WWDG的作用

WWDG主要作用有以下三点:

(1)精准时序控制

  1. 必须在指定时间窗口(0x40~0x7F)内刷新
  2. 防止过早刷新(程序运行过快)或过晚刷新(程序阻塞)
  3. 典型应用:保障关键任务(如通信协议处理)的实时性

(2)异常检测机制

// 当计数器递减到0x40时触发复位
// 若在计数器>0x7F时刷新会立即复位(防程序跑飞)
HAL_WWDG_Refresh(&hwwdg); // 必须在窗口期内调用

(3)故障预警功能

/* USER CODE BEGIN 4 */
void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg)
{
    // 在复位前记录错误信息(比IWDG多出预警阶段)
    HAL_UART_Transmit(&huart1, (uint8_t *)"SYSTEM_WARNING!\r\n", 16, 100);
    __ASM volatile("nop"); // 预留处理时间
}
/* USER CODE END 4 */

3. IWDG与WWDG的比较

特性WWDGIWDG
时钟源PCLK1(最高36MHz)LSI(约40kHz)
复位条件过早/过晚刷新超时未刷新
中断支持支持早期中断(可记录错误)无中断
适用场景关键任务监控防系统死锁

实际工程中建议将两者结合使用,如:

  1. IWDG:作为系统级保底防护(类似防火墙)
  2. WWDG:保护核心业务逻辑(如报文解析循环)

4. WWDG框图

在这里插入图片描述

时钟源

在STM32不同系列里,时钟源频率有所不同。

  • F103:PCLK1(36MHz)
  • F407:PCLK1(42MHz)
  • F429:PCLK1(45MHz)
  • F767:PCLK1(54MHz)
  • F743:PCLK1(100MHz)
  • ……

二、WWDG的工作过程

在这里插入图片描述
在这里插入图片描述

  • 计数器的初始值是0x7F(127),随时时间增加计数器开始递减。
  • 减到窗口上限值(图示0x5F)之前,如果喂狗,就会产生复位,这个值是可以改的;
  • 减到0x40(64)之间,可产生中断,这个值是可以改的;
  • 减到窗口下限值 0x63 ,产生复位,这个值是固定的。

窗口期是 W[6:0] >= 窗口期 > 0x3F

三、WWDG寄存器

1. WWDG_CR控制寄存器

  • 第6:0位:递减计数器(T[6:0])
  • 第7位:激活位(WDGA),置1启用WWDG

2. WWDG_CFR 配置寄存器

  • 第6:0位:窗口值(W[6:0])
  • 第8:7位:预分频器(WDGTB[1:0])
  • 第9位:提前唤醒中断使能(EWI),计数器达到0x40时产生中断(另外需要启动NVIC才能工作)

预分频器值列表: 2 W D G T B 2^{WDGTB} 2WDGTB

  • 00: CK计时器时钟(PCLK1除以4096) 除以1
  • 01: CK计时器时钟(PCLK1除以4096) 除以2
  • 10: CK计时器时钟(PCLK1除以4096) 除以4
  • 11: CK计时器时钟(PCLK1除以4096) 除以8

3. WWDG_SR 状态寄存器

  • 第0位:提前唤醒中断标志(EWIF)。当计数器值达到40h时,此位由硬件置1。它必须通过软件写“0”来清除。

四、WWDG超时时间计算

基本公式

T w w d g = ( T 5 : 0 + 1 ) × 4096 × 2 W D G T B P C L K ( m s ) T_{wwdg} = \frac{(T_{5:0} + 1) \times 4096 \times 2^{WDGTB}}{PCLK} \quad (ms) Twwdg=PCLK(T5:0+1)×4096×2WDGTB(ms)

符号说明典型值范围
T₅:₀计数器低6位值(CR寄存器[5:0])0x00 ~ 0x3F
WDGTB预分频系数(CFR寄存器[8:7])0(1分频)~3(8分频)
PCLKAPB总线时钟频率(MHz)8~72 (MHz)

使用示例

当配置参数:

  • 计数器初始值 = 0x7F
  • 窗口值 = 0x5F
  • 预分频 = WWDG_PRESCALER_1 (WDGTB=0)
  • PCLK = 32 MHz

计算步骤:

最小超时时间:

T = ( 0 x 00 + 1 ) × 4096 × 2 0 36000000 × 1000000 = 113 u s T = \frac{(0x00 + 1) \times 4096 \times 2^{0}}{36000000} \times 1000000 = 113us T=36000000(0x00+1)×4096×20×1000000=113us

最大超时时间:

T = ( 63 + 1 ) × 4096 × 2 0 36000000 × 1000 = 7.28 m s T = \frac{(63+1) \times 4096 \times 2^0}{36000000} \times 1000 = 7.28ms T=36000000(63+1)×4096×20×1000=7.28ms

对于F1系列可以得到下表:

WDGTB最小超时值最大超时值
0113us7.28ms
1227us14.56ms
2455us29.12ms
3910us58.25ms

五、WWDG HAL库配置步骤

1. 整体流程

Created with Raphaël 2.3.0 开始 WWDG工作参数初始化 WWDG MSP初始化 设置中断优先级 编写中断服务函数 重定义提前唤醒回调函数 是否在窗口期内喂狗? 系统复位 yes no

2. 相关HAL库函数介绍

(1)HAL_WWDG_Init

HAL_StatusTypeDef HAL_WWDG_Init(WWDG_HandleTypeDef *hwwdg);

主要作用是设置窗口值、计数值、预分频系统等进行设置,主要寄存器是 WWDG_CR,WWDGCRF,其典型代码:

// 典型用法示例:
WWDG_HandleTypeDef hwwdg;

void MX_WWDG_Init(void)
{
  hwwdg.Instance = WWDG;                     // 选择WWDG外设
  hwwdg.Init.Prescaler = WWDG_PRESCALER_8;  // 预分频系数
  hwwdg.Init.Window = 0x5F;                 // 窗口值(0x40 ~ 0x7F)
  hwwdg.Init.Counter = 0x7F;                // 初始计数器(必须 >= 窗口值)
  hwwdg.Init.EWIMode = WWDG_EWI_ENABLE;     // 使能提前唤醒中断
  
  if (HAL_WWDG_Init(&hwwdg) != HAL_OK) {
    Error_Handler();
  }
}

(2)HAL_WWDG_Refresh

重装载计数器,即喂狗,主要操作寄存器是 WWDG_CR T[6:0]。
典型用法示例:

/* USER CODE BEGIN 4 */
// 典型用法示例:
void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg) 
{
    // 在窗口期内刷新计数器(喂狗)
    HAL_WWDG_Refresh(hwwdg);  // 重新加载计数器值为初始值
    
    // 可以添加调试信息
    HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_0); // LED状态翻转
}
/* USER CODE END 4 */

3. STM32CubeMX 配置WWDG

本示例使用早期中断,设置如下:

在这里插入图片描述

  • 预分频系数设置为8,
  • 窗口值 0x5F,
  • 计数器值为0x7F,
  • 启用Early wakeup interrupt(图中忘启用了,从代码中启用)。

查看项目,
在这里插入图片描述

main文件

main函数会自动添加:

WWDG_HandleTypeDef hwwdg;

并增加函数:

static void MX_WWDG_Init(void);
/**
  * @brief WWDG Initialization Function
  * @param None
  * @retval None
  */
static void MX_WWDG_Init(void)
{

  /* USER CODE BEGIN WWDG_Init 0 */

  /* USER CODE END WWDG_Init 0 */

  /* USER CODE BEGIN WWDG_Init 1 */

  /* USER CODE END WWDG_Init 1 */
  hwwdg.Instance = WWDG;
  hwwdg.Init.Prescaler = WWDG_PRESCALER_8;
  hwwdg.Init.Window = 0x5F;
  hwwdg.Init.Counter = 0x7F;
  hwwdg.Init.EWIMode = WWDG_EWI_ENABLE;
  if (HAL_WWDG_Init(&hwwdg) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN WWDG_Init 2 */
    // 添加中断优先级配置
    HAL_NVIC_SetPriority(WWDG_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(WWDG_IRQn);
  /* USER CODE END WWDG_Init 2 */

}


中断函数:

void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg)
{
    HAL_WWDG_Refresh(hwwdg);  // 必须在此中断中喂狗
    HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_0); // 添加LED指示
}

在main函数里会调用 :


  MX_GPIO_Init();
  MX_USART1_UART_Init();
  //MX_IWDG_Init();
  MX_WWDG_Init();

stm32f1xx_it.c 中断设置


extern WWDG_HandleTypeDef hwwdg;

// 在stm32xxx_it.c中添加(若不存在)
void WWDG_IRQHandler(void)
{
    HAL_WWDG_IRQHandler(&hwwdg);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI星球

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值