05:HAL-----看门狗WDT,HAL中的看门狗WDT功能介绍

马肤

温馨提示:这篇文章已超过468天没有更新,请注意相关的内容是否还可用!

摘要:本文介绍了HAL(硬件抽象层)中的看门狗WDT(看门狗定时器)功能。WDT是一种用于监控和保护嵌入式系统运行的定时器,能够检测并处理系统中的异常情况。HAL通过提供WDT的功能,帮助开发人员实现系统的稳定性和可靠性。WDT在嵌入式系统开发中扮演着重要的角色,能够及时发现并处理系统中的故障,确保系统的正常运行。

 

目录

一:看门狗

1:WDT

2:独立看门狗 (IWDG)

A:IWDG框图

B:IWDG_KR键寄存器

C:IWDG超时时间

D:HAl库的配置

3:窗口看门狗 (WWDG)

A:WWDG框图

B:WWDG工作特性

C:WWDG超时时间

D:HAL库配置

4:独立看门狗和窗口看门狗的区别

5:数据手册

二:案例

A:独立看门狗

B:窗口看门狗


一:看门狗

1:WDT

        WDG(Watchdog)看门狗------本质就是自动复位

        看门狗可以监控程序的运行状态,当程序因为设计漏洞、硬件故障、电磁干扰等原因,出现卡死或跑飞现象时,看门狗能及时复位程序,避免程序陷入长时间的罢工状态,保证系统的可靠性和安全性

        看门狗本质上是一个定时器,当指定时间范围内,程序没有执行喂狗(重置计数器--重置不是清零)操作时,看门狗硬件电路就自动产生复位信号

        STM32内置两个看门狗     

                独立看门狗(IWDG):独立工作,对时间精度要求较低     

                窗口看门狗(WWDG):要求看门狗在精确计时窗口起作用

2:独立看门狗 (IWDG)

A:IWDG框图

