一、WDG

1.WDG简介

        WDG(Watchdog)看门狗

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

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

        STM32内置两个看门狗:

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

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

2.IWDG框图(独立看门狗)

        输入时钟LSI内部低速时钟,时钟频率为40kHz,之后时钟进入预分频器进行分频,上面的IWDG_PR可以配置预分频系数,经过预分频器之后,时钟经过递减计数器,每来一个时钟,自减一个数,这个计数器是12位所以最大值为2^{12} -1 = 4095,当自减为0时,产生IWDG复位,正常情况下,为了避免复位,在IWDG_RLR寄存器写入一个值,写好值之后,在后面的键寄存器,写一个特定数据,控制电路进行喂狗,这时的重装值就会复制到当前的计数器中,这样计数器就会回到重装值,重新自减运行。

        上面的寄存器都位于1.8V供电区,下面的工作电路位于VDD供电区。

3.IWDG键寄存器     

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

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

4.IWDG超过时间

        超时时间:T_{IWDG}=T_{LSI} *PR *(RL+1)

        其中:T_{LSI} = 1/F_{LSI}

                LSI = 40kHz(输入时钟)   FLSI = 40k  TLSI是周期 = 1 / 40K = 0.025ms

        例如,采用4分频,RL给0,那么T_{IWDG} = 0.025 * 4 *1 =0.1ms也就是图中最短时间,RL给4095,那么T_{IWDG} = 0.025 * 4 *4096 =409.6ms,也就是图中最长时间。

5.WWDG框图(窗口看门狗)

        左下角为时钟源部分,时钟源为PCLK1,右边为预分频器WDGTB,上面是6位递减计数器,位于控制寄存器CR中,计数器和控制计数器合二为一,窗口看门狗没有重装寄存器,数据直接写入计数器,上面看门狗配置寄存器是窗口值,也就是设置最早和最晚喂狗时间,左边就是输出信号的操作逻辑。

        工作流程:时钟来源为PCLK1,也就是APB1的时钟,时钟默认是36MHz,时钟进来之后进入预分频器进行分频,分频之后的时钟驱动计数器进行计数,每来一个时钟自减一次,这个计数器的T5~T0是有效的计数值,T6是溢出标志位,T6位=1时表示计数器没溢出,T6位=0,表示计数器溢出,WDGA是窗口看门狗的激活位,也就是使能,WDGA写入1,启用窗口看门狗,使能位作用左上角的与门,与门的右边是复位信号的来源,有两个来源,用或门连接,下面一路来自于溢出标志位T6,当溢出时T6为0,进入与门前取反,所以0变为1,或门有效,输出1,当使能信号给1,那么溢出信号就通向复位。上部分W6~W0,我们需要写入最早界限的计数值,写入后固定不变,当我们执行写入WWDG_CR操作时,与门开关就会打开,写入CR也就是喂狗,在喂狗时,比较器开始工作,比较当前计数器T6:0 > 窗口值W6:0,比较结果为1,这个1通过或门也可以申请复位,这就是喂狗最早时间窗口的实现流程。

6.WWDG工作特性

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

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

        递减计数器T[6:0]等于0x40时可以产生早期唤醒中断(EWI),用于重装载计数器以避免WWDG复位

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

7.WWDG超过时间

        超时时间:

                T_{WWDG}=T_{PCLK1} * 4096 * WDGTB *(T[5:0]+1)

        窗口时间:

                T_{WIN}=T_{PCLK1} * WDGTB *(T[5:0] - W[5:0])

        其中:T_{PCLK1} = 1/F_{PCLK1},WDGTB为预分频系数,乘4096是因为在PCLK1进来时先执行了一个4096分频,然后再进入WDGTB分

        例如,采用不分频,WDGTB给0,那么T_{WWDG} =1/36M * 4096 * 2^0 * 1 =113us也就是图中最短时间,RL给2^6-1 = 63,那么T_{WWDG} =1/36M * 4096 * 2^0 * 64 =7.28ms,也就是图中最长时间。

8.IWDG和WWDG对比

二、IWDG库函数

void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess);

作用:写使能控制(解除写保护)

void IWDG_SetPrescaler(uint8_t IWDG_Prescaler);

作用:写预分频器

void IWDG_SetReload(uint16_t Reload);

作用:写重装值

void IWDG_ReloadCounter(void);

作用:重新装载寄存器(喂狗)

void IWDG_Enable(void);

