目录
【看门狗简述】
【独立看门狗】

【独立看门狗框图】
喂狗是指在IWDG_RLR重装载寄存器中写值
【独立看门狗时钟】
【预分频寄存器IWDG_PR】

// 刊误:111时预分频因子为512
分频系数计算公式:
说明: prer即PR[2:0]的值,上表给出的预分频因子PSC是根据公式计算后的结果
例: PR[2:0] = 010 时,PSC = 4 × 2² = 16
【重装载寄存器IWDG_RLR】
【键寄存器IWDG_KR】

溢出时间计算公式:
计数器时钟(频率):F_IWDG / PSC
计数器周期(完成一次所需时间):PSC / F_IWDG
溢出时间(一次时间×次数):T_out = (PSC * (RLR+1)) / F_IWDG
F_IWDG即LSI,40kHz
最长时间:RLR为4095,T_out = ((256)*(4095+1)) / 40000 = 26.2144 s
【demo · IWDG_KEY_USART】
项目概述:开启独立看门狗,溢出时间为1秒,使用按键1进行喂狗
接线:KEY(按下高电平)——PA1 USART1——PA9 、PA10
溢出时间:PSC=64,RLR=624 T_out = (64*624) / (40×1000) = 1 s
在CubeMX_USART_NVIC基础上修改(增加IWDG,KEY)
初始化函数(CubeMX自动生成):
MX_IWDG_Init();
喂狗函数:
HAL_IWDG_Refresh(&hiwdg);
/* main.c */
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
MX_IWDG_Init();
HAL_UART_Receive_IT(&huart1, &buf, 1);
printf("若未喂狗则反复启动,打印该行,若程序正常运行可回显串口数据\r\n");
//HAL_Delay(1000);
while (1)
{
if(HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin) == GPIO_PIN_SET)
HAL_IWDG_Refresh(&hiwdg);
HAL_Delay(50);
if(UART1_RX_STA & 0x8000)
{
printf("收到数据:"); // 把“”中的内容打印到串口
printf("%s",UART1_RX_Buffer); // 将收到的数据发送到串口
//HAL_UART_Transmit(&huart1, UART1_RX_Buffer, UART1_RX_STA & 0x3fff, 0xffff); // 将收到的数据发送到串口
while(huart1.gState != HAL_UART_STATE_READY); // 等待发送完成
printf("\r\n");
UART1_RX_STA = 0; // 重新开始下一次接收
memset(UART1_RX_Buffer,0,sizeof(UART1_RX_Buffer)); // 清空缓冲区
}
}
}
注意:
若在程序中加入了 HAL_Delay(1000); 喂狗一定失败
因为需要在1s内进行喂狗,但是延时时间已经1s了,无法及时喂狗
实测 HAL_Delay(500); 时可喂狗成功
参考:STM32 HAL库 STM32CubeMX -- IWDG(独立看门狗)_cubemx看门狗_Dir_xr的博客-优快云博客
【标准库代码】
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "Key.h"
int main(void)
{
/*模块初始化*/
OLED_Init(); //OLED初始化
Key_Init(); //按键初始化
/*显示静态字符串*/
OLED_ShowString(1, 1, "IWDG TEST");
/*判断复位信号来源*/
if (RCC_GetFlagStatus(RCC_FLAG_IWDGRST) == SET) //如果是独立看门狗复位
{
OLED_ShowString(2, 1, "IWDGRST"); //OLED闪烁IWDGRST字符串
Delay_ms(500);
OLED_ShowString(2, 1, " ");
Delay_ms(100);
RCC_ClearFlag(); //清除标志位
}
else //否则,即为其他复位
{
OLED_ShowString(3, 1, "RST"); //OLED闪烁RST字符串
Delay_ms(500);
OLED_ShowString(3, 1, " ");
Delay_ms(100);
}
/*IWDG初始化*/
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); //独立看门狗写使能
IWDG_SetPrescaler(IWDG_Prescaler_16); //设置预分频为16
IWDG_SetReload(2499); //设置重装值为2499,独立看门狗的超时时间为1000ms
IWDG_ReloadCounter(); //重装计数器,喂狗
IWDG_Enable(); //独立看门狗使能
while (1)
{
Key_GetNum(); //调用阻塞式的按键扫描函数,模拟主循环卡死
IWDG_ReloadCounter(); //重装计数器,喂狗
OLED_ShowString(4, 1, "FEED"); //OLED闪烁FEED字符串
Delay_ms(200); //喂狗间隔为200+600=800ms
OLED_ShowString(4, 1, " ");
Delay_ms(600);
}
}