独立看门狗&窗口看门狗

WDG (看门狗 Watchdog)

  1. 什么是看门狗?
    ①看门狗可以监控程序的运行状态,当程序因为设计漏洞、硬件故障、电磁干扰等原因,出现卡死或跑飞现象时,看门狗能及时复位程序,避免程序陷入长时间的罢工状态,保证系统的可靠性和安全性.
    ②看门狗本质上是一个定时器,当指定时间范围内,程序没有执行喂狗(重置计数器)操作时,看门狗硬件电路就自动产生复位信号.
    ③STM32内置两个看门狗
    独立看门狗(IWDG):独立工作,对时间精度要求较低.
    窗口看门狗(WWDG):要求看门狗在精确计时窗口起作用.

  2. IWDG(独立看门狗)

  • 框图:
    在这里插入图片描述

①独立看门狗的时钟信号来源是LSI(内部低速时钟),只有40kHZ的频率.
②IWDG由主电源VDD直接供电,即使是在停机和待机模式下也能正常工作.

  • IWDG键寄存器
    IWDG寄存器实质上是控制寄存器,用来控制电路的运行,IWDG是程序卡死复位的一道有利屏障,所以要保证其各项指令不被其他信号干扰,所以写入键寄存器的值很有特点,如图:
    在这里插入图片描述
    如:0x5555的二进制值是:0101 0101 0101 0101;0xAAAA的二进制值是:1010 1010 1010 1010,这种0和1交叉出现的二进制值有效防止了因信号干扰而造成某一位由0变1或由1变0.

-IWDG超时时间
计算公式如下:

IWDG中的分频系数较多,有4 8 16 32 64 128 256 这7中分频系数可选,各分频系数对应的最短响应时间和最长响应时间如图:
在这里插入图片描述
具体需要哪种分频系数要根据自己设置的响应时间来查找.

  1. WWDG(窗口看门狗)
  • 框图:
    在这里插入图片描述

  • WWDG超时时间
    计算公式:
    在这里插入图片描述
    WWDG的有1 2 4 8四种分频,各分频系数对应的最短响应时间和最长响应时间如图:
    在这里插入图片描述

  • WWDG工作特性
    ①递减计数器T[6:0]的值小于0x40时,WWDG产生复位.
    ②递减计数器T[6:0]在窗口W[6:0]外被重新装载时,WWDG产生复位.
    ③递减计数器T[6:0]等于0x40时可以产生早期唤醒中断(EWI),用于重装载计数器以避免WWDG复位.
    ④定期写入WWDG_CR寄存器(喂狗)以避免WWDG复位.1
    ⑤当把T0~ T5看作一个计数器体系,把T6单拎出来看作另一个体系时:

WWDG的T0~T5是6位的计数器,T6是溢出标志位,当T6位为1时,表示没有溢出,为0时,表示溢出.
例如:当给T6~T0值为:1111 111时,每来一个脉冲信号,值就减1,当减到1000 000时(十六进制为0x40),只剩下T6位位1,其余为全为0,再来一个脉冲信号(值再减去1),T6的1就会变为0,这就产生了溢出标志位.

⑥时钟信号来源于APB1,36MHZ.
⑦配置寄存器W0~W6用来设置WWDG的最早界限的计数值.
当看门狗控制寄存器(WWDG_CR)的值大于看门狗配置寄存器(WWDG_CFR)的值,此时表示喂狗太早,程序复位.当看门狗控制寄存器(WWDG_CR)的值小于看门狗配置寄存器(WWDG_CFR)的值,看门狗控制寄存器(WWDG_CR)的值自减到0,此时表示喂狗太晚,程序复位.所以在WWDG_CFR的值和WWDG_CR的自减为0的值之间形成了一个窗口值,只有WWDG在此窗口值之间运行时才不会使系统复位.

-WWDG运行流程图:
0x3F是看门狗控制寄存器(WWDG_CR)溢出计数器为0时,即T6位为0,其他位全为1时.

独立看门狗&窗口看门狗

独立看门狗(IWDG)

  • 接线图如下:
    在这里插入图片描述
  • 本工程只涉及main.c文件
    main.c代码:
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Key.h"

int main(void)
{
	/*模块初始化*/
	OLED_Init();	

	OLED_ShowString(1,1,"IWDG TEST");
	
	if(RCC_GetFlagStatus(RCC_FLAG_IWDGRST) == SET)
	{
		OLED_ShowString(2,1,"IWDGRST");
		Delay_ms(500);
		OLED_ShowString(2,1,"       ");
		Delay_ms(100);
		
		RCC_ClearFlag();
	}
	else
	{
		OLED_ShowString(3,1,"RST");
		Delay_ms(500);
		OLED_ShowString(3,1,"   ");
		Delay_ms(100);
	}
	
	//解除IWDG的写保护
	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
	//配置超时时间位1000ms,使用的系统时钟LSI的频率位40khz,默认开启
	//配置分频系数
	IWDG_SetPrescaler(IWDG_Prescaler_16);
	//配置重装值
	IWDG_SetReload(2499);
	//运行前先喂狗一次,保证周期完整
	IWDG_ReloadCounter();
	IWDG_Enable();
	
	while (1)
	{
		//按住按键不放,就会阻塞程序
		Key_GetNum();
		IWDG_ReloadCounter();
		
		OLED_ShowString(4,1,"FEED");
		Delay_ms(600);
		OLED_ShowString(4,1,"    ");
		Delay_ms(200);
	}
}

