7、【STM32】独立看门狗和窗口看门狗(IWDG、WWDG)实验

前言

使用的是正点原子的探索者开发板进行学习,芯片:STM32F407ZGTx

学习说明此文档为本人的学习笔记,注重实践,关于理论部分会给出相应的学习链接。


注:本文档添加了对代码的在线调试功能,有助于大家更好理解相关寄存器和重要变量值的变化


理论学习

一、看门狗(WDG)简介

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

在启动正常运行的时候,系统不能复位,可以通过看门狗来复位单片机。

在系统跑飞(程序异常执行)的情况,系统复位,程序重新执行。

具有两个嵌入式看门狗外设,具有安全性高、定时准确及使用灵活的优点。两个看门狗外设(独立和窗口)均可用于检测并解决由软件错误导致的故障;当计数器达到给定的超时值时,触发一个中断(仅适用于窗口型看门狗)或产生系统复位。

二、独立看门狗(IWDG)

2.1 IWDG简介

        独立看门狗 (IWDG) 由其专用低速时钟 (LSI) 驱动,因此即便在主时钟发生故障时仍然保持
工作状态。 IWDG 最适合应用于那些需要看门狗作为一个在主程序之外,能够完全独立工作,并且对时间精度要求较低的场合。

2.2  IWDG特征

  • 自由运行递减计数器
  • 时钟由独立RC振荡器提供(可在待机和停止模式下运行)
  • 当递减计数器值达到0x000时产生部位(看门狗激活时)

2.3 IWDG功能

在键值寄存器(IWDG_KR)中写入0xCCCC,开始启用独立看门狗。此时计数器开始从其复位值0xFFF递减,当计数器值计数到尾值0x000时会产生一个复位信号(IWDG_RESET)。

无论何时,只要在键值寄存器IWDG_KR中写入0xAAAA(通常说的喂狗), 自动重装载寄存器IWDG_RLR的值就会重新加载到计数器,从而避免看门狗复位。

如果程序异常,就无法正常喂狗,从而系统复位。

  • 硬件看门狗
        如果通过器件选项位使能“硬件看门狗”功能,上电时将自动使能看门狗;如果在计数器计
数结束前,若软件没有 向关键字寄存器写入相应的值(喂狗) ,则系统会产生复位。
  • 寄存器访问保护
        IWDG_PR 和 IWDG_RLR 寄存器具有写访问保护。 若要修改寄存器,必须首先对 IWDG_KR
寄存器写入代码 0x5555 。而写入其他值则会破坏该序列,从而使寄存器访问保护再次生效。这意味着重装载操作(即写入 0xAAAA )也会启动写保护功能。
状态寄存器指示预分频值和递减计数器是否正在被更新。
  • 调试模式(请参考芯片手册)
注意: 看门狗功能由 V DD 电压域供电,在停止模式和待机模式下仍能工作。

2.4 IWDG相关寄存器

  •  键值寄存器(IWDG_KR): 0~15位有效(只写,读为0000h)

必须每隔一段时间通过软件对这些位写入键值AAAAh,否则当计数器计数到0时,看门狗产生复位。写入键值 5555h 可使能对 IWDG_PR IWDG_RLR 寄存器的访问;写入键值 CCCCh 可启动看门狗(选中硬件看门狗选项的情况除外)

  • 预分频寄存器(IWDG_PR):对时钟(LSI)进行分频
  • 重载寄存器(IWDG_RLR):看门狗计数器重载值

受写保护,每次对 IWDR_KR 寄存器写入值 AAAAh 时,这个值就会重装载到看门狗计数器中。之后,看门狗计数器便从该装载的值开始递减计数。超时周期由该值和时钟预分频器共同决定。

若要更改重载值, IWDG_SR 中的 RVU 位必须为 0
  • 状态寄存器(IWDG_SR):只有RVU、PVU两位有效

RVU:看门狗计数器重载值更新。可通过硬件将该位置 1 以指示重载值正在更新。当在 VDD 电压域下完成重载值更新操作后 (需要多达 5 RC 40 kHz 周期),会通过硬件将该位复位。

重载值只有在 RVU 位为 0 时才可更新。

PVU:看门狗预分频器值更新。可通过硬件将该位置 1 以指示预分频器值正在更新。当在 VDD 电压域下完成预分频器值更新操作后(需要多达 5 RC 40 kHz 周期),会通过硬件将该位复位。

预分频器值只有在 PVU 位为 0 时才可更新。

三、窗口看门狗(WWDG)

