赞
踩
窗口看门狗的本质是一个能产生系统复位信号和提前唤醒中断的6位计数器
1. 当递减计数器值从 0x40(64) 减到 0x3F(63) 时复位(即T6位跳变到0)
2. 计数器的值大于 W[6:0] 值时喂狗会复位。
1. 当递减计数器等于 0x40 时可产生提前唤醒中断 (EWI)。
在窗口期内重装载计数器的值,防止复位,也就是所谓的喂狗。
WWDG框图
超时时间计算 :
Tout 是WWDG超时时间(没喂狗)
Fwwdg 是WWDG的时钟源频率(最大36M(默认))
4096 是WWDG固定的预分频系数
2^WDGTB 是WWDG_CFR寄存器设置的预分频系数值
T[5:0] 是WWDG计数器低6位,最多63
(T[5:0]+1)就是计数次数;
剩下部分是记一次数用的时间,相乘就是超时时间(1/(Fwwdg/4096*2^WDGTB))
(这里计算的是频率,倒数才是T)
开启窗口看门狗,计数器值设置为 0X7F ,窗口值设置为 0X5F ,预分频系数为 8(WDGTB=3)。程序启动时点 亮 LED1 ,300ms 后熄灭。在提前唤醒中断服务函数进行喂狗,同时翻转 LED2 状态。
此时Tout1 = (4096*8*64)/36000(ms) 约等于58.25ms
Tout2 = (4096*8*42)/36000(ms) 约等于29.13ms
CubeMx
1.常规配置
SYS->Debug->Serial Wire
RCC->High Speed Clock(HSE)->Crystal/Ceramic Resonator
时钟树HSE、PLLCLK打开,HCLK设置成72MHz、
2.可看到时钟树的PCLK1最大也就36MHz
3.
4.打开中断
Keil
1.查看WWDG的初始化
2.通过stm32f1xx_it.c --> WWDG_IRQHandler() --> HAL_WWDG_IRQHandler() --> HAL_WWDG_EarlyWakeupCallback(),这就是提前唤醒中断的处理函数,需要在Main.c中重写:
3.编写代码
注意,这部分的代码不再是完全写在系统提示的用户代码区间,因为项目要求在启动时点亮LED1 300ms,而这句话如果写在看门狗的初始化的后面,显然会导致直接Time out复位,所以LED1点亮的代码不得不写在窗口看门狗初始化函数的前面。
但是在之后代码的编写中,还是要注意尽量把代码都写在系统提示的用户代码区间。
- void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg)
- {
- HAL_WWDG_Refresh(hwwdg); //喂狗
- HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_9);
- }
-
- int main(void)
- {
-
- MX_GPIO_Init();
-
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);
- HAL_Delay(300);
-
- MX_WWDG_Init();
-
- while (1)
- {
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);
- HAL_Delay(40);
- }
- }
实验现象:程序开始运行时,LED1亮一下,然后LED2不断闪烁,表现在代码中就是窗口看门狗不断向下计数,每当快要复位时触发提前唤醒中断,进行喂狗并翻转LED状态
对比点
|
独立看门狗
| 窗口看门狗 |
时钟源
|
独立时钟,
LSI (40KHz)
,不精确
|
PCLK1
或
PCLK3
,精
|
复位条件
|
递减计数到
0
|
窗口期外喂狗或减到
0x3F
|
中断
|
没有中断
|
计数值减到
0x40
可产生中断
|
递减计数器位数
|
12
位(最大计数范:
4096~0
)
|
7
位(最大计数范围:
127~63
)
|
应用场合
|
防止程序跑飞,死循环,死机(硬件)
|
检测程序时效,防止软件异常(软件)
|
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。