摘要:WWDG是STM32的窗口看门狗,与IWDG不同,WWDG专用于监测软件异常(如循环、阻塞),它使用6位递减计数器,从0x7F递减到0x40时触发复位;WWDG必须在指定时间窗口内刷新,在计数器的值大于W[6:0]值时喂狗也会复位;WWDG的时钟源来自APB1
WWDG是STM32的窗口看门狗,与IWDG不同,WWDG专用于监测软件异常(如循环、阻塞),它使用6位递减计数器,从0x7F递减到0x40时触发复位;
WWDG必须在指定时间窗口内刷新,在计数器的值大于W[6:0]值时喂狗也会复位;
WWDG的时钟源来自APB1(PCLK1)经过预分频。
在递计数器等于0x40时可以产生提前唤醒中断。
// 当计数器递减到0x40时触发复位// 若在计数器>0x7F时刷新会立即复位(防程序跑飞)HAL_WWDG_Refresh(&hwwdg); // 必须在窗口期内调用/* 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 */特性WWDGIWDG时钟源PCLK1(最高36MHz)LSI(约40kHz)复位条件过早/过晚刷新超时未刷新中断支持支持早期中断(可记录错误)无中断适用场景关键任务监控防系统死锁实际工程中建议将两者结合使用,如:
IWDG:作为系统级保底防护(类似防火墙)WWDG:保护核心业务逻辑(如报文解析循环)在STM32不同系列里,时钟源频率有所不同。
F103:PCLK1(36MHz)F407:PCLK1(42MHz)F429:PCLK1(45MHz)F767:PCLK1(54MHz)F743:PCLK1(100MHz)……窗口期是 W[6:0] >= 窗口期 > 0x3F
预分频器值列表:
T₅:₀计数器低6位值(CR寄存器[5:0])0x00 ~ 0x3FWDGTB预分频系数(CFR寄存器[8:7])0(1分频)~3(8分频)PCLKAPB总线时钟频率(MHz)8~72 (MHz)当配置参数:
计数器初始值 = 0x7F窗口值 = 0x5F预分频 = WWDG_PRESCALER_1 (WDGTB=0)PCLK = 32 MHz对于F1系列可以得到下表:
WDGTB最小超时值最大超时值0113us7.28ms1227us14.56ms2455us29.12ms3910us58.25ms主要作用是设置窗口值、计数值、预分频系统等进行设置,主要寄存器是 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;}}/* 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 */查看项目,
main函数会自动添加:
WWDG_HandleTypeDef hwwdg;并增加函数:
static void MX_WWDG_Init(void);/*** @brief WWDG InitializationFunction* @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;extern WWDG_HandleTypeDef hwwdg;// 在stm32xxx_it.c中添加(若不存在)void WWDG_IRQHandler(void){HAL_WWDG_IRQHandler(&hwwdg);}来源:编程圈子