值得注意的是:
①IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);解除IWDG的写保护后,在执行喂狗操作​ (IWDG_ReloadCounter())或向键寄存器(IWDG_KR)写入除0x5555之外的任何其他值写保护会自动生效.
②按键按住不放,就会阻塞程序.
③运行时间超过IWDG的设置时间,IWDG就会复位,程序代码从头执行.

  • IWDG程序执行流程图:

窗口看门狗(WWDG)

  • 接线图如下:
    在这里插入图片描述
  • 本工程只涉及main.c文件
    main.c代码:
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Key.h"

int main(void)
{
	/*模块初始化*/
	OLED_Init();	

	OLED_ShowString(1,1,"WWDG TEST");
	
	if(RCC_GetFlagStatus(RCC_FLAG_WWDGRST) == SET)
	{
		OLED_ShowString(2,1,"WWDGRST");
		Delay_ms(500);
		OLED_ShowString(2,1,"       ");
		Delay_ms(100);
		
		RCC_ClearFlag();
	}
	else
	{
		OLED_ShowString(3,1,"RST");
		Delay_ms(500);
		OLED_ShowString(3,1,"   ");
		Delay_ms(100);
	}
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE);
	
	WWDG_SetPrescaler(WWDG_Prescaler_8);
	WWDG_SetWindowValue(0x40 | 21);
	WWDG_Enable(0x40 | 54);   //50ms
	
	
	while (1)
	{
		//按住按键不放,就会阻塞程序
		Key_GetNum();
		
		OLED_ShowString(4,1,"FEED");
		Delay_ms(20);
		OLED_ShowString(4,1,"    ");
		Delay_ms(20);
		
		WWDG_SetCounter(0x40 | 54);
	}
}

值得注意的是:
①根据WWDG的超时时间公式,要想得到超时时间位50ms,即预分频(WDGTB预分频系数)给8,重装值(T[5:0])给54,0x40 | 54的含义是将寄存器T6位设置为1(1表示不溢出).
②根据WWDG的窗口时间公式,知道了WDGTB预分频系数以及T[5:0]的重装值,要想得到窗口时间位30ms,则W[5:0]的值应为21,0x40 | 21的含义是将寄存器W6位置为1,W6应该也是表示溢不溢出的标志位.
③WWDG没有重装寄存器,重装时直接给寄存器赋值即可.
④循环中的代码WWDG_SetCounter(0x40 | 54);不应放在循环开头,这会导致在程序一启动设置的WWDG的值大于窗口值(过早喂狗).喂狗时间应在0~30ms内算正常.

  • 程序运行流程图:
### 独立看门狗(IWDG) - **介绍**:独立看门狗能产生系统复位信号的递减计数器,时钟由独立的 RC 振荡器提供,只要芯片供电(电压来自于 VDD)就可以工作,可在待机和停止模式下运行[^3]。 - **原理**:独立看门狗是一个递减计数器,被激活后开始计数。当递减计数器计数到 0x000 时,会产生复位信号。为避免复位,需要在计数器计数到 0 之前,对计数器进行重装载操作,即“喂狗”[^3]。 - **应用**:用于监测外界电磁干扰或硬件异常导致的程序跑飞问题,适用于一些需要高稳定性的产品,且对时间精度要求较低的场合。它是异常处理的最后手段,在设计时应尽量避免异常的发生[^3]。 - **配置示例代码**: ```c #include "stm32fxxx.h" void IWDG_Configuration(void) { // 使能独立看门狗时钟 IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); // 设置预分频器值 IWDG_SetPrescaler(IWDG_Prescaler_64); // 设置重装载值 IWDG_SetReload(1250); // 例如设置超时时间为1s // 重载计数值 IWDG_ReloadCounter(); // 使能独立看门狗 IWDG_Enable(); } int main(void) { IWDG_Configuration(); while (1) { // 喂狗操作 IWDG_ReloadCounter(); } } ``` ### 窗口看门狗(WWDG) - **介绍**:窗口看门狗的时钟来自于系统总线上的时钟,具有较高的时间精准度,并且有中断功能[^4]。 - **原理**:窗口看门狗也是一个递减计数器,其复位条件独立看门狗不同。当计数器大于窗口值 W[6:0] 时喂狗,或者计数器递减至 0x3F 时,会产生复位信号。它要求在特定的时间窗口内进行“喂狗”操作,以保证系统正常运行[^4]。 - **应用**:主要用于检测程序的时效性,防止软件异常。例如,在一些对程序执行时间有严格要求的场合,确保程序在规定的时间内完成相应的任务[^4]。 - **配置示例代码**: ```c #include "stm32fxxx.h" void WWDG_Configuration(void) { // 使能窗口看门狗时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); // 设置预分频器值 WWDG_SetPrescaler(WWDG_Prescaler_8); // 设置窗口值 WWDG_SetWindowValue(0x5F); // 设置计数器初始值 WWDG_Enable(0x7F); // 使能提前唤醒中断 WWDG_ClearFlag(); WWDG_ITConfig(ENABLE); } int main(void) { WWDG_Configuration(); while (1) { // 在合适的时间喂狗 } } // 窗口看门狗中断服务函数 void WWDG_IRQHandler(void) { // 喂狗操作 WWDG_SetCounter(0x7F); // 清除中断标志 WWDG_ClearFlag(); } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

必胜的思想钢印

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

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

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

打赏作者

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

抵扣说明:

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

余额充值