江协科技STM32学习笔记(第13章 WDG看门狗)

news2024/9/20 22:58:05

第13章 WDG看门狗

13.1 WDG看门狗

13.1.1 WDG简介

看门狗就是程序运行的一个保障措施,我们得在程序中定期地喂狗,如果程序卡死了,没有在规定的时间里喂狗,那么看门狗硬件电路就会自动帮我们复位一下,防止程序长时间卡死,起到重启的作用。

WDG(Watchdog)看门狗;

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

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

STM32内置两个看门狗:

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

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

13.1.2 IWDG框图

预分频器之前,输入时钟是LSI,内部低速时钟, 时钟频率为40KHz,之后时钟进入预分频器进行分频,这个分频器只有8位,所以最大只能进行256分频。上面这个预分频寄存器IWDG_PR,可以配置分频系数,这个PR和定时器的PSC是一个意思,它们都是Prescale的缩写,可能不是一个人设计的,所以手册里很多缩写都不太一样。之后后面,时钟经过预分频器分频之后,时钟驱动递减计数器,每来一个时钟,自减一个数,另外这个数是12位的,所以最大值是2^12-1=4095,然后,当自减到0之后,产生IWDG复位,正常运行时,为了避免复位,我们可以提前在重装寄存器写一个值,IWDG_RLR,和定时器的ARR是一样的,RLR是Reloader,ARR是Auto Reloader,那当我们预先写好值之后,在运行过程中,我们在这个键寄存器里写一个特定数据,控制电路进行喂狗,这时重装值就会复制到当前的计数器中,这样计数器就会回到重装值,重新自减运行了。状态寄存器IWDG_SR,这就是标志电路运行的状态了,其实这个SR里没什么东西,只有两个更新同步位,最后,上面这些寄存器,位于1.8V供电区,下面主要的工作电路,都位于VDD供电区。

13.1.3 IWDG键寄存器

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

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

如果只在控制寄存器中设置一个位,那这一位就有可能在误操作中,变成1或者变成0,这个概率是比较大的,所以单独设置一位来进行控制比较危险。比如程序跑飞,胡乱地设置各个寄存器,寄存器收到影响,可能会变成0x0000,0xFFFF,它可以随机变为任何数,但它恰好变成0xAAAA这个数的概率比较小。

写入键寄存器的值

作用

0xCCCC

启用独立看门狗

0xAAAA

IWDG_RLR中的值重新加载到计数器(喂狗)

0x5555

解除IWDG_PRIWDG_RLR的写保护

0x5555之外的其他值

启用IWDG_PRIWDG_RLR的写保护

13.1.4 IWDG超时时间

13.1.5 WWDG框图

窗口看门狗没有重装寄存器, 那如何重装寄存器喂狗呢?我们直接在CNT写入数据就行了,想写多少就写多少。喂狗的最早时间界限,就写到看门狗配置寄存器(WWDG_CFR)存起来。左边就是输出信号的操作逻辑了,什么情况下会产生复位,就有这几个逻辑门来确定。

时钟来源是PCLK1,也就是APB1的时钟,这个时钟默认是36MHz,所以就是36MHz的时钟进来,进来之后,还是先经过一个预分频器进行分频,这个和独立看门狗的预分频器,定时器的预分频器,都是一个作用,就是灵活地调节后面计数器地时钟频率,同时预分频系数也是计算计数器溢出时间的重要参数。接着,分频之后的时钟,驱动这个计数器进行计数,这个计数器和独立看门狗一样,也是一个递减计数器,没来一个时钟,自减一次,不过这个计数器比较特殊,从图上看,这里写了T6~T0,总共是7个位,但下面确写的是6位递减计数器,最高位T6,这里用来当作溢出标志位,T6位等于1时,表示计数器没溢出,T6位等于0时,表示计数器溢出,不过对于硬件电路来说,T6位也是计数器的一部分。只不过T6位被单独拎出来,当作标志位了而已。举个例子,比如这个计数器,我们给初始值111 1111,那么来一个计数脉冲,值减1,变为111 1110,再来一个变为111 1101,直到减为100 0000这一个数值,是一个关键节点,此时包括T6位在内的数,是100 0000,转为16进制0x40,那就是说,若果把T6位的值也当作计数器的一部分,那计数器的值实际上才减一半,但是如果把T6位剥离出去,当作溢出标志位,低6位,当作计数器,那此时的状态就是,标志位为1,计数器为000 0000,已经减到0了,再减一次,下一个值就是011 1111,这时最高位T6由1变为0,即代表计数器溢出,这时最高位T6,就会通过这个线路,产生复位信号。

