看门狗原理:
单片机系统在外界的干扰下会出现程序跑飞的现象导致出现死循环,看门狗电路就是为了避免这种情况的发生。
看门狗的作用:就是在一定时间内(通过定时计数器实现)没有接收喂狗信号(表示 MCU 已经挂了),便实现处理器的自动复位重启(发送复位信号) 。
独立看门狗和窗口看门狗的区别(F4版本):
1、相同点
都是为了防止CPU跑飞
2、独立看门狗
根据内部看门狗时钟频率,装载寄存器定一个时间值,比如是1000,那么独立看门狗就会按照时钟频率,从1000开始向下每隔一个时钟周期减1,如果在减到0之前,你用程序代码重新向向下计数器里面写1000(喂狗),那么定时器会重新从1000开始向下递减。如果在减到0的时候,你还没有喂狗(用新的数值覆盖计数器),就会产生复位信号。
3、窗口看门狗
根据系统时钟频率,装载一个初始值到向下计数器(假设还是1000),并且设置一个窗口值(小于装载到计数器的初始值,假设是500),窗口看门狗一般会定死窗口下线值是64。计数器从1000开始向下减,在减到500之前(1000到500间),是不允许你去喂狗的,一旦喂狗,就会产生复位信号。只有计数器值减到上限值之后(500到64),才允许你去喂狗。当计数器减到下限值(64到0之间),如果喂狗,也会产生复位信号,当减到0之后,自动产生复位信号。
所以窗口看门狗实际上就是设置一个窗口(上下限),在这个范围内,你才允许你去喂狗,只要不在这个范围之内,都会复位。
4、区别总结:
1)窗口看门狗计时时间比独立看门狗精准,窗口看门狗使用的是系统时钟源
2)窗口看门狗严格限定喂狗时间段,独立看门狗则是只要没有到时间,都能喂狗
3)独立看门狗没有中断,一般在主循环或定时器中断回调函数内喂狗
窗口看门狗有中断,在其自己的中断服务函数内喂狗
4)独立看门狗有硬件软件之分,窗口看门狗只能软件控制
5)独立看门狗只有下限,窗口看门狗有下限和上限
6)独立看门狗是12位递减的。窗口看门狗是7位递减的
7)独立看门狗是用的内部的大约32khz rc振荡器,窗口看门狗是用的系统时钟APB1 enr
版权声明:此处为CSDN博主「嵌入式Sky」的原创内容,具体的请查询该作者的原文
原文链接:https://blog.csdn.net/CSDNmianfeixiazai001/article/details/79493899
独立看门狗(IWDG)
一、资料:
这个是计算喂狗临界时间的公式(单位:ms)
最好不要接近临界值,因为IWDG并不稳定,压线喂狗容易赶不上从而被强制复位。
二、实验及其现象:
本实验,如果看门狗没有复位,开发板的DS0将常亮,如果WK_UP按键按下,就喂狗,只
要WK_UP不停的按,看门狗就一直不会产生复位,保持DS0的常亮,一旦超过看门狗定溢
出时间(Tout=1s)还没按,那么将会导致程序重启,这将导致DS0熄灭一次。
下载代码后,可以看到 DS0 不停的闪烁,证明程序在不停的复位,否则只会DS0 常亮。这时我们试试不停的按 KEY_UP 按键,可以看到 DS0 就常亮了,不会再闪烁。说明我们的实验是成功的
三、不使用cubemx:
预先封装好正点原子的system文件夹、所需要的hal库(包括stm32f4xx_hal_iwdg.c)、移植好 led文件和key文件,然后移植iwdg文件
iwdg文件一共有两个函数:
第一个初始化函数用来设置IWDG的喂狗时间并hal库初始化IWDG
第二个函数是喂狗函数,一般实际应用时将喂狗函数放在主循环内、定时器中断内来不停的喂狗
配置好延时初始化函数并且在主循环内延时100ms再初始化看门狗,让灯泡的变化可见 。
注意:这里如果没有延时的话,那么即使复位了但是灯泡还是一直亮着,看起来就没有什么变化。之所以要延时是为了观测到这个实验现象
该工程样例是放在主循环内的,如果按下按键就喂狗并延时10ms,如果按晚了就会被强制复位。具体的大家自己看吧
四、使用cubemx:
在该处配置独立看门狗和喂狗时间
记得PF9、PF10(两个灯泡)、PA0、PE4(两个按键)也配置一下
要移植好delay文件和key文件
注意:cubemx配置的iwdg.c内是没有喂狗函数的,如果需要自己添加,这里添加了
还是在主循环内进行喂狗:
窗口看门狗(WWDG)
一、资料:
这里注意:
1、必须满足计数器初值>上窗口值>下窗口值(0X40)(下窗口值是固定的)
2、看门狗超时时间公式
(超时时间Twwdg;预分频系数WDGTB;计数器T[5:0],APB1时钟频率Fpclk1),注意单位!
3、最小/大超时时间表(前提:Fpclk1=42Mhz)
计数器值T[5:0]最小=0X00/最大=0X3F,利用其来计算超时时间
4、该计数器的值从0X40变成0X3F时,产生看门狗复位
3个寄存器:
控制寄存器WWDG_CR只有低8位有效,用来设置看门狗计数器值
因为该计数器是一个递减计数器,一开始位6是1(T[6:0]=0X7F),之后逐渐减小数值
最小超时时间是在计数器值刚减小到窗口值(T[6:0]=0X40,T[5:0]=0X00,位6是1,位5-0是0)
用此时的T[5:0]=0X00来计算最小超时时间
最大超时时间是在计数器值刚好比窗口值小1(T[6:0]=T[5:0]=0X3F,位6位0,位5-0是1)
用此时的T[5:0]=0X3F来计算最大超时时间
该计数器的值从0X40变成0X3F时,产生看门狗复位
配置寄存器WWDG_CFR的W[6:0]来配置上窗口值,模板用的是0X50
必须满足计数器初值>上窗口值>下窗口值(0X40)
配置寄存器WWDG_CFR的EWI是提前唤醒中断,也就是在快要产生复位的前一段时间(T[6:0]=0X40)来提醒我们,需要进行喂狗了,否则将复位!
所以EWI用来设置中断,当计数器值减到 0X40 的时候,如果该位设置,并开启了中断,则会产生中断,我们可以在中断里面向 WWDG_CR 重新写入计数器的值,来达到喂狗的目的。
注意这里在进入中断后,必须在不大于 1 个窗口看门狗计数周期的时间(在 PCLK1 频率为 42M 且 WDGTB 为 0 的条件下, 该时间为 97.52us)内重新写 WWDG_CR,否则,看门狗将产生复位!
二、实验及其现象:
本实验用到的硬件资源有:
1) 指示灯 DS0 和 DS1
2) 窗口看门狗 其中指示灯前面介绍过了,窗口看门狗属于 STM32F4 的内部资源,只需要软件设置好即 可正常工作。
DS0指示:STM32F4的复位情况,如果被复位了就会点亮300ms
DS1指示:窗口看门狗的中断喂狗情况,每次中断喂狗翻转一次
将代码下载到 STM32F407 最小系统板后,可以看到 DS0 亮一下之后熄灭,紧接着 DS1 开始不停的闪烁。每秒钟闪烁 20 次左右,和我们预期的一致,说明我们的实验是成功的
三、不使用cubemx:
预先封装好正点原子的system文件夹、所需要的hal库(包括stm32f4xx_hal_wwdg.c)、移植好 led文件和key文件,然后移植wwdg文件
第一个函数 WWDG_Init(),主要作用是调用函数 HAL_WWDG_Init 设置 WWDG 的分频系数、窗口值和计数器初始值、提前唤醒中断。
第二个函数 HAL_WWDG_MspInit 是 WWDG 的 MSP 回调函数,该函数主要作用是使能 WWDG 时钟,以及设置 NVIC
第三个函数 WWDG_IRQHandler 也就是中断服务函数,一般情况下,在该函数内部会调用中断共用处理函数 HAL_WWDG_IRQHandler 。
第四个函数 HAL_WWDG_WakeupCallback 是提前唤醒中断回调函数,该函数内部我们主要编写了喂狗操作,以及LED1翻转。
注意到这里有个全局变量WWDG_Handler,该变量用来保存最初设置WWDG_CR 计数器的值。在后续的中断服务函数里面,就又通过 HAL_WWDG_Refresh 函数把该数值放回到 WWDG_CR 上。
主函数通过 LED0(DS0)来指示是否正在初始化。而 LED1(DS1)用来指示是否发生了中断。
我们先让 LED0 亮 300ms,然后关闭以用于判断是否有复位发生了。
在初始化 WWDG 之后, 我们回到死循环,关闭 LED1,并等待看门狗中断的触发/复位。
注意:计数器初始值设置为:0X7F,窗口值设置为0X5F,分频数为8
在编译完成之后,我们就可以下载这个程序到开发板上,观察现象。
四、使用cubemx:
cubemx配置下WWDG有点类似端口的外部中断,运行逻辑非常相似,唯一的区别是端口的外部中断没有单独的外部中断文件,初始化端口、中断优先级配置、中断使能放在了gpio.c里面。之后都是到stm32f4xx_it.c内最底下查看中断外设处理函数,里面调用hal库外设中断处理函数。然后利用里面的一个函数是弱定义,所以在其他地方重新定义回调函数。
记得PF9、PF10(两个灯泡)、PA0、PE4(两个按键)也配置一下
要移植好delay文件和key文件
注意:cubemx配置的wwdg.c内下面的回调函数是一个weak定义,这里重新编写在wwdg.c内了
这里有一点冲突,被迫修改函数形式参数,加个1就可以了
注意:
这里无法先延时300ms再初始化看门狗,LED0的变化"可见",是因为ST官方生成库强制把端口配置和看门狗配置放在了一起
当然也可以强行将gpio部分放到前面,不过再次生成还是会变成原样
当然也可以强行将灯泡引脚配置部分自己封装,不过在cubemx芯片模型上将无法观测到
所以这里干脆先让窗口看门狗进行,然后再LED0亮并延时300ms后灭掉,同样能起到观察是否复位的作用
大家都学会stm32的IWDG和WWDG了嘛,喜欢这篇博客就点个赞吧,感谢大家