05:HAL-----看门狗WDT,HAL中的看门狗WDT功能介绍 第1张

                                                              结构 

        它的结构和定时器是常相似的 , 只不过是,定时器溢出,产生中断 .  而看门狗定时器溢出,直接产生复位信号(IWDG复位) .  喂狗操作,其实也就是重置这个计数器(12位 递减计数器). 这是一个递减计数器,减到0之后就复位 . 

        程序正常运行时,为了避免复位 ,  就得在这个计数器(12位 递减计数器)减到0之前 , 及时地把计数值加大点-----这个操作,就是喂狗 .   如果你程序卡死了,  没有及时加大这个计数器 ,  那减到0之后,就自动复位了

                                                        独立看门狗运行逻辑

        开始 :  A : 输入时钟,是LSI,内部低速时钟(时钟频率为40KHz)--------------- B: 时钟进入预分频器进行分频(8位) ,所以它最大只能进行256分频 ;  上面这个预分频j寄存器IWDG PR, 可以配置分频系数, 这个PR和定时器的PSC (//预分频器PSC) 是一个意思 -----------------C:时钟动递减计数器 ,  每来一个时钟,自减一个数(12位, max=2^12-1=4095) .  然后,当自减到0之后-------------D: 产生IWDG复位 ; 

        正常运行时,为了避免复位 .  我们可以提前在重装载寄存器写一值,  IWDG_ RLR,和定时器的ARR(自动重装载寄存器ARR 计数目标值)是一样的 .   那当我们预先写好值之后, 在运行过程中我们在这个键寄存器里,写一个特定数据 .  控制电路,进行喂狗          这时重装值,就会复制到当前的计数器中,  这样计数器就会回到重装值,重新自减运行了

        状态奇存器IWDG_SR : 标志电路运行的状态

05:HAL-----看门狗WDT,HAL中的看门狗WDT功能介绍 第2张

B:IWDG_KR键寄存器

        键寄存器本质上是控制寄存器,用于控制硬件电路的工作

        在可能存在干扰的情况下,一般通过在整个键寄存器写入特定值来代替控制寄存器写入一位的功能,以降低硬件电路受到干扰的概率

05:HAL-----看门狗WDT,HAL中的看门狗WDT功能介绍 第3张

上面说的喂狗操作 : 实际就是在键寄存器里面写入 0xAAAA

C:IWDG超时时间

超时时间(溢出时间) :如果超超过了自己设置的时间,没有喂狗系统就会自动复位   

复位条件:   计数器的值数到零时,就会复位

05:HAL-----看门狗WDT,HAL中的看门狗WDT功能介绍 第4张

        超时时间:TIWDG = TLSI × PR预分频系数 × (RL + 1)

        其中:TLSI = 1 / FLSI

05:HAL-----看门狗WDT,HAL中的看门狗WDT功能介绍 第5张

RL重装值-----重装载寄存器IWDG_RLR写入的值

PR预分频系数------相当于定时器的PSC (//预分频器PSC)

RL------相当于定时器的ARR(自动重装载寄存器ARR 计数目标值)是一样的

FLSI----是LSI内部低速时钟   40KHz=40 000HZ

TLSI= 1/40 000=0.000 025s = 0.025ms

                         

                                                时间的计算

以第一组为例

05:HAL-----看门狗WDT,HAL中的看门狗WDT功能介绍 第6张

05:HAL-----看门狗WDT,HAL中的看门狗WDT功能介绍 第7张

D:HAl库的配置

05:HAL-----看门狗WDT,HAL中的看门狗WDT功能介绍 第8张

05:HAL-----看门狗WDT,HAL中的看门狗WDT功能介绍 第9张

都在响应的iwdg文件里面(HAl库函数)

3:窗口看门狗 (WWDG)

A:WWDG框图

05:HAL-----看门狗WDT,HAL中的看门狗WDT功能介绍 第10张

 05:HAL-----看门狗WDT,HAL中的看门狗WDT功能介绍 第11张

         T[6:0]和w[6:0]的数字是我们自己可以设置的, 下面的0x40(64)和0x3F(63)已经固定好了。

        T[6:0]: 递减计数器(第6位做位标志位) 11 1111= 127=0x7F(最大填写的数),又因为窗口下限值为63(0x3F),所以实际可设置的范围为6到127

        W[6:0]:窗口值(看门狗配置寄存器,窗口上限值)1111 1111=225=0xff       注意窗口的值不能比计数器初始值还大

05:HAL-----看门狗WDT,HAL中的看门狗WDT功能介绍 第12张

                                                               喂狗

窗口看门狗没有重装寄存器 ,喂狗操作 : 这个,我们直接在CNT写入数据就行了 , 想写多少就写多少

                                                窗口看门狗运行逻辑

        开始 : A :这个时钟源是PCLK1(36MHz)---------B: 先经过一个预分频器进行分频 ,  这个和独立看门狗的预分频器,定时器的预分频器相同---------C: 分频之后的时钟,驱动这个计数器进行计数(6位递减计数器)...........

                                                        6位递减计数器

        从图上看,这里写了T6~T0, 总共是7个位 .  但是下面却写的是6位递减计数器---------因为这个计数器只有T5~T0, 这6位是有效的计数值.  最高位T6,这里用来当作溢出标志位:

        T6位等于1时,表示计数器没溢出

        T6位等于0时,表示计数器溢出

        不过对于硬件电路来说 ,  T6位其实也是计数器的一部分 , 只不过是T6位被单独拎出来 ,  当作标志位了而已.          EG: 当看门狗寄存器把数据从1111 111  减到了1000 000(16进制表示:0X40) .        此时,如果把T6位也当做计数器的一部分, 那计数器的值实际上才减一半. 但是,如果我们把T6位剥离出去,当作溢出标志位,  低6位,当作计数器.  那此时的状态就是,标志位为1,  计数器为00 0000,已经减到0了.   再减一次变为011 1111 ,这时最高位T6,由1变为0---溢出--产生复位信号

        结论:

        T6位看作是计数器的一部分,  那就是整个计数器,值减到0x40(1000 000)之后溢出;

        如果你把T6位当成溢出标志位,低6位,当作计数器, 那就是,低6位的计数值减到0之后溢

                                                                WDGA

        WDGA-------是窗口看门狗的激活位 ;  WDGA写入1,启用窗口看门狗

                                             喂狗最早时间窗口的实现流程

由这部分电路组成

05:HAL-----看门狗WDT,HAL中的看门狗WDT功能介绍 第13张

        需要计算一个最早界限的计数值 ,  写入到这里的W6~W0中 .  这些值,写入之后是固定不变的 .      一旦我们执行写入CR操作时(写看门狗控制寄存器) ,这个与门开关打开,  

写入CR,其实就是写入计数器,也就是喂狗.  在喂狗时,比较器开始工作  .  一旦它比较,我们当前的计数器T6:0>窗口值W6:0,   比较结果就=1 .这个1,通过或门,也可以去申请复位-------这就是喂狗最早时间窗口的实现流程

05:HAL-----看门狗WDT,HAL中的看门狗WDT功能介绍 第14张

B:WWDG工作特性

        递减计数器T[6:0]的值小于0x40时,WWDG产生复位------------T[6:0]包含T6位

        递减计数器T[6:0]在窗口W[6:0]外被重新装载时,WWDG产生复位------过早喂狗

        递减计数器T[6:0]等于0x40时可以产生早期唤醒中断(EWI),用于重装载计数器以避免WWDG复位-----在溢出的前一刻发送, 也叫做死前中断----操作比如保存重要数据、关闭危险设备等等

          过早喂狗不会产生中断,中断是递减计数器等于0X4F的时候才会产生的。所以如果要在系统发生错误的时候做出一些紧急的操作,我们需要避免过早喂狗

        定期写入WWDG_CR寄存器(喂狗)以避免WWDG复位

05:HAL-----看门狗WDT,HAL中的看门狗WDT功能介绍 第15张

C:WWDG超时时间

窗口时间(喂狗的最早时间):   

                 TWIN = TPCLK1 × 4096 × WDGTB预分频系数 × (T[5:0] - W[5:0])

TPCLK1-----1/36000 000

超时时间(计数器减到零的时间):   

                TWWDG = TPCLK1 × 4096 × WDGTB预分频系数 × (T[5:0] + 1)---T[5:0]不包含T6位

其中:

        TPCLK1 = 1 / FPCLK1

05:HAL-----看门狗WDT,HAL中的看门狗WDT功能介绍 第16张

FPCLK1---36Mkz  36000 000HZ

TPCLK1-----1/36000 000

05:HAL-----看门狗WDT,HAL中的看门狗WDT功能介绍 第17张s

6位递减计数器(CNT)--------6位的计数器,最大值是2^6-1=63

D:HAL库配置

05:HAL-----看门狗WDT,HAL中的看门狗WDT功能介绍 第18张

在WWDG的初始化函数中,初始化函数会自动调用Mspinit回调函数

05:HAL-----看门狗WDT,HAL中的看门狗WDT功能介绍 第19张

4:独立看门狗和窗口看门狗的区别

IWDG和WWDG对比

05:HAL-----看门狗WDT,HAL中的看门狗WDT功能介绍 第20张

05:HAL-----看门狗WDT,HAL中的看门狗WDT功能介绍 第21张

5:数据手册

硬件看门狗:

        如果用户在选择字节中启用了“硬件看门狗”功能,在系统上电复位后,看门狗会自动开始运行;如果在计数器计数结束前,若软件没有向键寄存器写入相应的值,则系统会产生复位。

窗口看门狗:

        启动看门狗------------在系统复位后,看门狗总是处于关闭状态,设置WWDG_CR寄存器的WDGA位能够开启看门狗,随后它不能再被关闭,除非发生复位。

        05:HAL-----看门狗WDT,HAL中的看门狗WDT功能介绍 第22张

        控制递减计数器-----------递减计数器处于自由运行状态,即使看门狗被禁止,递减计数器仍继续递减计数。当看门狗被启用时,TE位必须被设置,以防止立即产生一个复位。-------也就是我们在开启的时候 ,  一定要首次给个重装值,并且T6位给1 .  以防止开的时候,立刻就复位了

二:案例

A:独立看门狗

设置溢出时间为1S, 如果在1S内没有及时喂狗系统就会复位;

#include "stm32f1xx_hal.h"
IWDG_HandleTypeDef g_iwdg_handle;
/**
  * @brief  独立看门狗初始化
  * @param  psc :预分频器值
  * @param  rlr:重装载值          
  * @retval 无
  */
void Iwdg_Init(uint8_t psc,uint16_t rlr)
{
	g_iwdg_handle.Instance=IWDG;             /*基地址*/
	g_iwdg_handle.Init.Prescaler=psc;      /*预分频器值*/
	g_iwdg_handle.Init.Reload=rlr;				/*重装载值*/
	
	HAL_IWDG_Init(&g_iwdg_handle);
}	
/**
  * @brief  独立看门狗喂狗操作
  */
void feed_dog(void)
{
	HAL_IWDG_Refresh(&g_iwdg_handle);
}
#include "stm32f1xx_hal.h"
#include "rcc.h"
#include "led.h"
#include "delay.h"
#include "key.h"
#include "exit.h"
#include "UART.h"
#include "OLED.h"
#include "iwdg.h"
int main(void)
{
	HAL_Init();                         /* 初始化HAL库 */
  sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
  delay_init(72);                     /* 延时初始化 */
  LED_Init();                        /* LED初始化 */
	LED_Exit_Init();
	OLED_Init();
	Uart_Init(115200);
	
	
	OLED_ShowString(1, 1, "Please feed the");
	OLED_ShowString(2, 1, "in time!!!!!");
	
	Iwdg_Init(IWDG_PRESCALER_16,2500);/*设置溢出时间为为1S,所以分频系数为16,重装载值为2500*/
	while(1)
	{
	
		delay_ms(1050);
		feed_dog();
		OLED_ShowString(1, 1, "                 ");
		OLED_ShowString(2, 1, "                ");
		OLED_ShowString(1, 1, "Dog fed");
		
		
	}
	
}

重装载值的计算(rlr):

05:HAL-----看门狗WDT,HAL中的看门狗WDT功能介绍 第23张

公式在上面写啦.

B:窗口看门狗

#include "stm32f1xx_hal.h"
#include "led.h"
#include "delay.h"
/**
  * @brief  窗口看门狗初始化
  * @param  psc :预分频器值      
  * @param  coun:计数器的值    T[6:0]   
	* @param  window_val:窗口的值    W[6:0]   
  * @retval 无
  */
void wwdg_feed_dog(void);
WWDG_HandleTypeDef Wwdg_Init_handle;
void wwdg_Init(uint32_t psc,uint8_t coun,uint8_t window_val)
{
		Wwdg_Init_handle.Instance=WWDG;
		Wwdg_Init_handle.Init.Counter=coun;         /*计数器的值*/
		Wwdg_Init_handle.Init.EWIMode=WWDG_EWI_ENABLE;   /*使能中断*/
		Wwdg_Init_handle.Init.Prescaler=psc;           /*预分频器值*/
		Wwdg_Init_handle.Init.Window=window_val;
		HAL_WWDG_Init(&Wwdg_Init_handle);
}	
/*回调函数:在初始化函数中都会自调用回调函数*/
void HAL_WWDG_MspInit(WWDG_HandleTypeDef *hwwdg)
{
			__HAL_RCC_WWDG_CLK_ENABLE();
			//HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2);
			HAL_NVIC_SetPriority(WWDG_IRQn,2,0);
			HAL_NVIC_EnableIRQ(WWDG_IRQn);
}
/*中断函数*/
void WWDG_IRQHandler()
{
		HAL_WWDG_IRQHandler(&Wwdg_Init_handle);
}
/*中断处理函数,发送中断时
*HAL_WWDG_IRQHandler函数自动调用这个函数
*
*/
void  HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg)
{			
		
		HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5);	
}
/*喂狗*/
void wwdg_feed_dog(void)
{
	HAL_WWDG_Refresh(&Wwdg_Init_handle);
}
#include "stm32f1xx_hal.h"
#include "rcc.h"
#include "led.h"
#include "delay.h"
#include "OLED.h"
#include "wwdg.h"
int main(void)
{
	HAL_Init();                         /* 初始化HAL库 */
  sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
  delay_init(72);                     /* 延时初始化 */
  LED_Init();                        /* LED初始化 */
	LED_Exit_Init();
	OLED_Init();
	wwdg_Init(WWDG_PRESCALER_8,0x7f, 0x5f);
	if(__HAL_RCC_GET_FLAG(RCC_FLAG_WWDGRST)!=RESET)   /*1===>发生窗口看门狗复位*/
	{
		OLED_ShowString(1, 1,"Widnow dog Reset");
		__HAL_RCC_CLEAR_RESET_FLAGS();                 /*清除中断标志位*/
	}
	else
	{
		OLED_ShowString(1, 1,"Outside dog Re");
		OLED_ShowString(2, 1,"set!!!!");
	
	}
	
	OLED_ShowString(3, 1,"Please feed");
	OLED_ShowString(4, 1,"the dog!!!!");
	while(1)
	{
	
		delay_ms(25);
		wwdg_feed_dog();
		OLED_ShowString(3, 1,"               ");
		OLED_ShowString(4, 1,"feed dog....");
		HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_6);	
		
	}
	
}

