【STM32-学习笔记-13-】WDG看门狗

发布于:2025-02-10 ⋅ 阅读:(43) ⋅ 点赞:(0)

WDG看门狗

一、WDG简介

  • 当程序出现异常时,能够自动复位系统,以保证系统的可靠性和安全性
  • STM32内置两个看门狗
特性 独立看门狗(IWDG 窗口看门狗(WWDG
时钟源 内部低速时钟(LSI) APB1时钟分频后得到的时钟
计数器位数 12位递减计数器 -
超时时间计算 T o u t = P R E R × ( R L R + 1 ) L S I Tout=\frac{PRER×(RLR+1)}{LSI} Tout=LSIPRER×(RLR+1) 时钟频率 -
是否可被调试工具暂停 不可 可以
应用场景 对时间精度要求低,需要完全独立工作的场合 要求在精确计时窗口起作用的程序
喂狗要求 在计数器减到0之前喂狗即可 必须在指定时间窗口内喂狗,否则系统复位
复位条件 计数器减到0 喂狗太早(计数器值大于窗口值)或太晚(计数器倒计时到0)

独立看门狗(IWDG)

  • 工作原理:IWDG是一个由内部低速时钟(LSI)驱动的12位递减计数器,LSI的频率通常在30kHz到60kHz之间,一般计算时取40kHz
    • IWDG内部还可以对LSI时钟进行分频,分频后的时钟作为计数器的时钟信号。当计数器值减到0时,会产生系统复位
  • 超时时间计算:超时时间 T o u t = P R E R × ( R L R + 1 ) L S I Tout=\frac{PRER×(RLR+1)}{LSI} Tout=LSIPRER×(RLR+1) 时钟频率(其中PRER是预分频系数,RLR是计数器重装载值)
  • 特点
    • 由独立的LSI时钟驱动,即使主时钟发生故障,它仍有效
    • 配置简单,适用于通用场景
    • 一旦启用,无法被软件或调试工具停止,只能通过硬件复位重启
  • 喂狗操作:在计数器减到0之前,将重载寄存器IWDG_RLR里的值重新载入看门狗计数器,就可以避免产生复位

窗口看门狗(WWDG)

  • 工作原理:WWDG是一个要求在精确计时窗口起作用的看门狗,由APB1时钟分频后得到的时钟驱动。它通过可配置的时间窗口来检测应用程序非正常的过迟或过早操作
  • 特点
    • 使用APB1的时钟,不算独立
    • 可以通过调试工具暂停计数
    • 可设置窗口值,要求喂狗在特定时间范围内完成,防止程序因逻辑错误频繁喂狗
  • 喂狗操作:喂狗必须在指定的时间窗口内完成,如果喂狗太早(计数器值大于窗口值)或太晚(计数器倒计时到0),系统会复位

二、独立看门狗(IWDG)

Ⅰ、IWDG框图

image-20250117115100299

Ⅱ、键寄存器(IWDG_KR)

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

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

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

Ⅲ、IWDG超时时间

  • 超时时间: T I W D G = T L S I × P R 预分频系数 × ( R L + 1 ) T_{IWDG} = T_{LSI} × PR预分频系数 × (RL + 1) TIWDG=TLSI×PR预分频系数×(RL+1)

  • 其中: T L S I = 1 F L S I T_{LSI} = \frac{1}{F_{LSI}} TLSI=FLSI1

  • 看门狗超时时间(40kHz的输入时钟(LSI))
预分频系数 PR[2:0] 最短时间 RL[11:0] = 0x000 最长时间(ms) RL[11:0] = 0xFFF
/4 0 0.1 (ms) 409.6 (ms)
/8 1 0.2 (ms) 819.2 (ms)
/16 2 0.4 (ms) 1638.4 (ms)
/32 3 0.8 (ms) 3276.8 (ms)
/64 4 1.6 (ms) 6553.6 (ms)
/128 5 3.2 (ms) 13107.2 (ms)
/256 (6或7) 6.4 (ms) 26214.4 (ms)

三、窗口看门狗(WWDG)

Ⅰ、WWDG框图

image-20250117134127316

  • 当7位(T[6:0])递减计数器从0x40翻转到0x3F(T6位清零)时,则产生一个复位
  • WDGA = 1:使能
  • 当看门狗被启用时, T6位必须被设置,以防止立即产生一个复位
  • image-20250117132753629

Ⅱ、WWDG工作特性

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

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

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

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

image-20250117133521431

Ⅲ、WWDG超时时间

  • 超时时间

    • T W W D G = T P C L K 1 × 4096 × W D G T B 预分频系数 × ( T [ 5 : 0 ] + 1 ) T_{WWDG} = T_{PCLK1} × 4096 × WDGTB预分频系数 × (T_{[5:0]} + 1) TWWDG=TPCLK1×4096×WDGTB预分频系数×(T[5:0]+1)
  • 窗口时间

    • T W I N = T P C L K 1 × 4096 × W D G T B 预分频系数 × ( T [ 5 : 0 ] − W [ 5 : 0 ] ) T_{WIN} = T_{PCLK1} × 4096 × WDGTB预分频系数 × (T_{[5:0]} - W_{[5:0]}) TWIN=TPCLK1×4096×WDGTB预分频系数×(T[5:0]W[5:0])

image-20250117134841545

  • 其中: T P C L K 1 = 1 F P C L K 1 T_{PCLK1} = \frac{1}{F_{PCLK1}} TPCLK1=FPCLK11

四、对比

如果独立看门狗已经由硬件选项或软件启动, LSI振荡器将被强制在打开状态,并且不能被关闭

在LSI振荡器稳定后,时钟供应给IWDG

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

五、IWDG函数

// 使能或失能IWDG寄存器的写访问
void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess);

// 设置IWDG预分频值
void IWDG_SetPrescaler(uint8_t IWDG_Prescaler);

// 设置IWDG重装载值
void IWDG_SetReload(uint16_t Reload);

// 重装载IWDG计数器
void IWDG_ReloadCounter(void);

// 使能IWDG
void IWDG_Enable(void);

// 获取IWDG标志位状态
FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG);