作用:启动独立看门狗

FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG);

作用:获取标志位状态

三、WWDG库函数

void WWDG_DeInit(void);

作用:恢复缺省配置

void WWDG_SetPrescaler(uint32_t WWDG_Prescaler);

作用:写入预分频器值

void WWDG_SetWindowValue(uint8_t WindowValue);

作用:写入窗口值

void WWDG_EnableIT(void);

作用:使能中断

void WWDG_SetCounter(uint8_t Counter);

作用:写入计数器的值(喂狗)

void WWDG_Enable(uint8_t Counter);

作用:WWDG使能

FlagStatus WWDG_GetFlagStatus(void);

作用:获取WWDG标志位

void WWDG_ClearFlag(void);

作用:清除标志位

四、代码

1.代码1——独立看门狗

        独立看门狗配置流程:

                ①开启时钟LSI不需要写代码手动开启

                ②解除写保护

                ③写入预分频器值和重装寄存器值

                ④启动看门狗

                ⑤喂狗

main.c

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

int main(void)
{
	OLED_Init();
	Key_Init();
	
	OLED_ShowString(1, 1, "IWDG TSET");
	
	if (RCC_GetFlagStatus(RCC_FLAG_IWDGRST) == SET)   // 判断是复位键复位还是看门狗复位
	{
		OLED_ShowString(2, 1, "IWDGRST");
		Delay_ms(500);
		OLED_ShowString(2, 1, "       ");
		Delay_ms(500);
		RCC_ClearFlag();
	}
	else
	{
		OLED_ShowString(3, 1, "RST");
		Delay_ms(500);
		OLED_ShowString(3, 1, "   ");
		Delay_ms(500);
	}
	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);      // 解除写保护
	
	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(200);
		OLED_ShowString(4, 1, "    ");
		Delay_ms(600);
	}	
}

        程序下载后,不断显示FEED喂狗,当按住按键不放,阻塞喂狗,就会显示,IWDGRST复位,当按下复位键就会显示RST复位。

2.代码2——窗口看门狗

        窗口看门狗配置流程:

                ①开启APB1时钟

                ②写入预分频器值和窗口值

                ③写入控制寄存器CR(看门狗使能位、计数器溢出标志位、计数器有效位)

                ④手动写入重装值

        假设设置的超过时间是50ms,窗口时间是30ms,那么只能选择WDGTB=3,那么T[5:0]=54

W[5:0]=21

main.c

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

int main(void)
{
	OLED_Init();
	Key_Init();
	
	
	OLED_ShowString(1, 1, "WWDG TSET");
	
	if (RCC_GetFlagStatus(RCC_FLAG_WWDGRST) == SET)
	{
		OLED_ShowString(2, 1, "WWDGRST");
		Delay_ms(500);
		OLED_ShowString(2, 1, "       ");
		Delay_ms(500);
		RCC_ClearFlag();
	}
	else
	{
		OLED_ShowString(3, 1, "RST");
		Delay_ms(500);
		OLED_ShowString(3, 1, "   ");
		Delay_ms(500);
	}
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);
	
	WWDG_SetPrescaler(WWDG_Prescaler_8);
	WWDG_SetWindowValue(0x40 | 21);
	WWDG_Enable(0x40 | 54);
	
	while (1)
	{
		Key_GetNum();

		OLED_ShowString(4, 1, "FEED");
		Delay_ms(20);
		OLED_ShowString(4, 1, "    ");
		Delay_ms(20);
		
		WWDG_SetCounter(0x40 | 54);   // 避免过快喂狗导致过早与窗口值
	}	
}

        我们可以看出54为重装值,但是只代表T[5:0],还有最高位T6所以需要且0x40使最高位为1,窗口值也是如此。

        程序下载后,不断显示FEED喂狗,当按住按键不放,阻塞喂狗,就会显示,WWDGRST复位,当按下复位键就会显示RST复位。

五、总结

        STM32的看门狗(Watchdog)是一种用于监控系统运行状态的定时器,分为独立看门狗(IWDG)和窗口看门狗(WWDG):独立看门狗由专用低速时钟(LSI)驱动,适用于监测主程序异常,需在计数器溢出前喂狗以避免系统复位;窗口看门狗由APB1时钟驱动,具有时间窗口限制,仅在特定窗口内喂狗才有效,可更精准地检测程序运行超时或异常,两者均通过强制复位确保系统在故障时恢复正常运行。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