STM32F4_独立看门狗

一、独立看门狗是什么😖

 在由单片机构成的微型计算机系统中,由于单片机的工作常常会受到来自外界的电磁波干扰,造成程序的跑飞,从而陷入到死循环,程序的正常运行被打断,由单片机控制的系统无法继续正常工作,会造成整个系统陷入停滞状态,发生不可预料的后果,所以出于对单片机运行状态进行实时监测的考虑,便产生了一种专门用于监测单片机程序运行状态的模块或者芯片,俗称“看门狗”。

        STM32板载了两种嵌入式看门狗外设,具有安全性高、定时精准及使用灵活的优点。看门狗分为独立看门狗窗户看门狗均可用于检测并解决由于软件错误导致的故障本章我们着重讲解独立看门狗

二、独立看门狗 IWDG简介

 看门狗的作用就是在一定的时间内  (这段时间通过定时器去实现)  ,如果超过这段时间还没有被喂养信号(表示MCU已经挂了),便启动处理器的自动复位重启(发送复位信号)。

  •         独立看门狗由其专用的低速内部时钟LSI驱动,通过对时钟的学习,我们知道LSI低速内部时钟是专门用来驱动看门狗的,独立看门狗由内部专门的32Khz低速时钟驱动,即使主时钟发生故障,它也仍然有效。独立看门狗的时钟是一个内部RC时钟,所以并不是准确的32Khz,而是一个在15~47Khz之间的可变化的时钟。
  •         独立看门狗最适合应用于那些需要看门狗作为一个在主程序之外,能够完全独立工作,并且对时间精度要求较低的场合。
  •         硬件看门狗:如果通过器件选项位使能 “硬件看门狗” 功能,上电时将自动使能看门狗;如果在计数器计数结束前,若软件没有向关键字寄存器写入相应的值,则系统会产生复位。

三、独立看门狗的主要特性 

🍋1. 自由运行的递减计数器   用于给定一段确定的时间,如果程序运行超过这段时间,表明MCU已经挂了

🍋2. 时钟由独立RC振荡器提供(可在待机和停止模式下运行)  低速内部时钟LSI,主时钟发生故障时,LSI 仍然保持工作状态

🍋3. 当递减计数器达到0x000时产生复位(前提是看门狗已激活)    递减定时器递减到0时,复位为初始值,循环工作

四、独立看门狗功能

4.1 独立看门狗功能框图

4.2IWDG寄存器 

🍉4.2.1 关键字寄存器 IWDG_KR

关键字寄存器 IWDG_KR(Key register)32位寄存器

位31:16  保留,必须保持复位值

位15:0  KEY[15:0]:键值,只写位,读为0000h

  •         必须每隔一段时间便通过软件对这些位写入键值AAAAh,否则当计数器计数到0时,看门狗会产生复位。
  •   写入键值5555h可使能对IWDG_PR和IWDG_RLR寄存器的访问。
  •    写入键值CCCCh可启动看门狗   该寄存器的15:0位再一次强调了上述框图中的情况
  •     在关键字寄存器(IWDG_KR)中写入0xCCCC,开始启用独立看门狗;此时计数器开始从其复位值0xFFF递减计数。当计数器计数到末尾0x000时,会产生一个复位信号(IWDG_RESET)。
  • 无论何时,只要关键字寄存器IWDG_KR中被写入0xAAAA, IWDG_RLR中的值就会被重新加载到计数器中从而避免产生看门狗复位 。  
🍊4.2.2 预分频器寄存器 IWDG_PR 

预分频器寄存器 IWDG_PR(Prescaler register) 32位寄存器

位31:3  保留,必须保持复位值

位2:0 PR[2:0]:预分频器

   这些值受写访问保护。通过软件设置这些位来选择计数器时钟的预分频因子。若要更改预分频的分频系数,IWDG_SR的PVU位必须为0

000:4分频   001:8分频   010:16分频   011:32分频   100:64分频   101:128分频   110:256分频   111:256分频

注意:读取该寄存器会返回VDD电压域的预分频值。如果正在对该寄存器执行写操作,则读取的值可能不是最新的/有效的。因此,只有在IWDG_SR寄存器中的PVU位为0时,从寄存器中读取的值才有效。

🔮4.2.3 重载寄存器 IWDG_RLR

重载寄存器 IWDG_RLR(Reload register)32位寄存器

位32:12  保留,必须保持复位值

