STM32窗口看门狗
Posted 想成为大师啊
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32窗口看门狗相关的知识,希望对你有一定的参考价值。
参考正点原子
窗口看门狗
之所以称为窗口就是因为其喂狗时间是一个有上下限的范围内(窗口),你可以通过设定相关寄存器,设定其上限时间(下限固定)。喂狗的时间不能过早也不能过晚。
而独立看门狗限制喂狗时间在0-x内,x由相关寄存器决定(X由预分频器和重装载值决定,最大值为0xFFF)。喂狗的时间不能过晚
为什么需要看门狗
- 独立看门狗:在0-重载值之间任意时间都可以喂狗
- 如果程序跑飞后又跑回正常
- 或者跑乱的程序正好执行了刷新看门狗
- 这样独立看门狗是不能检查到并复位芯片的
- 窗口看门狗:限制了喂狗时间
- 如果程序跑飞并且在限制的时间段喂狗是很困难的
- 从而保证了程序的正常运行
独立看门狗和窗口看门狗比较
独立看门狗:
- 驱动:由LSI驱动,即使主时钟发生故障它仍有效
- 适用场景:作为主程序之外能够完全独立工作
- 对时间精度要求较低
窗口看门狗:
- 驱动:由APB1时钟分频后得到时钟驱动
- 适用场景:在精确计时窗口起作用的程序
窗口看门狗工作示意图
参数
- CNT:递减计数器
- 窗口上限:寄存器设置
- 窗口下限:0x3F
- 随时间推移,计数器值递减,经过上窗口W和下窗口
- 重载值 -> 上窗口:这段时间不允许喂狗,如果喂狗会使芯片复位
- 上窗口 -> 下窗口:这段时间允许喂狗,下窗口位固定值(0x3F)
- 下窗口:进入下窗口会产生复位
T6位
- 0x3F = 00111111
- 在计数器到达0x3F之前第六位为1
- 所以当计数器到达窗口下限前T6位为1,到达窗口下限后T6位为低电平
复位
- 当计数器到达窗口下限(喂狗失败),会产生MCU复位信号,使芯片复位
窗口看门狗框图
递减计数器时钟:
- 时钟来源PCLK1
- 由于PCLK1时钟频率过高/4096
- 再经过预分频器WDGTB
- 预分频后作为递减计数器时钟
WWDG_CR寄存器:
- T7:WDGA启动位-使能窗口看门狗
- T0~6:6位递减计数器寄存器
WWDG_CFR:
- W0~6:设置窗口看门狗上窗口值
窗口看门狗工作过程总结
STM32F的窗口看门狗中有一个7位的递减计数器T[6 : 0],它会在出现下述2种情况之一时产生看门狗复位:
- 当喂狗的时候如果计数器的值大于某一设定数值W[6 : 0]时,此设定数值在WWDG_CFR寄存器定义。
- 当计数器的数值从0x40减到0x3F时(T6位跳变到0)。
如果启动了看门狗并且允许中断,当递减计数器等于0x40时产生早期唤醒中断(EWI),它可以用于喂狗以避免WWDG复位
窗口看门狗超时时间
窗口看门狗的超时公式如下:
Twwdg = (4096 X 2^WDGTB X (T[5:0]+1))/Fpclk1
其中:
- Twwdg:WWDG超时时间(单位为ms)
- Fpclk1:APB1的时钟频率(单位为Khz)
- WDGTB:WWDG的预分频系数
- T[5:0]:窗口看门狗的计数器低6位
为什么要窗口看门狗
对于一般的看门狗,程序可以在它产生复位前的任意时刻刷新看门狗,但这有一个隐患,有可能程序跑乱了又跑回到正常的地方,或跑乱的程序正好执行了刷新看门狗操作,这样的情况下一般的看门狗就检测不出来了;
如果使用窗口看门狗,程序员可以根据程序正常执行的时间设置刷新看门狗的一个时间窗口,保证不会提前刷新看门狗也不会滞后刷新看门狗,这样可以检测出程序没有按照正常的路径运行非正常地跳过了某些程序段的情况
窗口看门狗其他注意事项
- 上窗口W[6 : 0]必须大于下窗口值0x40.否则就无窗口了。
- 窗口看门狗时钟来源PCLK1(APB1总线时钟)分频后。
控制寄存器WWDG_CR
void WWDG_Enable(uint8_t Counter);//启动并设置初始值
void WWDG_SetCounter(uint8_t Counter);//喂狗
配置寄存器WWDG_CFR
void WWDG_EnableT(void);//使能提前唤醒中断
void WWDG_SetPrescaler(uint32_t WWDG_Prescaler);
void WWDG_SetWindowValue(uint8_t WindowValue);
状态寄存器WWDG_SR
FlagStatus WWDG_GetFlagStatus(void);
void WWDG_ClearFlag(void);
窗口看门狗配置过程
1.使能看门狗时钟:
Rcc_APB1PeriphClockCmd();
2.设置分频系数:
WWDG_SetPrescaler();
3.设置上窗口值:
WWDG_SetWindowValue();
4.开启提前唤醒中断并分组:
WWDG_EnableT();
NVIC_Init();
5.使能看门狗:
WWDG_Enable();
6.喂狗:
WWDG_SetCounter();
7.编写中断服务函数:
WWDG_IRQHandler();
正点原子例程
void WWDG_Init(u8 tr,u8 wr,u32 fprer)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); //WWDG时钟使能
WWDG_CNT=tr&WWDG_CNT; //初始化WWDG_CNT
WWDG_SetPrescaler(fprer);//设置IWDG预分频值
WWDG_SetWindowValue(wr);//设置窗口值
WWDG_Enable(WWDG_CNT); //使能看门狗,设置counter
WWDG_ClearFlag();//清除提前唤醒的中断标志位
WWDG_NVIC_Init();//初始化窗口看门狗 NVIC
WWDG_EnableIT(); //开启窗口看门狗中断
}
以上是关于STM32窗口看门狗的主要内容,如果未能解决你的问题,请参考以下文章