一、CubeMX配置
选择对应的mcu型号,新建工程
输入相应型号,选中并开始工程
sys中打开调试
时钟配置
GPIO配置板载LED小灯
IWDG配置
可以计算出复位时间是1.6s
串口一配置
生成工程
二、IWDG
添加串口重定向
/* USER CODE BEGIN 0 */ uint32_t count=0; #include <stdio.h> int fputc(int ch,FILE *f) { HAL_UART_Transmit(&huart1,(uint8_t*)&ch,1,0xFFFF); return ch; } /* USER CODE END 0 */
勾选use microLIB
看门狗及时喂狗代码
/* USER CODE BEGIN 2 */ printf("start %d\r\n",count++); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { HAL_IWDG_Refresh(&hiwdg); printf("循环 %d次\r\n",count++); HAL_Delay(1000); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */
运行状态
看门狗超时喂狗
/* USER CODE BEGIN 2 */ printf("start %d\r\n",count++); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { HAL_IWDG_Refresh(&hiwdg); printf("循环 %d次\r\n",count++); HAL_Delay(2000); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ }
运行效果
三、WWDG
在之前的基础上改,打开WWDG配置以下参数:
- Prescaler (预分频器): 选择预分频因子,可以是 1、2、4 或 8。
- Window Value (窗口值): 设置WWDG的窗口值,即看门狗的允许计数器值范围。
- Counter Value (计数器值): 设置WWDG的初始计数器值。通常设置为小于或等于窗口值的一半。
WWDG的主时钟是PCLK1(APB1的时钟),这里设置为8,则分频为PCLK1/8/4096;
窗口看门狗的计时器是减法计数,从设置的WWDG free-running downcounter value向下计数,如果不喂狗,计到0x3F时,会复位MCU;因此WWDG free-running downcounter value设置的值必须大于0x3F;而其最大值不能超过0x7F,图中设置的就是最大值0x7F;
WWDG window value的值必须在0x3F和WWDG free-running downcounter value之间,图中设置的值时0x70,表示WWDG计时器从0x7F向下递减时,要减到0x70之下后,才能有效喂狗(即喂狗的窗窗口区间在0x3F ~ WWDG window value之间)。
- 早期中断
喂狗的窗口:PCLK1/8/4096 = 1099Hz;
(0x7F-0x3F)/ 1099 = 58ms;
(0x7F-0x70)/1099 = 14ms;
喂狗的窗口时间约为14ms~58ms。
生成keil工程,打开后,在wwdg.c中添加早期窗口看门狗中断额回调函数,只是置一个标志位:
/* USER CODE BEGIN 1 */ extern unsigned char early_wwdg_flag; void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg){ early_wwdg_flag=1; } /* USER CODE END 1 */
main.c
串口重定向以及头文件
/* USER CODE BEGIN 0 */ uint32_t count = 0; #include <stdio.h> int fputc(int ch,FILE *f) { HAL_UART_Transmit(&huart1,(uint8_t*)&ch,1,0xFFFF); return ch; } unsigned char early_wwdg_flag; /* USER CODE END 0 */
主循环
/* USER CODE BEGIN 2 */ printf("start %d\r\n",count++); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { if(early_wwdg_flag==1){ early_wwdg_flag=0; HAL_WWDG_Refresh(&hwwdg); printf("循环 %d次\r\n",count++); } /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */
运行效果
链接:https://pan.baidu.com/s/10ovIt5w7iJwxABKmtt9zeA?pwd=nmvw
提取码:nmvw
参考文章:
https://www.cnblogs.com/xiaobaibai2021/p/15716908.html