IWDG和WWDG分析

来源:互联网 发布:验证码注册软件 编辑:程序博客网 时间:2024/05/18 02:15

关于本博文的介绍:
1. 基于STM32F103ZET芯片和3.5V标准库
2. 分开介绍两种模式:独立看门狗IWDG和窗口看门狗WWDG
3.从寄存器,介绍到对应的库函数;

一 什么是看门狗?
单片机系统在正常执行程序时,当收到外界各种物理干扰或其他原因出现程序跑飞或者陷入死循环的现象,而使得正常的程序无法正常运行,导致MCU挂掉,看门狗就是为了解决这么个问题而出现的;

二 工作原理
在一定时间内(时间由看门狗定时计数器决定)没有接收到喂狗信号(表示MCU挂了),便实现处理器自动复位重启(发出复位信号);
* IWDG和WWDG的时钟源 *
这里写图片描述
从图中可以看出:
1.独立看门狗IWDG有自己独立的时钟源——LSI
2. 窗口看门狗WWDG的时钟源——PCLK1
由此图可以看出:在编程时,IWDG不需要使能时钟源,而WWDG需要;所以IWDG的操作会比较简单一些;

独立看门狗定时器IWDG

一 相关寄存器以及功能
(1)键值寄存器IWDG_KR
这里写图片描述
功能和使用方法:
1. 当[15:0]位被写入0xCCCC时,使能,此时寄存器从其0xFFF开始递减计数,当递减到0x0000时,会产生一个复位信号(IWDG_RESET)
2. 当[15 : 0]位被写入0xAAAA时,IWDG_RLR寄存器中的值将会被重新加载到计数器中(这就是喂狗的过程),就是通过这个功能,从而避免产生MCU复位;
3. 当寄存器被写入0x5555时,可以访问IWDG_PR和IWDG_RLR寄存器;(这里要注意了,这个重要,因为如果IWDG_PR和IWDG_RLR不能被写入数据,也就是相当于无法给IWDG预分频和重载值)

(2)预分频寄存器IWDG_PR
这里写图片描述
功能和使用:
对照着对[2:0]位的介绍选择分频因子;

(3)重载寄存器IWDG_RLR
这里写图片描述
功能和使用方法:看方框中吧;

(4)状态寄存器IWDG_SR
这里写图片描述
功能和使用方法:看方框中吧;

二 编程步骤
1. 取消寄存器写保护(也即是先IWDG_KR中写入0x5555)
目的:取消PR和RLR寄存器写保护,从而可以操作这两个寄存器
库函数:
void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess);
2. 设置预分频系数和重装载值
库函数:
void IWDG_SetPrescaler(uint8_t IWDG_Prescaler);
void IWDG_SetReload(uint16_t Reload);
这里要明白一个重要的概念:
Tout = ((4*2^prer) * rlr)/40;

 Tout:要设置的溢出时间,也就是多久初始化一次MCU,**单位是ms** prer :分频系数 rlr    :重载值; 比如:prer = 4,rlr = 625时,Tout = 1000ms
  1. 重载计数值喂狗(向IWDG_KR写入0xAAAA)
    库函数:
    void IWDG_ReloadCounter(void);

  2. 启动看门狗(向IWDG_KR 写入0xCCCC)
    库函数:
    void IWDG_Enable(void);

自此,整个程序就完成了;比较简单;

窗口看门狗WWDG

“窗口”的原因:
因为喂狗的时间有一个时间上的限制,必须在一定时间范围内(窗口);这个时间范围(窗口)上限是相关寄存器配置;下限时间是0x40;在这段时间内要完成喂狗,否则将会发生MCU复位;

一 WWDG发出复位信号的条件
1. 计数器的数值从0x40减到0x3F时候;
2. 喂狗的时候,计数器的值大于WWDG_CFG寄存器设置的数值;

二 WWDG和IWDG的区别
当MCU受到外界干扰或者内部干扰时候,导致程序出现跑飞或者死循环现象的时候,有一种情况是:程序在死循环的时候同时执行了喂狗程序,这就尴尬了,看门狗就无法起到了作用;
如果使用窗口看门狗,程序员可以根据程序执行的时间设置刷新看门狗的一个时间窗口,保证不会提前刷新看门狗或滞后刷新看门狗,这样可以检测出程序有没有正常的执行程序;

三 相关寄存器功能
先总结一下:
控制寄存器——WWDG_CR——使能WWDG,WWDG倒计数计时器;
配置寄存器——WWDG_CFG——设置唤醒中断标志位,设置分频因子,设置上窗口的值;
状态寄存器——WWDG_SR——唤醒中断位中断标志;

  1. 控制寄存器WWDG_CR
    这里写图片描述
    功能和使用:
    [7]:WWDG功能的开关位;
    [6:0] : 1. 这7位的值为要递减的值;
    2. 喂狗就是要喂这7位的值;
    3. 最大值0x7F,最小值是0x40;

2.配置寄存器WWDG_CFG
这里写图片描述
[9] : EWI提前唤醒中断,说白了此位置1会开启WWDG中断,调用相应中断相应函数;
[8:7]:时候最设置分频因子;
[6:0]:窗口值;

3.状态寄存器WWDG_SR
这里写图片描述
重点来了:当EWIF位被置1,程序将不能进入中断函数;对这个位的理解将影响到

四 窗口看门狗WWDG超时公式:
Twwdg = (4096*2^WDGTB *(T[5:0]+1))/Fpclk1;

Twwdg : WWDG超时时间(单位ms)
Fplck1:APB1的时钟频率(单位KHz) (pclk1时钟线上的最高频率为36MHz)
WDGTB:WWDG预分频系数
T[5:0]:窗口看门狗计数器低6位;

这里写图片描述

编程思路
这里写图片描述

五 编程步骤

一定要切记这个步骤,不然因为对EWIF位的不理解导致错误

(1) 开启WWDG时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);

(2)设置窗口值和分频系数值(配置WWDG_CFG)
void WWDG_SetPrescaler(uint32_t WWDG_Prescaler);//设置分频因子
void WWDG_SetWindowValue(uint8_t WindowValue);//设置窗口值
(3)使能WWDG,并加载初值
void WWDG_Enable(uint8_t Counter);
这里需要特别注意:如果说Counter的值为0x7F(MAX),会使得WWDG_SR寄存器中的EWIF位(提醒中断标志位)。
(4)清除提醒中断标志位EWIF
void WWDG_ClearFlag(void); //WWDG_SR的EWIF清零,如果不清零会使得程序无法进入到WWDG中断函数;
(5)开启WWDG中断
void WWDG_EnableIT(void); //使能之前要配置好NVIC;