独立看门狗IWDG和窗口看门狗WWDG

一、独立看门狗IWDG

1、简介

1、IWDG:即看门狗

2、本质:能产生系统复位信号的计数器。

3、特性:递减的计数器

        时钟由独立的RC振荡器提供(可在待机和停止模式下运行)

        看门狗被激活后,当递减计数器计数到0x000时产生复位

4、喂狗:在计数器计数到0之前,重装计数器的值,防止复位

2、作用 

独立看门狗是异常处理的最后手段,不可依赖,应在设计时尽可能避免异常发生。 

3、IWDG工作原理

时钟源(Src CLK)到PSC预分频器 再得到真正的工作时钟(IWDG CLK),经过CNT递减计数器的递减,判断CNT是否为0,为0则复位,在递减过程中会进行喂狗,即RELOAD重装载寄存器使CNT= RELOAD。

 

4、IWDG寄存器

低16位有效,通过键值来实现不同的功能,当键值为0xAAAA表示喂狗;当键值为0x5555表示允许访问预分频器寄存器IWDG_PR和IWDG_RLR重装载寄存器;当键值为0x5555表示启动看门狗工作;也即是上述这三个功能

以上使寄存器编写用到的,如果用HAL直接一个函数就可以了

5、IWDG溢出时间计算

6、IWDG配置步骤

7、编程实战:验证不及时喂狗,系统将复位重启

1、先复制正点原子的串口实验文件夹,进入在D:\1野火嵌入式\正点原子看门狗\实验5 串口实验\Drivers\BSP 路径新建WDG文件夹,在其下面新建俩个文件:wdg.c和wdg.h文件

2、打开工程,还需要在工程上添加如下图文件:

1、首先打开wdg.c文件,编写以下代码,运行之后导入wdg.h文件

#include "./BSP/WDG/wdg.h"


2、在wdg.c文件编写iwdg_init初始化函数和iwdg_feed喂狗函数。

#include "./BSP/WDG/wdg.h"


IWDG_HandleTypeDef g_iwdg_handle; //句柄

/*IWDG初始化函数*/

/* uint8_t和uint16_t是为了节约内存空间,也可以都设置为32位 */
/* prer:分频系数,rlr:重装载值 */
void iwdg_init(uint8_t prer, uint16_t rlr){
	
	//基地址	
	g_iwdg_handle.Instance = IWDG;
	//Init里有俩个参数,一个是分频系数,另一个是重装载值
	g_iwdg_handle.Init.Prescaler = prer;
	g_iwdg_handle.Init.Reload = rlr;
	HAL_IWDG_Init(&g_iwdg_handle);
	
}


/*喂狗函数*/
void iwdg_feed(void){
	HAL_IWDG_Refresh(&g_iwdg_handle);
}





3、在wdg.h文件进行声明

#ifndef _WDG_H
#define _WDG_H

#include "./SYSTEM/sys/sys.h"

void iwdg_init(uint8_t prer, uint16_t rlr);
void iwdg_feed(void);


#endif /*_WDG_H*/


4、在main.c文件进行实验测试看门狗,首先系统初始化-----串口打印------初始化IWDG的溢出时间大约为1s------进入循环判断是否在1s内喂狗,喂狗则打印已经喂狗,否则系统复位。

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/WDG/wdg.h"

int main(void)
{
 
	/*系统初始化*/
  HAL_Init();                             /* 初始化HAL库 */
  sys_stm32_clock_init(RCC_PLL_MUL9);     /* 设置时钟为72Mhz */
  delay_init(72);                         /* 延时初始化 */
  usart_init(115200);                     /* 串口初始化为115200 */
  // led_init(); 
	
	
	printf("您还没喂狗,请及时喂狗!!!\r\n");
	/* 预分频系数为32,重装载值为1250,溢出时间约为1s */
	iwdg_init(IWDG_PRESCALER_32,1250);   

    while (1)
    {
			delay_ms(1000);
			iwdg_feed();
			printf("已经喂狗!!!\r\n");			
    }
}

/*
*溢出时间是1秒,F1,根据那张图
*1、先选分频系数,根据最长时间大于1秒来选择(本次选择IWDG_PRESCALER_32)
*2、计算重装载值,根据公式计算(Tout=1s,psc就是上面选的32,fIWDG时钟频率为40000即40kHz)
*   计算结果为1250
*/



8、总结

二、WWDG窗口看门狗

1、简介

1、全称:WWDG,即窗口看门狗

2、本质:能产生系统复位信号提前唤醒中断的计数器

3、特性:递减的计数器

         当递减计数器值从 0x40减到0x3F时复位(即T6位跳变到0)

        计数器的值大 于W[6:0]值(窗口上限值)时喂狗会复位

        提前唤醒中断(EWI):当递减计数器等于 0x40 时可产生