3.1 WWDG简介

         窗口看门狗 (WWDG) 时钟由 APB1 时钟经预分频后提供,通过可配置的时间窗口来检测应用程序非正常的过迟或过早的操作。 WWDG 最适合那些要求看门狗在精确计时窗口起作用的应用程序。
         之所以称为窗口就是因为其喂狗时间是一个有上下限的范围内(窗口),你可以通过设定相关寄存器,设定其上限时间(下限固定)。喂狗的时间不能过早也不能过晚。
        窗口看门狗通常被用来监测,由外部干扰或不可预见的逻辑条件造成的应用程序背离正常的 运行序列而产生的软件故障。除非递减计数器的值在 T6 位变成 0 前被刷新,看门狗电路在达到预置的时间周期时,会产生一个 MCU 复位。如果在递减计数器达到窗口寄存器值之前刷新控制寄存器中的 7 位递减计数器值,也会产生 MCU 复位。这意味着必须在限定的时间窗口内刷新计数器
         而独立看门狗限制喂狗时间在0-x内,x由相关寄存器决定。喂狗的时间不能过晚。
        对于一般的看门狗,程序可以在它产生复位前的任意时刻刷新看门狗,但这有一个隐患,有可能程序跑乱了又跑回到正常的地方,或跑乱的程序正好执行了刷新看门狗操作,这样的情况下一般的看门狗就检测不出来了;        如果使用窗口看门狗,程序员可以根据程序正常执行的时间设置刷新看门狗的一个时间窗口,保证不会提前刷新看门狗也不会滞后刷新看门狗,这样可以检测出程序没有按照正常的路径运行非正常地跳过了某些程序段的情况。

3.2  WWDG特征

  • 可编程的自由运行递减计数器
  • 复位条件

        - 当递减计数器值小于 0x40 时复位(如果看门狗已激活)

        - 在窗口之外重载递减计数器时复位(如果看门狗已激活)

  • 提前唤醒中断 (EWI) :当递减计数器等于 0x40 时触发(如果已使能且看门狗已激活)

3.3 WWDG功能

T[6:0] 就是 WWDG_CR 的低七位, W[6:0] 即是 WWDG->CFR 的低七位。 T[6:0]就是窗口看门狗的计数器,而 W[6:0](由用户定义) 则是窗口看门狗的上窗口,下窗口值是固定的( 0X40 )。 当窗口看门狗的计数器在上窗口值之外被刷新,或者低于下窗口值都会产生复位。

 STM32F的窗口看门狗中有一个7位的递减计数器T[6:0],它会在出现下述2种情况之一时产生看门狗复位:

  • 当喂狗的时候如果计数器的值大于某一设定数值W[6:0]时,此设定数值在WWDG_CFR寄存器定义。
  • 当计数器的数值从0x40减到0x3F时【T6位跳变到0】

如果启动了看门狗并且允许中断,当递减计数器等于0x40时产生早期唤醒中断(EWI),它可以用于喂狗以避免WWDG复位。

实战演练  

一、独立看门狗

1.1 设计规划

  • 实验目标

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

  • 硬件资源 
独立看门狗实验的核心是在 STM32F4 内部进行,并不需要外部电路,但是为了外部观察使用了:
1 ) 指示灯 DS0            2) KEY_UP 按键             3) 独立看门狗

1.2 程序设计

  • 配置步骤
  1. 向IWDG_KR写入0X5555(取消 IWDG_PR IWDG_RLR 的写保护,且可以设置)            预分频和重装载,看门狗喂狗时间(看门狗溢出时间),计算公式:                                       Tout = ((4x2^peer) x rlr) / 32    Tout为看门狗溢出时间(ms); prer为看门狗时钟预分频值(IWDG_PR值,范围0~7);rlr为看门狗的重装载值(IWDG_RLR的值)                             如:Tout = ((4x2^4) x 500/32 = 64 x 500 /32 = 1000ms                                                                 (由于时钟不准,所以喂狗时间不能太晚)                           
  2. IWDG_KR 写入 0XAAAA(喂狗)
  3. IWDG_KR 写入 0XCCCC(启动看门狗)                                                                              一旦启动就不能再关闭,只有重启时才会关闭,重启后不会自动打开IWDG,慎用。
  • IWDG配置

iwdg.h

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

void IWDG_Init(u8 per,u16 rlr);
void IWDG_Feed(void);
#endif

iwdg.c

#include "iwdg.h"

//IWDG->PR[2:0]=000:111     2^prer   prer=(0~7)   
//IWDG->RLR[11:0]=0X000:0XFFF 	 rlr=(0~4095)      
//OUT TIME£ºTout=((4*2^prer)*rlr)/32   ms
void IWDG_Init(u8 prer,u16 rlr)
{
	IWDG->KR = 0X5555;      //openen : IWDG->PR;IWDG->RLR
	IWDG->PR = prer;
	IWDG->RLR = rlr;
	IWDG->KR = 0XAAAA;      //reload
	IWDG->KR = 0XCCCC;      //IWDGen
}

void IWDG_Feed(void)
{
	IWDG->KR = 0XAAAA;
}
  • 主函数text.c
#include "led.h"  
#include "key.h" 
#include "iwdg.h"
  
int main(void)
{  
	Stm32_Clock_Init(336,8,2,7);
	delay_init(168);		    
	LED_Init();		  		//??
	KEY_Init();		  		//??
 	delay_ms(100);			//??
	IWDG_Init(4,500);    	//??  
	LED0=0;				 	//??
	while(1)
	{ 
		if(KEY_Scan(0)==WKUP_PRES)//??WK_UP??,???
		{
			IWDG_Feed();//??
		}
		delay_ms(10);
	};
}

1.3 在线调试

查看IWDG定时器,可以看到KE无论向里面写什么数,读出都是0。而PR和RLR里面也有相关值

1.4 上板验证

编译后无错误下载到开发板中,会发现DS0没隔1s进行闪烁(不复位常亮,复位灭),如果按击WK_UP按键,则不会复位,DS0就会一直亮。

二、窗口看门狗

1.1 设计规划

  • 实验目标
通过 DS0 来指示 STM32F4 是否被复位了,如果被复位了就会点亮 300ms DS1 用来指
示中断喂狗,每次中断喂狗翻转一次。
  • 硬件资源 
窗口看门狗实验的核心是在 STM32F4 内部进行,并不需要外部电路,但是为了外部观察使用了:
1 ) 指示灯 DS0 、DS1           2) KEY_UP 按键             3) 独立看门狗

