You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32H7窗口看门狗(WWDG)唤醒中断失效及配置问题咨询

STM32H7窗口看门狗(WWDG)问题排查与解决

问题描述

  • 提前唤醒中断失效:配置了WWDG的EWI(提前唤醒中断),但系统复位前该中断从未触发,无法执行复位前的自定义代码。
  • 窗口值配置异常:当窗口值设置为小于计数器初始值时,芯片无法正常工作,但手册明确说明窗口值可小于等于计数器值。

用户提供的代码

WWDG配置代码

hwwdg1.Instance = WWDG1;
hwwdg1.Init.Prescaler = WWDG_PRESCALER_128;
hwwdg1.Init.Window = 127;
hwwdg1.Init.Counter = 127;
hwwdg1.Init.EWIMode = WWDG_EWI_ENABLE;
if (HAL_WWDG_Init(&hwwdg1) != HAL_OK)
{
  Error_Handler();
}

主测试代码

int main(void)
{

  MPU_Config();
  HAL_Init();

  SystemClock_Config();


  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_CRC_Init();
  MX_RTC_Init();
  MX_WWDG1_Init();

HAL_WWDG_Refresh(&hwwdg1);
    
HAL_GPIO_WritePin(AlarmLEDsVDD_GPIO_Port, AlarmLEDsVDD_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(YellowLEDs_GPIO_Port, YellowLEDs_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(RedLEDs_GPIO_Port, RedLEDs_Pin, GPIO_PIN_RESET);

HAL_GPIO_WritePin(AlarmLEDsVDD_GPIO_Port, AlarmLEDsVDD_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(YellowLEDs_GPIO_Port, YellowLEDs_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(RedLEDs_GPIO_Port, RedLEDs_Pin, GPIO_PIN_RESET);

int counter = 490;
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
        HAL_WWDG_Refresh(&hwwdg1);
        HAL_Delay(counter++); // limit is about 507-510 delay
  }
  /* USER CODE END 3 */
}

中断处理函数

void WWDG_IRQHandler(void)
{
  /* USER CODE BEGIN WWDG_IRQn 0 */
    
  /* USER CODE END WWDG_IRQn 0 */
  HAL_WWDG_IRQHandler(&hwwdg1);
  /* USER CODE BEGIN WWDG_IRQn 1 */

  /* USER CODE END WWDG_IRQn 1 */
}

问题分析与解决

问题1:提前唤醒中断未触发

核心原因及修复步骤

  1. NVIC中断未配置使能
    HAL库不会自动配置WWDG的NVIC中断,需要在HAL_WWDG_MspInit函数中手动添加NVIC配置,否则中断无法触发:

    void HAL_WWDG_MspInit(WWDG_HandleTypeDef* hwwdg)
    {
      if(hwwdg->Instance==WWDG1)
      {
        __HAL_RCC_WWDG1_CLK_ENABLE();
        // 配置中断优先级,可根据实际需求调整
        HAL_NVIC_SetPriority(WWDG_IRQn, 0, 0);
        HAL_NVIC_EnableIRQ(WWDG_IRQn);
      }
    }
    
  2. 测试逻辑导致中断无触发机会
    WWDG的提前唤醒中断仅在计数器递减到0x40(十进制64)时触发,随后计数器继续递减到0x3F时触发复位。
    按用户配置计算WWDG总超时时间:假设PCLK1为100MHz,WWDG时钟为PCLK1/4=25MHz,预分频128,计数器从127递减到0x3F的总时间约为328ms。而用户初始延迟为490ms,远大于超时时间,导致计数器直接递减到复位值,根本没机会走到0x40触发中断。
    修复测试逻辑:先保持小延迟保证正常刷新,再主动停止刷新等待中断触发:

    int counter = 100;
    while (1)
    {
      HAL_WWDG_Refresh(&hwwdg1);
      HAL_Delay(counter);
      if(counter >= 400) {
        // 停止刷新,等待中断触发后复位
        while(1);
      }
      counter += 50;
    }
    
  3. 未实现中断回调函数
    HAL库中,HAL_WWDG_IRQHandler会调用HAL_WWDG_EarlyWakeupCallback执行自定义逻辑,用户需要重写该函数:

    void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg)
    {
      // 复位前的处理代码,比如切换LED状态
      HAL_GPIO_WritePin(YellowLEDs_GPIO_Port, YellowLEDs_Pin, GPIO_PIN_RESET);
      HAL_GPIO_WritePin(RedLEDs_GPIO_Port, RedLEDs_Pin, GPIO_PIN_SET);
      // 代码要尽量精简,因为很快会触发复位
    }
    

问题2:窗口值小于计数器值时芯片异常

核心原因及修复步骤

WWDG的窗口规则是:仅当当前计数器值大于窗口值时,才能执行刷新操作。如果在计数器值≤窗口值时调用HAL_WWDG_Refresh,会立即触发系统复位。
用户测试时主循环每次都调用刷新函数,当计数器递减到窗口值以下时,刷新操作直接触发复位,表现为“芯片无法正常工作”。

修复方法:

  • 若不需要窗口限制,将窗口值设为最大值0x7F(十进制127),此时刷新操作在计数器值0x7F~0x40范围内都允许。
  • 若需要窗口限制,需在代码中判断计数器值是否大于窗口值,再执行刷新:
    // 读取当前计数器值
    uint32_t current_counter = WWDG1->CR & WWDG_CR_T;
    if(current_counter > hwwdg1.Init.Window) {
      HAL_WWDG_Refresh(&hwwdg1);
    }
    

内容的提问来源于stack exchange,提问作者ali .V

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 22:35:01