1.独立看门狗 (IWDG)
lsi 低速内部时钟驱动 不是很精确, 15-47Khz 一般算作32Khz
工作原理:
在键值寄存器(IWDG_KR)中写入0xcccc,开启独立看门狗
此时计数器开始从其复位值0xfff递减计数,当计数器计数到末尾0x000的时候,会产生一个复位信号
(IWGD_RESET) 无论何时,只要寄存器IWDG_KR中被写入0xaaaa,IWDG_RLR的值就会被重新加载到计数器中,从而避免看门口复位。
预分频寄存器(IWDG_RP)和重载寄存器(IWDG_RLR)的写保护:
IWDG_PR和IWDG_RLR寄存器具有写保护功能,要想修改这两个寄存器的值,首先要向IWDG_KR中写入0X5555。以不同的值写入这个寄存器或者重装载(写入0XAAAA)都会重新启动写保护。
几个寄存器
1.1键值寄存器(IWDG_KR)
1.2预分频寄存器(IDWG_PR)
该寄存器是用来设置看门狗的时钟分频系数,最低是4,最高是256,虽然是32位寄存器,我们只使用了最低的3位,其他保留
1.3计数重装载寄存器(IWDG_RLR)
该寄存器保存重装载计数器中的值,32位寄存器,我们只使用了低12位有效
2.独立看门狗启动过程
1 )取消寄存器写保护(向 IWDG_KR 写入 0X5555 )
通过这步,我们取消 IWDG_PR 和 IWDG_RLR 的写保护,使后面可以操作这两个寄存器,
设置 IWDG_PR 和 IWDG_RLR 的值。这在库函数中的实现函数是:``IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); ``
2 )设置独立看门狗的预分频系数和重装载值
设置看门狗的分频系数的函数是:void IWDG_SetPrescaler(uint8_t IWDG_Prescaler); //设置 IWDG 预分频值
设置看门狗的重装载值的函数是:void IWDG_SetReload(uint16_t Reload); //设置 IWDG 重装载值
设置好看门狗的分频系数 prer 和重装载值就可以知道看门狗的喂狗时间(也就是看门狗溢
出时间),该时间的计算方式为:Tout=((4×2^prer) ×rlr) /40
其中 Tout 为看门狗溢出时间(单位为 ms);prer 为看门狗时钟预分频值(IWDG_PR 值),
范围为 0~7;rlr 为看门狗的重装载值(IWDG_RLR 的值);
比如我们设定 prer 值为 4,rlr 值为 625,那么就可以得到 Tout=64×625/40=1000ms,这样,
看门狗的溢出时间就是 1s,只要你在一秒钟之内,有一次写入 0XAAAA 到 IWDG_KR,就不
会导致看门狗复位(当然写入多次也是可以的)。这里需要提醒大家的是,看门狗的时钟不是准
确的 40Khz,所以在喂狗的时候,最好不要太晚了,否则,有可能发生看门狗复位。
3 )重载计数值喂狗(向 IWDG_KR 写入 0XAAAA )
库函数里面重载计数值的函数是:
IWDG_ReloadCounter(); //按照 IWDG 重装载寄存器的值重装载 IWDG 计数器
通过这句,将使 STM32 重新加载 IWDG_RLR 的值到看门狗计数器里面。即实现独立看门
狗的喂狗操作。
4) 启动看门狗(向 向 IWDG_KR 写入 0XCCCC)
库函数里面启动独立看门狗的函数是:
IWDG_Enable(); //使能 IWDG
通过这句,来启动 STM32F4 的看门狗。注意 IWDG 在一旦启用,就不能再被关闭!想要
关闭,只能重启,并且重启之后不能打开 IWDG,否则问题依旧,所以在这里提醒大家,如果
不用 IWDG 的话,就不要去打开它,免得麻烦。
通过上面 4 个步骤,我们就可以启动 STM32F4 的看门狗了,使能了看门狗,在程序里面
就必须间隔一定时间喂狗,否则将导致程序复位。利用这一点,我们本章将通过一个 LED 灯来
指示程序是否重启,来验证 STM32F4 的独立看门狗。
在配置看门狗后,DS0 将常亮,如果 KEY_UP 按键按下,就喂狗,只要 KEY_UP 不停的
按,看门狗就一直不会产生复位,保持 DS0 的常亮,一旦超过看门狗定溢出时间(Tout)还没
按,那么将会导致程序重启,这将导致 DS0 熄灭一次。
#include "iwdg.h" // 将接口驱动程序头文件包含进来
//接口驱动函数定义
//初始化独立看门狗
//prer:分频数:0~7(只有低 3 位有效!) rlr:自动重装载值,0~0XFFF.
//分频因子=4*2^prer.但最大值只能是 256!
//rlr:重装载寄存器值:低 11 位有效.
//时间计算(大概):Tout=((4*2^prer)*rlr)/32 (ms).
void IWDG_Init(u8 prer,u16 rlr)
{
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); //取消寄存器写保护
IWDG_SetPrescaler(prer); //设置 IWDG 分频系数
IWDG_SetReload(rlr); //设置 IWDG 装载值
IWDG_ReloadCounter(); //reload
IWDG_Enable(); //使能看门狗
}
//喂独立看门狗
void IWDG_Feed(void)
{
IWDG_ReloadCounter();//reload
}
**
#include "led.h" // 将接口驱动头文件包含进来
#include "key.h"
#include "beep.h"
#include "iwdg.h"
#include "delay.h"
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组 2
delay_init(168); //初始化延时函数
LED_Init(); //初始化 LED 端口
KEY_Init(); //初始化按键
delay_ms(100); //延时 100ms
IWDG_Init(4,500); //与分频数为 64,重载值为 500,溢出时间为 1s
LED0=0; //先点亮红灯
LED1=0;
while(1)
{
if(KEY_Scan(0)==WKUP_PRES)//如果 WK_UP 按下,则喂狗
{
IWDG_Feed();//喂狗
}
delay_ms(10);
};
}