位11:0 RL[11:0]:看门狗计数器重载值

        这些值受写访问保护,每次对IWDG_KR寄存器写入值AAAAh时,这个值就会重装载到看门狗计数器中,之后便会从重装载以后的值开始递减计数若要更改重装载值,IWDG_SR中的RVU位必须为0;该寄存器用来保存重装载到计数器中的值

🔮4.2.4 状态寄存器 IWDG_SR

状态寄存器 IWDG_SR(Status register)32位寄存器

位31:2  保留,必须保持复位值

位1 RVU:看门狗计数器重装载更新

  •    可通过硬件将该位置1以指示重装载值正在更新。当在VDD电压域下完成重装载更新操作后,会通过硬件将该位复位。
  •  重载值只有在RVU位为0时才可更新。
  • 位0 PVU看门狗预分频器值更新
  •     可通过硬件将该位置1以指示预分频器值正在更新。当在VDD电压域下完成预分频器值更新操作后,会通过硬件将该位复位。
  •    重载值只有在PVU位为0时才可更新。   

五、库函数配置独立看门狗

库函数配置独立看门狗的步骤:

🍜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重装载值

通过对以上两个寄存器设置可以计算出看门狗的喂狗时间(也就是看门狗溢出时间):

Tout=((4*2^prer)*rlr)/32 

Tout:看门狗溢出时间     prer:预分频值  0~7      rlr:重装载值

单位ms       4*2^prer=称为分频因子最大值256      分母=看门狗时钟(并不固定)看使用的芯片

具体来说就是:比如通过计算得到看门狗的溢出时间是1000ms,也就是1s,只要你在1s之内,有一次写入0xAAAA到IWDG_KR,就不会导致看门狗复位。

🍜3. 重载计数器喂狗(向IWDG_KR写入0xAAAA)

IWDG_ReloadCounter(); //重载计数器的值到IWDG计数器中,避免其复位  这一步骤就是看门狗喂狗

🍜4. 启动看门狗(向IWDG_KR写入0xCCCC)

IWDG_Enable();   //使能IWDG

注意IWDG一旦启动,就不能再关闭,想要关闭,只能重启;一般不使用IWDG,就不要启动看门狗;启动看门狗以后必须间隔一段时间去喂狗,否则就会导致程序复位。

 六、实例程序

这里使用的是F4的芯片,所以看门狗的时钟为32---所以计算公式为:

分频因子=4*2^prer.但最大值只能是256!
             时间计算(大概):Tout=((4*2^prer)*rlr)/32 (ms).

IWDG.C 

#include "iwdg.h"

/*******************************************
*@函数名    : IWDG_Init
*@函数功能  :  初始化独立看门狗
*@函数参数  :  prer: 分频数:0~7(只有低3位有效!)
**			 rlr: 重装载寄存器值:低11位有效.
*@Data    2023-09-20
*@函数返回值: None
*@函数描述  :分频因子=4*2^prer.但最大值只能是256!
			 时间计算(大概):Tout=((4*2^prer)*rlr)/32 (ms).
*********************************************/
void IWDG_Init(u8 prer,u16 rlr)
{
	//启用或禁用对IWDG_PR和IWDG_RLR寄存器的写访问
	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
	//设置IWDG预调值。
	IWDG_SetPrescaler(prer);
	//重装载的值
	IWDG_SetReload(rlr);//最大4096
	//用重新加载寄存器中定义的值重新加载IWDG计数器
	//*(禁止对IWDG_PR和IWDG_RLR寄存器的写访问)。
	IWDG_ReloadCounter();
	//使能
	IWDG_Enable();	
}

//喂独立看门狗
void IWDG_Feed(void)
{   
 	IWDG_ReloadCounter();//reload										   
}

主函数调用这个,就启动了看门狗,要定期喂狗,不然程序就会复位

IWDG_Init(6,1000);      //分频数为256,重载值为1000,溢出时间为8s--重装载最大为4096

分频系数可以是以下值

@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

因为宏定义了,所以可以是以下值---同样的效果

#define IWDG_Prescaler_4            ((uint8_t)0x00)
#define IWDG_Prescaler_8            ((uint8_t)0x01)
#define IWDG_Prescaler_16           ((uint8_t)0x02)
#define IWDG_Prescaler_32           ((uint8_t)0x03)
#define IWDG_Prescaler_64           ((uint8_t)0x04)
#define IWDG_Prescaler_128          ((uint8_t)0x05)
#define IWDG_Prescaler_256          ((uint8_t)0x06)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值