0x0F WDG

一、WDG

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

二、IWDG

和TIM定时器很像, 只不过当CNT==ARR, 会清0CNT, 但是看门狗的这个RLR, 需要手动重装, 这一步就是喂狗, 如果喂狗不及时, IWDG的CNT就会清0 , 产生复位

这里的RLR(reload register)就好比TIM的ARR(auto reload register), PSC就好比PR(都是一个意思, 预分频器), CNT就好比这个12位的递减计数器

于是我们可以轻易得出喂狗频率的计算公式

*TFEED=LSI/(PR+1)RLR

假设需要一秒喂一次狗, 那么(PR+1)*RLR就需要等于40000hz

PR可以是2499 RLR可以是16(不固定)

image-20231105201345614

写入键寄存器的值作用
0xCCCC启用独立看门狗
0xAAAAIWDG_RLR中的值重新加载到计数器(喂狗)
0x5555解除IWDG_PR和IWDG_RLR的写保护
0x5555之外的其他值启用IWDG_PR和IWDG_RLR的写保护

其实配置库函数就是在配置这个入键寄存器, 知道就行

以下是独立看门狗的代码, 现在是每0.8s喂一次狗, 于是FEED会一直显示, 但如果delay的时间超过1s, 就会来不及喂狗, 出现独立看门狗的复位

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"

int main(void)
{
	OLED_Init();
	//如果复位来自独立看门狗打印IWDGRST
	if(RCC_GetFlagStatus(RCC_FLAG_IWDGRST)==SET){
		OLED_ShowString(1,1,"IWDGRST");
		Delay_ms(500);
		OLED_ShowString(1,1,"       ");
	}
    //否则打印RST
	else{
		OLED_ShowString(1,1,"RST    ");
		Delay_ms(500);
		OLED_ShowString(1,1,"       ");
	}
    
	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);//看门狗写使能
	IWDG_SetPrescaler(IWDG_Prescaler_16); //设置16分频
    IWDG_SetReload(2500-1); //设置重装值为2499
	IWDG_Enable(); //启动独立看门狗
	IWDG_ReloadCounter(); //手动重装

	while (1)
	{
		IWDG_ReloadCounter(); //喂狗
		OLED_ShowString(2,1,"FEED");
		Delay_ms(400);//Delay_ms(650);
		OLED_ShowString(2,1,"    ");
		Delay_ms(400);
        //如果这里delay的总和超过1000 超过规定喂狗时间, 程序就会产生复位
	}
}

三、WWDG

窗口看门狗的时钟来自于APB1且经过固定的4096分频 , 这里的WDGTB就好比PSC, WWDG_CR就好比CNT的WDGA位表示使能位, T6表示溢出, 当T6为0, 表示数据CNT为0, 执行复位, 喂狗就是写WWDG_CR, WWDG_CFR就是窗口区, 早于这个值喂狗会也会导致复位

递减计数器T[6:0]等于0x40(下一刻T6=0)时可以产生早期唤醒中断(EWI),用于重装载计数器以避免WWDG复位 可以在库函数中的 WWDG_EnableIT(void); 使能中断, 在复位前最后一刻进入中断, 关闭危险设备/保留关键数据

image-20231106152634975

  • 超时时间: TWWDG = TPCLK1 × 4096 × WDGTB预分频系数 × (T[5:0] + 1)
  • 窗口时间: TWIN = TPCLK1 × 4096 × WDGTB预分频系数 × (T[5:0] - W[5:0])
  • 其中:TPCLK1 = 1 / FPCLK1

如果需要一个在30ms-50ms窗口内的喂狗频率, 那么WDFTB可以配置为8 , T[5:0] 为54 ,W[5:0]为21

以下是窗口看门狗的代码, 现在是每0.8s喂一次狗, 于是FEED会一直显示, 但如果delay的时间超过50md或低于30md, 就会来不及喂狗, 出现窗口看门狗的复位

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"

int main(void)
{
	OLED_Init();
	//如果复位来自窗口看门狗打印WWDGRST
	if(RCC_GetFlagStatus(RCC_FLAG_WWDGRST)==SET){
		OLED_ShowString(1,1,"WWDGRST");
		Delay_ms(500);
		OLED_ShowString(1,1,"       ");
	}
    //否则打印RST
	else{
		OLED_ShowString(1,1,"RST    ");
		Delay_ms(500);
		OLED_ShowString(1,1,"       ");
	}
    RCC_APB1PeriphClockCmd(RCC_APB1ENR_WWDGEN,ENABLE);//开启窗口看门狗时钟
	WWDG_SetPrescaler(WWDG_Prescaler_8); //WDFTB为8
    //这里或上0x40是为了不改变T6(溢出标志位)
	WWDG_SetWindowValue(0x40 | 21); // T[5:0] 为54
	WWDG_Enable(0x40 | 54);  //W[5:0]为21
	while (1)
	{
		OLED_ShowString(2,1,"FEED");
		Delay_ms(20);//可以尝试修改delay的值, 看到不同效果
		OLED_ShowString(2,1,"    ");
		Delay_ms(20);
        //如果这里delay的总和超过50或低于30 不符合喂狗时间, 程序就会产生复位
		WWDG_SetCounter(0x40 | 54); //喂狗
	}
}

四、对比

大部分时间用IWDG就够了, 只有在需要及其精确控制的情况下用WWDG

IWDG独立看门狗WWDG窗口看门狗
复位计数器减到0后计数器T[5:0]减到0后、过早重装计数器
中断早期唤醒中断
时钟源LSI(40KHz)PCLK1(36MHz)
预分频系数4、8、32、64、128、2561、2、4、8
计数器12位6位(有效计数)
超时时间0.1ms~26214.4ms113us~58.25ms
喂狗方式写入键寄存器,重装固定值RLR直接写入计数器,写多少重装多少
防误操作键寄存器和写保护
用途独立工作,对时间精度要求较低要求看门狗在精确计时窗口起作用
数器,写多少重装多少
防误操作键寄存器和写保护
用途独立工作,对时间精度要求较低要求看门狗在精确计时窗口起作用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值