一、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
参考文章: