看门狗就是定期查看芯片内部的情况,一旦发生错误就向芯片发送重启信号,从而实现无人职守时持续工作。看门狗在程序中的中断拥有最高优先级。
工作原理:看门狗芯片与单片机的一个IO引脚相连,通过程序控制定时的往看门狗芯片发送脉冲(称为喂狗),当单片机由于其他原因导致跑飞或进入死循环,就不能执行喂狗,看门狗芯片没有接收到单片机的信号,则看门狗芯片向单片机复位引脚发送复位信号,则实现了单片机的自动复位。STM32 M4芯片集成了看门狗到内部,化身为一个计数器,当设定的计数值减法计数到0的时候,就会触发复位中断。需要定时的刷新计数值(喂狗),防止计数值到达0产生复位。
独立看门狗(IWDG):Independent Watch Dog
监测并解决软件导致的故障,当计数器达到超时值时,触发一个中断或产生系统复位。
独立看门狗由专用的低速时钟(LSI)驱动,因此在主时钟发生故障时,看门口仍然可以保持运行。
主时钟一般频率都比较高,比较容易收到外界条件的干扰,稳定性较差,低速时钟由于频率低,抗干扰能力比较强,能够保证在主时钟发生故障的情况下仍然能够运行,提高系统的稳定性。
IWDG主要特性:
1、自由运行递减计数器
2、时钟由独立的振荡器提供,
3、当递减计数器到达0x000时产生复位。
/*添加复位检测代码,反映出当前程序是否有问题,如果看门口复位太多,则需要检查程序*/
//检查当前复位是否由看门狗导致
if(RCC_GetFlagStatus(RCC_FLAG_IWDGRST) != RESET)
{
printf("iwdg reset cpu\r\n");
//清空标志位
RCC_ClearFlag();
}
else
{
//普通复位
printf("normal reset cpu\r\n");
}
//使能看门口寄存器
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
//设置看门狗的时钟,分频 32kHz/256=125Hz,就是一秒完成125次计数
IWDG_SetPrescaler(IWDG_Prescaler_256);
//设置看门狗计数值125 一秒内没有刷新计数值,就会复位一次
IWDG_SetReload(125);
//刷新独立看门狗的计数值,重新计数,就是喂狗动作
IWDG_ReloadCounter();
/* 使能独立看门狗 */
IWDG_Enable();
//建议:不要在main中喂狗,main中执行的代码比较多,难以确定喂狗的时刻。
//没有操作系统,利用定时器中断喂狗
//有操作系统,在任务中喂狗,任务相当于线程
定时器喂狗程序
void tim3_init(void)
{
//使能定时器1的时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
/* 定时器的时间的配置,中断频率为1000Hz,也就是说中断周期时间为1ms
最大的定时器时间约为6.5535s
TIM_TimeBaseStructure.TIM_Period =65535;
如果要进行2秒的定时
TIM_TimeBaseStructure.TIM_Period = (10000*2)-1;
如果要进行1秒的定时
TIM_TimeBaseStructure.TIM_Period = (10000)-1;
如果要进行100毫秒的定时
TIM_TimeBaseStructure.TIM_Period = (10000/10)-1;
*/
//配置定时器3的属性,定时的时间 = 时钟源/频率
TIM_TimeBaseStructure.TIM_Period = (10000/10)-1; //定时时间100ms
TIM_TimeBaseStructure.TIM_Prescaler =8400-1; //第一分频,设置预分频值
TIM_TimeBaseStructure.TIM_C