①、IWDG配置

  1. 开启LSI的时钟(自动执行
  2. 写入0x5555键值,解除写保护
  3. 设置预分频值(PR)和重装值(RLR)
    • 超时时间: T I W D G = 1 F L S I × P R 预分频系数 × ( R L + 1 ) T_{IWDG} = \frac{1}{F_{LSI}} × PR预分频系数 × (RL + 1) TIWDG=FLSI1×PR预分频系数×(RL+1)
  4. 在主循环钟写入0xAAAA不断喂狗

image-20250117163249813

②、IWDG配置示例

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

int main(void)
{
    OLED_Init();
	Key_Init();
	
	OLED_ShowString(1,1,"Test Code:");
	
	if(RCC_GetFlagStatus(RCC_FLAG_IWDGRST) == SET)//独立看门狗复位检测
	{
		OLED_ShowString(3,1,"IWDG_RES");//独立看门狗复位
		Delay_ms(500);
		OLED_ShowString(3,1,"        ");
		Delay_ms(100);
		RCC_ClearFlag();//清除标志位
	}
	else//按键复位检测
	{
		OLED_ShowString(4,1,"RES");
		Delay_ms(500);
		OLED_ShowString(4,1,"       ");
		Delay_ms(100);
	}
//********初始化独立看门狗************************	
	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);//开启对IWDG_PR和IWDG_RLR寄存器的写访问
	IWDG_SetPrescaler(IWDG_Prescaler_16);//设置预分频器的值
	IWDG_SetReload(2499);//设置重装值	1000ms之内必须喂一次狗
	IWDG_ReloadCounter();//喂狗
	IWDG_Enable();//启动看门狗
//********初始化独立看门狗************************	
	
    while(1)
    {
		Get_KeyNum();
		
		OLED_ShowString(2,1,"********");
		Delay_ms(500);
		OLED_ShowString(2,1,"        ");
		Delay_ms(100);
		
		IWDG_ReloadCounter();//喂狗
    }
}

