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

360影视 国产动漫 2025-05-07 14:02 2

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

窗口期是 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.25msHAL_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;}}/* 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 */预分频系数设置为8,窗口值 0x5F,计数器值为0x7F,启用Early wakeup interrupt(图中忘启用了,从代码中启用)。

查看项目,

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);}

来源:编程圈子

相关推荐