1、看门狗是什么?
WDG(Watchdog)看门狗
看门狗可以监控程序的运行状态,当程序因为设计漏洞、硬件故障、电磁干扰等原因,出现卡死或跑飞现象时,看门狗能及时复位程序,避免程序陷入长时间的罢工状态,保证系统的可靠性和安全性
看门狗本质上是一个定时器,当指定时间范围内,程序没有执行喂狗(重置计数器)操作时,看门狗硬件电路就自动产生复位信号
STM32内置两个看门狗
独立看门狗(IWDG):独立工作,对时间精度要求较低
窗口看门狗(WWDG):要求看门狗在精确计时窗口起作用
2、 独立看门狗?
键寄存器本质上是控制寄存器,用于控制硬件电路的工作
在可能存在干扰的情况下,一般通过在整个键寄存器写入特定值来代替控制寄存器写入一位的功能,以降低硬件电路受到干扰的概率
超时时间:TIWDG = TLSI × PR预分频系数 × (RL + 1)
其中:TLSI = 1 / FLSI
3、窗口看门狗?
递减计数器T[6:0]的值小于0x40时,WWDG产生复位
递减计数器T[6:0]在窗口W[6:0]外被重新装载时,WWDG产生复位
递减计数器T[6:0]等于0x40时可以产生早期唤醒中断(EWI),用于重装载计数器以避免WWDG复位
定期写入WWDG_CR寄存器(喂狗)以避免WWDG复位
超时时间:
TWWDG = TPCLK1 × 4096 × WDGTB预分频系数 × (T[5:0] + 1)
窗口时间:
TWIN = TPCLK1 × 4096 × WDGTB预分频系数 × (T[5:0] - W[5:0])
其中:TPCLK1 = 1 / FPCLK1
窗口看门狗(WWDG):
有特定的“喂狗”时间窗口,须在此范围内操作防止复位。
用于精确时间要求的关键流程监控。
独立看门狗(IWDG):
独立运行,“喂狗”时间精度要求低。
用于一般性系统监控,防系统故障死机。
例如,在汽车电子系统中,引擎控制等关键环节用窗口看门狗,整车系统状态监测用独立看门狗。
4、使用的一个过程
独立看门狗
1、定义 IWDG_Init 函数初始化独立看门狗,包括使能寄存器写操作、设置预分频系数、设置重载值、重载计数器和使能看门狗。
2、定义 IWDG_Feed 函数进行喂狗操作。
3、在 main 函数中初始化独立看门狗,并在主循环中定期喂狗。
/*********************************************************************
@Function : 初始化独立看门狗
@Parameter : prer : 分频数:0~7(只有低3位有效!)
rlr : 重装载寄存器值:低11位有效.
@Return : N/A
@Read : 1、分频因子=4*2^prer.但最大值只能是256!
2、时间计算(大概):Tout=((4*2^prer)*rlr)/40 (ms).
**********************************************************************/
void IWDG_Init(uint8_t prer,uint16_t rlr)
{
/* 寄存器写操作 */
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); //使能对寄存器IWDG_PR和IWDG_RLR的写操作
/* 设置IWDG */
IWDG_SetPrescaler(prer); //设置IWDG预分频值:设置IWDG预分频值为64
IWDG_SetReload(rlr); //设置IWDG重装载值
IWDG_ReloadCounter(); //按照IWDG重装载寄存器的值重装载IWDG计数器
/* 使能IWDG */
IWDG_Enable(); //使能IWDG
}
/*********************************************************************
@Function : 喂独立看门狗
@Parameter : N/A
@Return : N/A
@Read : 不喂狗会自动复位系统
**********************************************************************/
void IWDG_Feed(void)
{
IWDG_ReloadCounter(); //重新加载
}
/*********************************************************************
@Function : 程序入口
@Parameter : N/A
@Return : N/A
**********************************************************************/
int main(void)
{
delay_init(); //启动滴答定时器
usart1_init(9600); //USART1初始化
SystemTinerInit(1000-1,3600-1); //系统时间初始化 定时100ms
ExpLEDInit(); // 外部LED初始化函数声明
ExpKeyInit(); //开发板按键初始化
IWDG_Init(4,625); //与分频数为64,重载值为625,溢出时间为1s
LED1 = 0;
delay_ms(800); //让人看得到灭
LED1 = 1;
delay_ms(800);
printf("初始化成功!\r\n");
while(1)
{
IWDG_Feed();//如果DK1按下,则喂狗
LED2 = 0;
delay_ms(100);
LED2 = 1;
delay_ms(100);
if(!DK1) //按下DK1按键
delay_ms(1000);
}
}
窗口看门狗
/*保存WWDG计数器的设置值,默认为最大. */
uint8_t WWDG_CNT=0x7f;
/*********************************************************************
@Function : 初始化窗口看门狗
@Parameter : tr : T[6:0],计数器值
wr : W[6:0],窗口值
fprer: 分频系数(WDGTB),仅最低2位有效
@Return : N/A
@Read : Fwwdg=PCLK1/(4096*2^fprer).
**********************************************************************/
void WWDG_Init(uint8_t tr,uint8_t wr,uint32_t fprer)
{
/* WWDG基本配置 */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); //WWDG时钟使能
WWDG_CNT=tr&WWDG_CNT; //初始化WWDG_CNT.
WWDG_SetPrescaler(fprer); //设置IWDG预分频值
WWDG_SetWindowValue(wr); //设置窗口值
/* 使能WWDG和中断配置 */
WWDG_Enable(WWDG_CNT); //使能看门狗 , 设置 counter .
WWDG_ClearFlag(); //清除提前唤醒中断标志位
WWDG_NVIC_Init(); //初始化窗口看门狗 NVIC
WWDG_EnableIT(); //开启窗口看门狗中断
}
/*********************************************************************
@Function : 重设置WWDG计数器的值
@Parameter : cnt : 计数器值
@Return : N/A
**********************************************************************/
void WWDG_Set_Counter(uint8_t cnt)
{
WWDG_Enable(cnt); //使能看门狗 , 设置 counter .
}
/*********************************************************************
@Function : 窗口看门狗中断配置
@Parameter : N/A
@Return : N/A
**********************************************************************/
void WWDG_NVIC_Init(void)
{
NVIC_InitTypeDef NVIC_InitStructure; // 定义 NVIC_InitTypeDef 结构体变量
/* 初始化 NVIC_InitTypeDef 结构体变量 */
NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn; // 设置中断通道为WWDG中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; // 设置抢占优先级为2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; // 设置子优先级为3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 使能中断通道
/* 初始化 NVIC */
NVIC_Init(&NVIC_InitStructure); //将配置好的NVIC_InitTypeDef结构体变量应用到NVIC
}
/*********************************************************************
@Function : 喂窗口看门狗
@Parameter : N/A
@Return : N/A
**********************************************************************/
void WWDG_IRQHandler(void)
{
WWDG_SetCounter(WWDG_CNT); //当禁掉此句后,窗口看门狗将产生复位
WWDG_ClearFlag(); //清除提前唤醒中断标志位
LED1=!LED1; //LED状态翻转
}
/*********************************************************************
@Function : 程序入口
@Parameter : N/A
@Return : N/A
**********************************************************************/
int main(void)
{
delay_init(); //启动滴答定时器
usart1_init(9600); //USART1初始化
SystemTinerInit(1000-1,3600-1); //系统时间初始化 定时100ms
LED_Init(); //板载LED初始化
ExpLEDInit(); //开发板LED初始化
LED2 = 0;
delay_ms(500); //让人看得到灭
WWDG_Init(0X7F,0X5F,WWDG_Prescaler_8);//计数器值为7f,窗口寄存器为5f,分频数为8
printf("初始化成功!\r\n");
while(1)
{
LED2 = 1;
delay_ms(300);
LED2 = 0;
delay_ms(300);
}
}
漫画时刻之看门狗
话说,小鹏今日的电脑又死机了。怎么操作都没有任何反应。“警告!警告!警告!…”
轻柔的“噗”声,原来是小鑫拔掉了电源
两个看门狗
独立看门狗(IWDG):独立工作,对时间精度要求较低
窗口看门狗(WWDG):要求看门狗在精确计时窗口起作用
定时得喂狗
到时间不喂狗看门狗就回帮助你插拔复位了