关于时间的计算:

窗口时间(喂狗的最早时间):   

                 TWIN = TPCLK1 × 4096 × WDGTB预分频系数 × (T[5:0] - W[5:0])

TPCLK1-----1/36000 000

        就设置计数器值为7f,窗口寄存器为5f,分频数为8,然后可由前面的公式得到窗口上限时间Twwdg=4096×8×(0x7F-0x5F)/36MHz=29.12ms,

        窗口下限时间Twwdg=4096×8×(0x7F-0x3F)/36MHz=58.25ms,

        即喂狗的窗口区间为29.12~58.25ms。

05:HAL-----看门狗WDT,HAL中的看门狗WDT功能介绍 第24张

关于寄存器:

if(__HAL_RCC_GET_FLAG(RCC_FLAG_WWDGRST)!=RESET)   /*1===>发生窗口看门狗复位*/
	{
		OLED_ShowString(1, 1,"Widnow dog Reset");
		__HAL_RCC_CLEAR_RESET_FLAGS();                 /*清除中断标志位*/
	}

在stm32f1xx hal_rcc.h文件里面 

05:HAL-----看门狗WDT,HAL中的看门狗WDT功能介绍 第25张

05:HAL-----看门狗WDT,HAL中的看门狗WDT功能介绍 第26张 05:HAL-----看门狗WDT,HAL中的看门狗WDT功能介绍 第27张

