北屋教程网

专注编程知识分享,从入门到精通的编程学习平台

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的比较

特性

WWDG

IWDG

时钟源

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才能工作)

预分频器值列表:


  • 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:

计数器低6位值(CR寄存器[5:0])

0x00 ~ 0x3F

WDGTB

预分频系数(CFR寄存器[8:7])

0(1分频)~3(8分频)

PCLK

APB总线时钟频率(MHz)

8~72 (MHz)

使用示例

当配置参数:

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

计算步骤:

最小超时时间:



最大超时时间:



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

WDGTB

最小超时值

最大超时值

0

113us

7.28ms

1

227us

14.56ms

2

455us

29.12ms

3

910us

58.25ms

五、WWDG HAL库配置步骤

1. 整体流程



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);
}
控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言