这就是这个计数器的工作流程和溢出条件。 

13.1.6 WWDG工作特性

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

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

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

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

13.1.7  WWDG超时时间

13.1.8 IWDG和WWDG对比 

IWDG独立看门狗

WWDG窗口看门狗

复位

计数器减到0

计数器T[5:0]减到0后、过早重装计数器

中断

早期唤醒中断

时钟源

LSI40KHz

PCLK136MHz

预分频系数

483264128256

1248

计数器

12

6位(有效计数)

超时时间

0.1ms~26214.4ms

113us~58.25ms

喂狗方式

写入键寄存器,重装固定值RLR

直接写入计数器,写多少重装多少

防误操作

键寄存器和写保护

用途

独立工作,对时间精度要求较低

要求看门狗在精确计时窗口起作用

13.2 独立看门狗

13.2.1 硬件电路

13.2.2 软件部分

(1)复制《OLED显示屏》并改名为《独立看门狗》

(2)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);         //获取标志位状态

(3)main.c

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

int main(void)
{
	/*模块初始化*/
	OLED_Init();						//OLED初始化
	Key_Init();							//按键初始化
	
	/*显示静态字符串*/
	OLED_ShowString(1, 1, "IWDG TEST");
	
	/*判断复位信号来源*/
	if (RCC_GetFlagStatus(RCC_FLAG_IWDGRST) == SET)	//如果是独立看门狗复位
	{
		OLED_ShowString(2, 1, "IWDGRST");			//OLED闪烁IWDGRST字符串
		Delay_ms(500);
		OLED_ShowString(2, 1, "       ");
		Delay_ms(100);
		
		RCC_ClearFlag();							//清除标志位
	}
	else											//否则,即为其他复位
	{
		OLED_ShowString(3, 1, "RST");				//OLED闪烁RST字符串
		Delay_ms(500);
		OLED_ShowString(3, 1, "   ");
		Delay_ms(100);
	}
	
	/*IWDG初始化*/
	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);	//独立看门狗写使能
	IWDG_SetPrescaler(IWDG_Prescaler_16);			//设置预分频为16
	IWDG_SetReload(2499);							//设置重装值为2499,独立看门狗的超时时间为1000ms
	IWDG_ReloadCounter();							//重装计数器,喂狗
	IWDG_Enable();									//独立看门狗使能
	
	while (1)
	{
		Key_GetNum();								//调用阻塞式的按键扫描函数,模拟主循环卡死
		
		IWDG_ReloadCounter();						//重装计数器,喂狗
		
		OLED_ShowString(4, 1, "FEED");				//OLED闪烁FEED字符串
		Delay_ms(200);								//喂狗间隔为200+600=800ms
		OLED_ShowString(4, 1, "    ");
		Delay_ms(600);
	}
}

13.3 窗口看门狗

13.3.1 硬件电路

13.2.2 软件部分

(1)复制《独立看门狗》工程并改名为《窗口看门狗》

(2)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);                  //使能窗口看门狗
FlagStatus WWDG_GetFlagStatus(void);                //获取标志位
void WWDG_ClearFlag(void);                          //清除标志位

(3)main.c

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

int main(void)
{
	/*模块初始化*/
	OLED_Init();						//OLED初始化
	Key_Init();							//按键初始化
	
	/*显示静态字符串*/
	OLED_ShowString(1, 1, "WWDG TEST");
	
	/*判断复位信号来源*/
	if (RCC_GetFlagStatus(RCC_FLAG_WWDGRST) == SET)	//如果是窗口看门狗复位
	{
		OLED_ShowString(2, 1, "WWDGRST");			//OLED闪烁WWDGRST字符串
		Delay_ms(500);
		OLED_ShowString(2, 1, "       ");
		Delay_ms(100);
		
		RCC_ClearFlag();							//清除标志位
	}
	else											//否则,即为其他复位
	{
		OLED_ShowString(3, 1, "RST");				//OLED闪烁RST字符串
		Delay_ms(500);
		OLED_ShowString(3, 1, "   ");
		Delay_ms(100);
	}
	
	/*开启时钟*/
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);	//开启WWDG的时钟
	
	/*WWDG初始化*/
	WWDG_SetPrescaler(WWDG_Prescaler_8);			//设置预分频为8
	WWDG_SetWindowValue(0x40 | 21);					//设置窗口值,窗口时间为30ms
	WWDG_Enable(0x40 | 54);							//使能并第一次喂狗,超时时间为50ms
	
	while (1)
	{
		Key_GetNum();								//调用阻塞式的按键扫描函数,模拟主循环卡死
		
		OLED_ShowString(4, 1, "FEED");				//OLED闪烁FEED字符串
		Delay_ms(20);								//喂狗间隔为20+20=40ms
		OLED_ShowString(4, 1, "    ");
		Delay_ms(20);
		
		WWDG_SetCounter(0x40 | 54);					//重装计数器,喂狗
	}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2042671.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