六、WWDG函数

// 重置WWDG寄存器为默认值
void WWDG_DeInit(void);

// 设置WWDG预分频值
void WWDG_SetPrescaler(uint32_t WWDG_Prescaler);

// 设置WWDG窗口值
void WWDG_SetWindowValue(uint8_t WindowValue);

// 使能WWDG中断
void WWDG_EnableIT(void);

// 设置WWDG计数器值
void WWDG_SetCounter(uint8_t Counter);

// 使能WWDG并设置计数器值
void WWDG_Enable(uint8_t Counter);

// 获取WWDG标志位状态
FlagStatus WWDG_GetFlagStatus(void);

// 清除WWDG标志位
void WWDG_ClearFlag(void);

①、WWDG配置

  1. 开启窗口看门狗APB1的时钟
  2. 配置寄存器(预分频器WDGTB、窗口值WWDG_CFR
  3. 写入控制寄存器CR看门狗使能位、计数器溢出标志位、计数器有效位

image-20250117134841545

  • 超时时间 : T W W D G = T P C L K 1 × 4096 × W D G T B 预分频系数 × ( T [ 5 : 0 ] + 1 ) T_{WWDG} = T_{PCLK1} × 4096 × WDGTB预分频系数 × (T_{[5:0]} + 1) TWWDG=TPCLK1×4096×WDGTB预分频系数×(T[5:0]+1)

  • 窗口时间 : T W I N = T P C L K 1 × 4096 × W D G T B 预分频系数 × ( T [ 5 : 0 ] − W [ 5 : 0 ] ) T_{WIN} = T_{PCLK1} × 4096 × WDGTB预分频系数 × (T_{[5:0]} - W_{[5:0]}) TWIN=TPCLK1×4096×WDGTB预分频系数×(T[5:0]W[5:0])

②、WWDG配置示例

  • 示例中设置WWDG的时间为30ms~50ms
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "Key.h"
#include "OLED.h"

int main(void)
{
    OLED_Init();
	Key_Init();
	
	OLED_ShowString(1,1,"Test Code:");
	
	if(RCC_GetFlagStatus(RCC_FLAG_WWDGRST) == SET)//窗口看门狗复位检测
	{
		OLED_ShowString(3,1,"WWDG_RES");//窗口看门狗复位
		Delay_ms(500);
		OLED_ShowString(3,1,"        ");
		Delay_ms(100);
		RCC_ClearFlag();//清除标志位
	}
	else//按键复位检测
	{
		OLED_ShowString(4,1,"RES");
		Delay_ms(500);
		OLED_ShowString(4,1,"       ");
		Delay_ms(100);
	}
//********初始化窗口看门狗************************	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);//开启窗口看门狗的时钟
	WWDG_SetPrescaler(WWDG_Prescaler_8);//设置预分频系数
	WWDG_SetWindowValue(21 | 0x40);//设置窗口值	约为30ms
	WWDG_Enable(54 | 0x40);//超时时间	约为50ms
	//当看门狗被启用时,T6位必须被设置(即 | 0x40),以防止立即产生一个复位	
//********初始化窗口看门狗************************	
	
    while(1)
    {
		Get_KeyNum();
				
		OLED_ShowString(2,1,"********");
		Delay_ms(20);
		OLED_ShowString(2,1,"        ");
		Delay_ms(10);
		
		WWDG_SetCounter(54 | 0x40);//喂狗时写入重装值	超时时间50ms	
    }
}


网站公告

今日签到

点亮在社区的每一天
去签到