STM32—独立看门狗(IWDG)

本文详细介绍了STM32的独立看门狗IWDG的工作原理,包括计数器、重装载寄存器和键寄存器的使用,以及如何通过库函数设置超时时间和喂狗操作。通过实际代码展示了如何配置和使用IWDG进行程序故障检测和重启管理。
摘要由CSDN通过智能技术生成

STM32—独立看门狗(IWDG)



独立看门狗(IWDG)

大家想要了解窗口看门狗(WWDG)的也可以去看我的另一篇文章——》 窗口看门狗(WWDG)

IWDG 简介

STM32 有两个看门狗,一个是独立看门狗另外一个是窗口看门狗,独立看门狗号称宠物狗,窗
口看门狗号称警犬 。独立看门狗用通俗一点的话来解释就是一个 12 位的递减计数器,当计数器的值从某个值一直减到 0 的时候,系统就会产生一个复位信号,即 IWDG_RESET。**如果在计数没减到 0 之前,刷新了计数器的值的话,那么就不会产生复位信号,这个动作就是我们经常说的喂狗。**看门狗功能由 VDD 电压域供电,在停止模式和待机模式下仍能工作。

IWDG 功能框图剖析

在这里插入图片描述

独立看门狗比较简单,当然它的安全性没有窗口看门狗高。下面就介绍一下这两个狗狗。

独立看门狗时钟

独立看门狗是由专门的低速总线进行驱动,即LSI总线时钟频率40KHz),它可以在主时钟故障的情况下仍然可以工作(或许这就是把这只狗成为独立看门狗的原因吧)。独立看门狗适合应用于需要看门狗作为一个在主程序之外 能够完全独立工作,并且对时间精度要求低的场合。

计数器

独立看门狗的计数器是一个 12 位的递减计数器,最大值为 0XFFF,当计数器减到 0 时,会产生
一个复位信号:IWDG_RESET,让程序重新启动运行,如果在计数器减到 0 之前刷新了计数器的
值的话,就不会产生复位信号,重新刷新计数器值的这个动作我们俗称喂狗。

重装载寄存器

重装载寄存器是一个 12 位的寄存器,里面装着要刷新到计数器的值,这个值的大小决定着独立看门狗的溢出时间。超时时间 Tout = (4*2^prv) / 40 * rlv (s) , prv 是预分频器寄存器的值, rlv 是重装载寄存器的值 。

键寄存器

在键值寄存器(IWDG_KR)中写入0xCCCC,开始启用独立看门狗。此时计数器开始从其复位值0xFFF递减,当计数器值计数到尾值0x000时会产生一个复位信号(IWDG_RESET)。无论何时,只要在键值寄存器IWDG_KR中写入0xAAAA(通常说的喂狗,但是0XAAAA并不是装入计数器中的值,真正装入计数器中的值是我们根据分频系数和我们需要的超时时间来计算好的), 自动重装载寄存器IWDG_RLR的值就会重新加载到计数器,从而避免看门狗复位。如果程序异常,就无法正常喂狗,从而系统复位。

在这里插入图片描述

通过写往键寄存器写 0XCCC 来启动看门狗是属于软件启动的方式,一旦独立看门狗启动,它就
关不掉,只有复位才能关掉。

怎么用 IWDG

独立看门狗一般用来检测和解决由程序引起的故障,比如一个程序正常运行的时间是 50ms,在
运行完这个段程序之后紧接着进行喂狗,我们设置独立看门狗的定时溢出时间为 60ms,比我们
需要监控的程序 50ms 多一点,如果超过 60ms 还没有喂狗,那就说明我们监控的程序出故障了,
跑飞了,那么就会产生系统复位,让程序重新运行。

独立看门狗所用到的库函数

下面是独立看门狗所用到的库函数

void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess);//取消写保护:0x5555使能
void IWDG_SetPrescaler(uint8_t IWDG_Prescaler);//设置预分频系数:写PR
void IWDG_SetReload(uint16_t Reload);//设置重装载值:写RLR
void IWDG_ReloadCounter(void);//喂狗:写0xAAAA到KR
void IWDG_Enable(void);//使能看门狗:写0xCCCC到KR
FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG);//状态:重装载/预分频 更新

独立看门狗操作步骤

由于预分频寄存器和重装载寄存器具有写保护,所以我们在设置这两个寄存器的值的时候,需要先取消写保护。

1) 取消寄存器写保护(向 IWDG_KR 写入 0X5555)

​ 这个函数非常简单, 顾名思义就是开启/取消写保护,也就是使能/失能写权限。

 void IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);//开启/取消写保护