<keep-alive> 一分钟了解

<keep-alive> 一分钟了解 <keep-alive> 是 Vue.js 提供的一个抽象组件&#xff0c;它的主要用途是在页面或组件切换时保留其状态&#xff0c;避免重复执行昂贵的渲染操作&#xff0c;从而提升应用性能。 文章目录 <keep-alive> 一分钟了解 一、 <keep-ali…

Ubuntu如何实现每天定时关机

要在Ubuntu中实现每天定时关机&#xff0c;你可以使用cron来安排定时任务。以下是具体的步骤&#xff1a; 步骤 1: 创建脚本 打开终端。使用文本编辑器创建一个新的文件。例如&#xff1a; nano ~/shutdown_script.sh 步骤 2: 编写脚本 在编辑器中输入以下内容&#xff1a…

华府便利店信息管理系统

TOC springboot239华府便利店信息管理系统 绪论 1.1 研究背景 当前社会各行业领域竞争压力非常大&#xff0c;随着当前时代的信息化&#xff0c;科学化发展&#xff0c;让社会各行业领域都争相使用新的信息技术&#xff0c;对行业内的各种相关数据进行科学化&#xff0c;规…

花四小时,写了个在线实时绘制等值面图小软件,明晚上线,喜欢的小伙伴关注哦

科研党的福音&#xff0c;绘图再也不需要安装一堆软件了&#xff0c;可以在线绘图了&#xff1b; 只需要传入绘制的区间、色值、以及所需要绘制的数据就可以直接出图了&#xff0c;可绘制各种等值面图&#xff0c;比如降水分布&#xff0c;高温分布&#xff0c;人口分布&#x…

文心快码真的很好用!!!

最近被身边的好友安利到了一个百度的新产品文心快码&#xff08;comate&#xff09;&#xff0c;没想到体验下来真的很好用&#xff0c;非常容易上手&#xff0c;解放了我的双手&#xff0c;提高了代码生产力&#xff01;可能有很多小伙伴不知道怎么使用comate,而我作为这类工具…

C语言-将n个数输入时顺序的逆序排列,用指针函数实现

一、题目要求&#xff1a; 将n个数输入时顺序的逆序排列&#xff0c;用指针函数实现 二、程序: #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> int main() {int n;printf("请输入一共有多少数:\n");scanf("%d", &n);int arr[100], i;…

大模型之二十五-人工智能新纪元

人类社会正式从信息科技时代步入了人工智能时代&#xff0c;相比信息科技革命&#xff0c;人工智能科技革命的影响要深远的多&#xff0c;在这新旧交替剧烈变革期&#xff0c;绝大多数人都有机会。 为了更好的理解人工智能科技革命&#xff0c;首先我们首先梳理一下技术的发展…

使用VNC-viewer对树莓派5 远程连接桌面—详细记录笔记版

树莓派5 的远程桌面连接&#x1f680; 在完成了对树莓派镜像的安装&#xff0c;以及点亮了屏幕之后&#xff0c;接下来就是为开发做一些准备&#xff0c;就是配置树莓派5的远程的桌面的操作&#xff0c;因为如果不这样的话&#xff0c;我在PC上和树莓派系统上分别进行作业的时候…

了解数据库中常用存储引擎数据结构(2)

目录 深入了解B树及其变种 BTree BTree B*Tree BTree并发机制 B-Link Tree 深入了解B树及其变种 先把我们要解释的B树变种都列出来&#xff0c;B树的变种主要有B树、B*树、B-Link树、COW B树、惰性B树、Bw树等。 下面具体来分析这些变种的优势和发展趋势。 BTree 下图…