代码解释:

HAL_StatusTypeDef HAL_WWDG_Init(WWDG_HandleTypeDef *hwwdg)
__weak void HAL_WWDG_MspInit(WWDG_HandleTypeDef *hwwdg)
void HAL_WWDG_IRQHandler(WWDG_HandleTypeDef *hwwdg)
HAL_StatusTypeDef HAL_WWDG_Refresh(WWDG_HandleTypeDef *hwwdg)

可以看到他们这些函数的句柄都一样,使用使用一个即可:

WWDG_HandleTypeDef Wwdg_Init_handle;

        我们在主函数中调用WWDG初始化函数(HAL_WWDG_Init)时,初始化函数里面会自动调用回调函数。在递减计数器减到0X4F时候触发中断或者在非窗口期喂狗触发中断,我们写的中断函数中调用中断函数,中断函数里面自动调用回滚函数HAL_WWDG_EarlyWakeupCallback()。

        过早喂狗不会产生中断,中断是递减计数器等于0X4F的时候才会产生的。所以如果要在系统发生错误的时候做出一些紧急的操作,我们需要避免过早喂狗


0
收藏0
文章版权声明:除非注明,否则均为VPS857原创文章,转载或复制请以超链接形式并注明出处。

相关阅读

  • 【研发日记】Matlab/Simulink自动生成代码(二)——五种选择结构实现方法,Matlab/Simulink自动生成代码的五种选择结构实现方法(二),Matlab/Simulink自动生成代码的五种选择结构实现方法详解(二)
  • 超级好用的C++实用库之跨平台实用方法,跨平台实用方法的C++实用库超好用指南,C++跨平台实用库使用指南,超好用实用方法集合,C++跨平台实用库超好用指南,方法与技巧集合
  • 【动态规划】斐波那契数列模型(C++),斐波那契数列模型(C++实现与动态规划解析),斐波那契数列模型解析与C++实现(动态规划)
  • 【C++】,string类底层的模拟实现,C++中string类的模拟底层实现探究
  • uniapp 小程序实现微信授权登录(前端和后端),Uniapp小程序实现微信授权登录全流程(前端后端全攻略),Uniapp小程序微信授权登录全流程攻略,前端后端全指南
  • Vue脚手架的安装(保姆级教程),Vue脚手架保姆级安装教程,Vue脚手架保姆级安装指南,Vue脚手架保姆级安装指南,从零开始教你如何安装Vue脚手架
  • 如何在树莓派 Raspberry Pi中本地部署一个web站点并实现无公网IP远程访问,树莓派上本地部署Web站点及无公网IP远程访问指南,树莓派部署Web站点及无公网IP远程访问指南,本地部署与远程访问实践,树莓派部署Web站点及无公网IP远程访问实践指南,树莓派部署Web站点及无公网IP远程访问实践指南,本地部署与远程访问详解,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南。
  • vue2技术栈实现AI问答机器人功能(流式与非流式两种接口方法),Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法探究,Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法详解
  • 发表评论

    快捷回复:表情:
    评论列表 (暂无评论,0人围观)

    还没有评论,来说两句吧...

    目录[+]

    取消
    微信二维码
    微信二维码
    支付宝二维码