STM32之独立看门狗(IWDG)和窗体看门狗(WWDG)
这个游戏以极高的自由度、出色的游戏质量与丰富的游戏内容被业界公认为开启次世代游戏的大门之作,该游戏被IGN评为年度最佳射击游戏(下载地址:http://down.ali213.net/pcgame/WatchDogs.html 有机会一定玩玩。)
二 开门见山:
下面言归正传,在工作中用的STM32需要使用看门狗技术:
看门狗通俗解释:
单片机系统在外界的干扰下会出现程序跑飞的现象导致出现死循环,看门狗电路就是为了避免这种情况的发生。看门狗的作用就是在一定时间内(通过定时计数器实现)没有接收喂狗信号(表示 MCU 已经挂了),便实现处理器的自动复位重启(发送复位信号)。
三 庐山面目:
STM32芯片一共有两个看门狗,一个是独立看门狗(IWDG),另一个是窗体看门狗(WWDG)
①先来讲讲独立看门狗:
STM32 的独立看门狗由内部专门的 40Khz 低速时钟驱动,即使主时钟发生故障,它也仍然
有效。这里需要注意独立看门狗的时钟是一个内部 RC 时钟,所以并不是准确的 40Khz,而是
在 30~60Khz 之间的一个可变化的时钟,只是我们在估算的时候,以 40Khz 的频率来计算,看
门狗对时间的要求不是很精确,所以,时钟有些偏差,都是可以接受的。
独立看门狗的配置工作代码:
1 void IWDG_Init(u8 prer,u16 rlr)2 {3 IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); //①使能对寄存器 I 写操作4 IWDG_SetPrescaler(prer); //②设置 IWDG 预分频值:设置 IWDG 预分频值5 IWDG_SetReload(rlr); //②设置 IWDG 重装载值6 IWDG_ReloadCounter(); //③按照 IWDG 重装载寄存器的值重装载 IWDG 计数器7 IWDG_Enable(); //④使能 IWDG8 }9 //喂独立看门狗10 void IWDG_Feed(void)11 {12 IWDG_ReloadCounter();//reload13 }
主逻辑区代码:
1 delay_init();//延时函数初始化2 NVIC_Configuration(); //设置 NVIC 中断分组 2:2 位抢占优先级,2 位响应优先级3 KEY_Init(); //按键初始化4 IWDG_Init(4,625); //与分频数为 64,重载值为 625,溢出时间为 1s5 while(1)6 {7 if(KEY_Scan(0)==KEY_UP)8 {9 IWDG_Feed(); //如果 按键按下,则喂狗10 }11 delay_ms(10);12 }
程序的功能就是通过按键打开看门狗,当看门狗被触发之后执行相应的操作。
②再来看看窗体看门狗
窗口看门狗(WWDG)通常被用来监测由外部干扰或不可预见的逻辑条件造成的应用程序
背离正常的运行序列而产生的软件故障。除非递减计数器的值在 T6 位(WWDG->CR 的第六位)
变成 0 前被刷新,看门狗电路在达到预置的时间周期时,会产生一个 MCU 复位。在递减计数
器达到窗口配置寄存器(WWDG->CFR)数值之前,如果 7 位的递减计数器数值(在控制寄存器中)
被刷新, 那么也将产生一个 MCU 复位。这表明递减计数器需要在一个有限的时间窗口中被刷
新。
看门狗时间计算公式:
窗口看门狗的超时公式如下:
Twwdg=(4096×2^WDGTB×(T[5:0]+1)) /Fpclk1;
其中:
Twwdg:WWDG 超时时间(单位为 ms)
Fpclk1:APB1 的时钟频率(单位为 Khz)
WDGTB:WWDG 的预分频系数
T[5:0]:窗口看门狗的计数器低 6 位
1 void WWDG_Init(u8 tr,u8 wr,u32 fprer)2 {3 RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); // WWDG 时钟使能4 WWDG_CNT=tr&WWDG_CNT; //初始化 WWDG_CNT.5 WWDG_SetPrescaler(fprer); //设置 IWDG 预分频值6 WWDG_SetWindowValue(wr); //设置窗口值7 WWDG_Enable(WWDG_CNT);8 //使能看门狗,设置 counter9 WWDG_ClearFlag(); //清除提前唤醒中断标志位10 WWDG_NVIC_Init(); //初始化窗口看门狗 NVIC11 WWDG_EnableIT(); //开启窗口看门狗中断12 }13 //重设置 WWDG 计数器的值14 void WWDG_Set_Counter(u8 cnt)15 {16 WWDG_Enable(cnt); //使能看门狗,设置 counter .17 }18 //窗口看门狗中断服务程序19 void WWDG_NVIC_Init()20 {21 NVIC_InitTypeDef NVIC_InitStructure;22 NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn; //WWDG 中断23 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //抢占 2 子优先级 3 组 224 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //抢占 2,子优先级 3,组 225 NVIC_Init(&NVIC_InitStructure); //NVIC 初始化26 }27 void WWDG_IRQHandler(void)28 {29 WWDG_SetCounter(WWDG_CNT);30 //当禁掉此句后,窗口看门狗将产生复位31 WWDG_ClearFlag();32 //清除提前唤醒中断标志位33 LED1=!LED1;34 //LED 状态翻转35 }
主逻辑区代码:
1 int main(void)2 {3 delay_init();//延时函数初始化4 NVIC_Configuration(); //设置 NVIC 中断分组 25 usart1_init();串口1初始化6 LED_Init(); //LED 初始化7 KEY_Init(); //按键初始化8 LED0=0;9 delay_ms(500);10 WWDG_Init(0X7F,0X5F,WWDG_Prescaler_8);//计数器值为 7f,窗口寄存器为 5f,//分频数为 811 while(1)12 {13 LED0=1;14 }15 }
功能:
通过 LED0(DS0)来指示是否正在初始化。而 LED1(DS1)用来指示是否发生了中
断。我们先让 LED0 亮 300ms,然后关闭以用于判断是否有复位发生了。在初始化 WWDG 之
后,我们回到死循环,关闭 LED1,并等待看门狗中断的触发/复位。
四 泛泛而谈:
再来分析一下独立看门狗(IWDG)和窗体看门狗(WWDG)的区别:
评论