4、喂狗:在窗口期内重装载计数器的值,防止复位

2、作用

1、作用:用于监测单片机程序运行时效是否精准,主要检测软件异常

2、应用:需要精准监测程序运行时间的场合

3、WWDG工作原理

注意:窗口上限值必须大于下限值

4096分频系数是固定的

WDGA:激活位

写WWDG_CR:喂狗

这个图很好分析,对比了上面的内容,太棒了,学会了

4、寄存器

5、WWDG超时时间计算

6、WWDG配置步骤

最重要介绍的时1和6    

7、编程实战:验证窗口看门狗功能

1、同独立看门狗一样,不过这次选择流水灯工程进行复制,然后步骤一样

2、首先打开wdg.c文件,编写以下代码,运行之后导入wdg.h文件

#include "./BSP/WDG/wdg.h"


3、在wdg.c文件编写:步骤1、2、3、4、5

#include "./BSP/WDG/wdg.h"
#include "./BSP/LED/led.h"

WWDG_HandleTypeDef g_wwdg_handle;


/* 窗口看门狗初始化函数 */
void wwdg_init(uint8_t tr,uint8_t wr,uint32_t fprer){
	/* 下面时初始化结构体 */
	/* 寄存器基地址 */
	g_wwdg_handle.Instance = WWDG;
	/* 结构体成员Init */
	//计数器值
	g_wwdg_handle.Init.Counter = tr;
	//窗口值
	g_wwdg_handle.Init.Window = wr;
	//预分频系数
	g_wwdg_handle.Init.Prescaler = fprer;
	//是否产生 提前唤醒中断使能
	g_wwdg_handle.Init.EWIMode = WWDG_EWI_ENABLE;
	HAL_WWDG_Init(&g_wwdg_handle);
}

/* WWDG MSP回调函数 */
void HAL_WWDG_MspInit(WWDG_HandleTypeDef *hwwdg){
	/* 设置CLOCK时钟 */
	//在stm32f1xx_hal_wwdg.c下的stm32f1xx_hal_rcc.h的文件的408行
	__HAL_RCC_WWDG_CLK_ENABLE();
	
	/* 下面是配置NVIC */
	/* 设置优先级 */
	HAL_NVIC_SetPriority(WWDG_IRQn, 2 , 3);
	/* 使能中断请求 形参WWDG_IRQn是中断号*/
	HAL_NVIC_EnableIRQ( WWDG_IRQn);
	
}


/* WWDG中端服务函数 */
//在startup_stm32f103xe.s中找,78行
void WWDG_IRQHandler(void){
	HAL_WWDG_IRQHandler(&g_wwdg_handle);
}



/* WWDG提前唤醒回调函数 进行重定义*/
void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg){
	
	//也可以在这里喂狗
	HAL_WWDG_Refresh(&g_wwdg_handle);
	/* 反转一下LED灯 , 在led.h 的55行*/
	LED1_TOGGLE();
}









4、在wdg.h文件声明初始化函数

#ifndef _WDG_H
#define _WDG_H

#include "./SYSTEM/sys/sys.h"
extern WWDG_HandleTypeDef g_wwdg_handle;
void wwdg_init(uint8_t tr,uint8_t wr,uint32_t fprer);

#endif /*_WDG_H*/


5、在main.c编写验证窗口看门狗功能

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/delay/delay.h"
#include "./SYSTEM/usart/usart.h"
#include "./BSP/LED/led.h"
#include "./BSP/WDG/wdg.h"

int main(void)
{
    HAL_Init();                                 /* 初始化HAL库 */
    sys_stm32_clock_init(RCC_PLL_MUL9);         /* 设置时钟,72M */
    delay_init(72);                             /* 初始化延时函数 */
		//串口的初始化函数,用串口打印一些数据
		usart_init(115200);                         /* 串口初始化为波特率115200 */
    led_init();                                 /* 初始化LED */
    
		if(__HAL_RCC_GET_FLAG(RCC_FLAG_WWDGRST) != RESET ){
			printf("窗口看门狗复位!!!\r\n");
			__HAL_RCC_CLEAR_RESET_FLAGS();
		}
		else{
			printf("外部复位!!!\r\n");
		}
			
		delay_ms(500);
		printf("请在窗口期喂狗\r\n\r\n");
		/* 1、窗口看门狗初始化 */
		/*    计数器值:0x7F   窗口值:0x5F  预分频系数:WWDG_PRESCALER_8   */
		wwdg_init(0x7F , 0x5F ,WWDG_PRESCALER_8);
		
	
    while(1)
    {
			delay_ms(29);
			/*喂狗函数,在stm32fxx_hal_wwdg.c 文件的343行*/
			//HAL_WWDG_Refresh(&g_wwdg_handle);
    }
}

8、IWDG和WWDG的主要区别

  • 22
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值