C语言整数溢出的问题

补漏&#xff1a; 昨天我在开头提到-1的二进制如何表示&#xff0c;我在这里简单分析一下。 首先我们要明白有符号的数转换是需要补码的&#xff0c;所以我们想这个问题之前将补码的规则思考一遍&#xff08;首先将有符号的首位保留&#xff0c;后面几位取反后加一&#xff0…

数据结构初阶——算法复杂度超详解

文章目录 1. 数据结构前言1. 1 数据结构1. 2 算法 2. 算法效率2. 1 复杂度的概念 3. 时间复杂度3. 1 大O的渐进表示法3. 2 时间复杂度计算示例3. 2. 1 示例13. 2. 2 示例23. 2. 3 示例33. 2. 4 示例43. 2. 5 示例53. 2. 6 示例63. 2. 7 示例7 4. 空间复杂度4. 1 空间复杂度计算…

螺丝虽小,但其质量关乎家具安全——业内解读紧固件生产标准

螺丝是家具组装中不可或缺的部件&#xff0c;其质量直接影响到家具的牢固性和安全性。因此&#xff0c;在生产螺丝时&#xff0c;必须确保螺丝符合家具组装的耐用性和安全性要求。确保生产出来的螺丝符合家具组装的耐用性和安全性要求&#xff0c;需要从设计、材料选择、生产工…

思维导图软件哪个好?这里有4款专业工具供你选择!

如何选择适合自己的思维导图软件&#xff1f;哪个思维导图软件好&#xff1f;选择思维导图工具时需要考虑使用的场景&#xff0c;操作的难易程度和性价比。在此基础上&#xff0c;我筛选了4款比较优秀的思维导图工具分享给大家。 1、福昕导图软件 传送门&#xff1a;pdf365.cn…

重写的介绍

一、基本介绍 1、基本介绍 重写又称为覆盖(override)&#xff0c;即子类继承父类的属性和方法后&#xff0c;根据业务需求&#xff0c;再重新定义同名的属性或方法 2、案例演示 二、练习 class Person:nameNoneageNonedef __init__(self,name,age):self.namenameself.ageage…

FastAPI+SQLModel开发角色的增删改查接口实战,附完整代码

实现查询角色的功能 完整代码&#xff1a; router.get("/", summary"角色查询") def get_role(page: int 1,size: int 20,name: str "",nickname: str "",db: SASession Depends(get_db), ):"""分页查询文件&qu…

面试被问到关于软件测试计划方面的面试题,怎么样回答好。

1、软件的评审一般由哪些人参加?其目的是什么? 参考答案&#xff1a; 在正式的会议上将软件项目的成果(包括各阶段的文档、产生的代码等)提交给用户、客户或有关部门人员对软件产品进行评审和批准。其目的是找出可能影响软件产品质量、开发过程、维护工作的适用性和环境方面…

系统编程-常用工具2

常用工具&#xff08;2&#xff09; 目录 常用工具&#xff08;2&#xff09; 一、gdb调试工具 如果想进行调试 编译程序的时候 二、makefile 脚本编译工具 1、makefile是什么&#xff1f; 2、使用makefile -- 安装make指令 -- make指令的使用 -- Makefile文件的书写…

面向新人的 Java 面试问题(51-100)

51. 使用 new() 创建 String 与创建文字有何不同&#xff1f; 使用 new() 的字符串与文字不同&#xff0c;因为当我们声明字符串时&#xff0c;它将元素存储在堆栈内存中&#xff0c;而当使用 new() 声明时&#xff0c;它会在堆内存中分配动态内存。即使存在相同内容的对象&am…

Xv6——物理分配器

对应文件&#xff1a;kalloc.c 物理内存布局 在Xv6中&#xff0c;物理内存大小是固定的&#xff0c;为128MB。物理内存起止也是固定的&#xff0c;由宏 KERNVASE 和 宏 PHYSTOP 定义。系统启动时&#xff0c;会把内核的代码加载到物理内存当中去&#xff1b;因此&#xff0c;可…

Android-自适用高度的ViewPager

需求 在项目中&#xff0c;我们常常遇到需要动态调整 ViewPager 的高度&#xff0c;以适应其内容大小的需求。默认情况下&#xff0c;ViewPager 的高度是固定的&#xff0c;无法根据每个页面的内容高度进行调整。这会导致在内容高度不一致时&#xff0c;出现不必要的空白区域或…