当前位置: 首页 > article >正文

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

文章目录

  • WDG看门狗
    • 一、WDG简介
    • 二、独立看门狗(IWDG)
      • Ⅰ、IWDG框图
      • Ⅱ、键寄存器(IWDG_KR)
      • Ⅲ、IWDG超时时间
    • 三、窗口看门狗(WWDG)
      • Ⅰ、WWDG框图
      • Ⅱ、WWDG工作特性
      • Ⅲ、WWDG超时时间
    • 四、对比
    • 五、IWDG函数
      • ①、IWDG配置
      • ②、IWDG配置示例
    • 六、WWDG函数
      • ①、WWDG配置
      • ②、WWDG配置示例

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启用独立看门狗
0xAAAAIWDG_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
/400.1 (ms)409.6 (ms)
/810.2 (ms)819.2 (ms)
/1620.4 (ms)1638.4 (ms)
/3230.8 (ms)3276.8 (ms)
/6441.6 (ms)6553.6 (ms)
/12853.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、2561、2、4、8
计数器12位6位(有效计数)
超时时间0.1ms~26214.4ms113us~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	
    }
}


http://www.kler.cn/a/510235.html

相关文章:

  • 庄小焱——2024年博文总结与展望
  • Hadoop•用Web UI查看Hadoop状态词频统计
  • JVM相关面试题
  • 前端项目搭建和基础配置
  • 移动端布局 ---- 学习分享
  • Elasticsearch:Jira 连接器教程第二部分 - 6 个优化技巧
  • python有goto语句吗
  • 《Java开发手册》核心内容
  • Qt开发:QSqlDatabase的常见用法
  • JAVA实现捡金币闯关小游戏(附源码)
  • xclip和xsel命令行工具详解
  • 大语言模型的语境中“越狱”和思维链
  • 最新-CentOS 7安装Docker容器(适合本地和云服务器安装)
  • 统信V20 1070e X86系统编译安装PostgreSQL-13.11版本以及主从构建
  • 嵌入式工程师必学(67):SWD仿真接口(for ARM)的使用方法
  • 在 Windows 上,如果忘记了 MySQL 密码 重置密码
  • 软考中级复习篇章:数据结构部分的复习
  • 2024年,我的技术探索与成长之路
  • Java(面向对象进阶——接口)
  • springboot基于微信小程序的停车场预订系统
  • 移远通信多模卫星通信模组BG95-S5获得Skylo网络认证,进一步拓展全球卫星物联网市场
  • 基于Java+MySQL实现在线作业提交系统
  • Android 上删除的短信存储在哪里 - 如何恢复
  • dl学习笔记:(4)简单神经网络
  • Java杂记:@TableField注解用法详解
  • HTTPS与HTTP:区别及安全性对比