1.2 程序设计

  • 配置步骤
  1. 使能WWDG时钟  :挂在PCK1时钟,需要先使能时钟。
  2. 设置WWDG_CFR、WWDG_CR两个寄存器:包括使能窗口看门狗、开启中断、设置计数器的初始值、设置窗口值并设置分频数 WDGTB 等。
  3. 开启WWDG中断并分组
  4. 编写中断服务函数:喂狗
  • WWDG配置

wwdg.h

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

void WWDG_Init(u8 tr, u8 wr , u8 fprer);
void WWDG_Set_Counter(u8 cnt) ;          //喂狗

#endif

wwdg.c

#include "wwdg.h"
#include "sys.h"	
#include "led.h"

u8 WWDG_CNT = 0X7F;       //±£´æWWDG¼ÆÊýÆ÷µÄÉèÖÃÖµ£¬Ä¬ÈÏΪ×î´ó
//tr :T[6:0] ,counter
//wr :w[6:0] ,´°¿ÚÖµ
//fprer£º·ÖƵϵÊý
//Fwwdg=PCLK1/(4096*2^fprer)      //Ò»°ãPCLK1 = 42MHz
void WWDG_Init(u8 tr, u8 wr , u8 fprer)	
{
	RCC->APB1ENR|=1<<11; //?? wwdg ??
	WWDG_CNT = tr & WWDG_CNT;//??? WWDG_CNT. 
	WWDG->CFR|=fprer<<7; //PCLK1/4096 ?? 2^fprer 
	WWDG->CFR&=0XFF80; 
	WWDG->CFR|=wr; //????? 
	WWDG->CR|=WWDG_CNT;//??????
	WWDG->CR|=1<<7; //????? 
	
//	MY_NVIC_Init(2,3,WWDG_IRQn,2);
	SCB->AIRCR |= 0X05FA0000 | 0X500;
	NVIC->IP[0] |= 0XF0;
	NVIC->ISER[0] |= 1<<0;
	
	WWDG->SR=0X00; //»½ÐÑÖжϱêÖ¾
	WWDG->CFR|=1<<9; //ʹÄÜ»½ÐÑÖжÏ
}

void WWDG_Set_Counter(u8 cnt) 
{ 
	WWDG->CR =(cnt & 0x7F);

void WWDG_IRQHandler(void) 
{ 
	WWDG_Set_Counter(WWDG_CNT);
	WWDG->SR=0X00;
	LED1=!LED1; 
}
  • 主函数text.c
#include "key.h" 
#include "wwdg.h"
  
int main(void)
{  
 	Stm32_Clock_Init(336,8,2,7);
	delay_init(168);		    
	LED_Init();		  		
//	KEY_Init();		  			
//	IWDG_Init(4,500);    	 
	LED0=0;	
 	delay_ms(300);	
	WWDG_Init(0X7F,0X5F,3);   
	while(1)
	{ 
//		if(KEY_Scan(0)==WKUP_PRES)//??WK_UP??,???
//		{
//			IWDG_Feed();//??
//		}
//		delay_ms(10);
		LED0=1;    
	};
}

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

追逐者-桥

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

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

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

打赏作者

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

抵扣说明:

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

余额充值