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)

image.png

1.2预分频寄存器(IDWG_PR)

该寄存器是用来设置看门狗的时钟分频系数,最低是4,最高是256,虽然是32位寄存器,我们只使用了最低的3位,其他保留
image.png

1.3计数重装载寄存器(IWDG_RLR)

该寄存器保存重装载计数器中的值,32位寄存器,我们只使用了低12位有效
image.png

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 熄灭一次。

  1. #include "iwdg.h" // 将接口驱动程序头文件包含进来
  2. //接口驱动函数定义
  3. //初始化独立看门狗
  4. //prer:分频数:0~7(只有低 3 位有效!) rlr:自动重装载值,0~0XFFF.
  5. //分频因子=4*2^prer.但最大值只能是 256!
  6. //rlr:重装载寄存器值:低 11 位有效.
  7. //时间计算(大概):Tout=((4*2^prer)*rlr)/32 (ms).
  8. void IWDG_Init(u8 prer,u16 rlr)
  9. {
  10. IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); //取消寄存器写保护
  11. IWDG_SetPrescaler(prer); //设置 IWDG 分频系数
  12. IWDG_SetReload(rlr); //设置 IWDG 装载值
  13. IWDG_ReloadCounter(); //reload
  14. IWDG_Enable(); //使能看门狗
  15. }
  16. //喂独立看门狗
  17. void IWDG_Feed(void)
  18. {
  19. IWDG_ReloadCounter();//reload
  20. }

**

  1. #include "led.h" // 将接口驱动头文件包含进来
  2. #include "key.h"
  3. #include "beep.h"
  4. #include "iwdg.h"
  5. #include "delay.h"
  6. int main(void)
  7. {
  8. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组 2
  9. delay_init(168); //初始化延时函数
  10. LED_Init(); //初始化 LED 端口
  11. KEY_Init(); //初始化按键
  12. delay_ms(100); //延时 100ms
  13. IWDG_Init(4,500); //与分频数为 64,重载值为 500,溢出时间为 1s
  14. LED0=0; //先点亮红灯
  15. LED1=0;
  16. while(1)
  17. {
  18. if(KEY_Scan(0)==WKUP_PRES)//如果 WK_UP 按下,则喂狗
  19. {
  20. IWDG_Feed();//喂狗
  21. }
  22. delay_ms(10);
  23. };
  24. }