2) 设置独立看门狗的预分频系数和重装载值
设置好看门狗的分频系数 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,所以在喂狗的时候,最好不要太晚了,否则,有可能发生看门狗复位。

 void IWDG_SetPrescaler(uint8_t IWDG_Prescaler); //设置 IWDG 预分频值
 void IWDG_SetReload(uint16_t Reload); //设置 IWDG 重装载值

3) 重载计数值喂狗(向 IWDG_KR 写入 0XAAAA)
库函数里面重载计数值的函数是:

void IWDG_ReloadCounter(); //按照 IWDG 重装载寄存器的值重装载 IWDG 计数器

通过这句,将使 STM32 重新加载 IWDG_RLR 的值到看门狗计数器里面。 即实现独立看门
狗的喂狗操作。

4) 启动看门狗(向 IWDG_KR 写入 0XCCCC)

库函数里面启动独立看门狗的函数是:

void IWDG_Enable(); //使能 IWDG

通过这句,来启动 STM32 的看门狗。 注意 IWDG 在一旦启用,就不能再被关闭!想要关闭,只能重启,并且重启之后不能打开 IWDG,否则问题依旧,所以在这里提醒大家,如果不用 IWDG 的话,就不要去打开它,免得麻烦。通过上面 4 个步骤,我们就可以启动 STM32 的看门狗了,使能了看门狗,在程序里面就必须间隔一定时间喂狗,否则将导致程序复位。利用这一点,我们将通过一个 LED 灯来指示程序是否重启,来验证 STM32 的独立看门狗。

相关代码如下

wdg.c

#include "wdg.h"
//初始化独立看门狗
//prer:分频数: 0~7  (只有低3位有效!)
//分频因子=4*2^prer.但最大值只能是256!
//rlr:重装载寄存器值: 0~2047 (低11位有效!)
//时间计算(大概):Tout=((4*2^prer)*rlr)/40 (ms).
void IWDG_Init(u8 prer,u16 rlr) 
{	
 	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);  //使能对寄存器IWDG_PR和IWDG_RLR的写操作
	
    
    /*
    @arg IWDG_Prescaler_4: IWDG prescaler set to 4
    @arg IWDG_Prescaler_8: IWDG prescaler set to 8
    @arg IWDG_Prescaler_16: IWDG prescaler set to 16
    @arg IWDG_Prescaler_32: IWDG prescaler set to 32
    @arg IWDG_Prescaler_64: IWDG prescaler set to 64
    @arg IWDG_Prescaler_128: IWDG prescaler set to 128
    @arg IWDG_Prescaler_256: IWDG prescaler set to 256
    */
	IWDG_SetPrescaler(prer);  //设置IWDG预分频值:设置IWDG预分频值为64
	
	IWDG_SetReload(rlr);  //设置IWDG重装载值
	
	IWDG_ReloadCounter();  //按照IWDG重装载寄存器的值重装载IWDG计数器
	
	IWDG_Enable();  //使能IWDG
}
//喂独立看门狗
void IWDG_Feed(void)
{   
 	IWDG_ReloadCounter();//喂狗									   
}

wdg.h

#ifndef __WDG_H
#define __WDG_H
#include "sys.h"

void IWDG_Init(u8 prer,u16 rlr);
void IWDG_Feed(void);

#endif

main.c

在配置看门狗后, LED0 将常亮,如果 WK_UP 按键按下,就喂狗,只要 WK_UP 不停的按,
看门狗就一直不会产生复位,保持 LED0 的常亮,一旦超过看门狗定溢出时间(Tout)还没按,
那么将会导致程序重启,这将导致 LED0 熄灭一次。

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include "wdg.h"

 int main(void)
 {		
	delay_init();	    	 //延时函数初始化	  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 	 //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
	uart_init(115200);	 //串口初始化为115200
 	LED_Init();		  	 //初始化与LED连接的硬件接口
	KEY_Init();          //按键初始化	 
	delay_ms(500);   	 //让人看得到灭
	IWDG_Init(4,625);    //与分频数为64,重载值为625,溢出时间为1s	   
	LED0=0;				 //点亮LED0
	while(1)
	{
		if(KEY_Scan(0)==WKUP_PRES)
		{
			IWDG_Feed();//如果WK_UP按下,则喂狗
		}
		delay_ms(10);
	};	 
}


给那些看完的朋友,奖励一个 赤赤博客-后端+前端,觉得不错的话可以推荐给身边的朋友哟!
在这里插入图片描述

  • 1
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安赫'

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值