STM32——看门狗通俗解析

news2024/11/16 10:50:36

笔者在学习看门狗的视频后,对看门狗仍然是一知半解,后面在实际应用中发现它是一个很好用的检测或者调试工具。所以总结一下笔者作为初学小白对看门狗的理解。

主函数初始化阶段、循环阶段和复位

众所周知,程序的运行一般是这样的:

         程序在进入循环阶段之前,会在初始化阶段将每个寄存器或者某些变量赋值。初始化阶段的代码执行一次后,就不再执行了。而循环阶段的代码会执行很多次,一直循环反复的执行下去。这时,如果进行了 复位,程序就会从头开始,执行一次初始化代码,再反复执行循环代码。

而如何进行 复位 呢?常用的方法就是“RESET” 键,也就是复位键。在程序故障、跑飞或者卡死的时候,让它重头开始跑一遍,避免程序陷入到长时间的罢工状态。不过复位键是人为按下,在程序自动运行的应用环境中,显然不适用。于是,在程序中使用 看门狗 就可以代替 复位键 来重启程序。

 避免程序陷入到长时间的罢工状态。这一句话非常关键,比如下面这个检测按键是否被按下的程序当中,while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0); 会等待按键是否被释放(松手)。

如果这个按键一直被按下,或者这个按键出现了故障,导致这个while循环一直出不来,就会造成程序始终被卡在这个地方。

因此,另一种复位方式——看门狗,它可以通过定时来重新启动程序。 看门狗本质上是一个递减的定时器,如果程序在某个循环卡住了,当看门狗定时器时间跑完,看门狗就会复位程序,从而跳出循环,重头开始。

喂狗

看门狗只是一个检测程序故障的工具。当我们在程序的初始化阶段设置了一个看门狗,当看门狗定时器时间跑完就会进行复位,重头开始。而我们的程序是一个循环过程,这就导致了我们需要用一个方法,让看门狗在程序正常时不作为,又要在程序故障时起作用。

这时就要进行喂狗操作。喂狗一般是在循环阶段的最后进行,喂狗的本质是将定时器重装,从头递减,一旦喂了狗,看门狗就会重新定时,不会执行复位操作。而遇到程序卡死在某一个等待循环时,就不会执行到喂狗操作函数。这个时候,看门狗一到时间就会进行复位。另外,如果没有及时喂狗,在看门狗定时器倒计时结束前还没有喂狗,也会重启程序。也就是说循环程序执行一次的时间需要在看门狗定时器的时间规定范围内。

独立看门狗和窗口看门狗

独立看门狗和窗口看门狗都是规定了程序循环时间,一旦时间到了,就会执行复位操作。独立看门狗是规定了一个最大时间点,时间从这个最大时间点递减为0,即倒计时为0后,执行复位。而窗口看门狗是规定了一个时间段,如果没有在这个时间段范围进行喂狗,也会执行复位。

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

键寄存器(KR)是一个控制寄存器,通过写入值来控制看门狗的操作。

独立看门狗(IWDG)初始化

首先,要设置看门狗需要有个钥匙,这个钥匙是保护寄存器被其他程序随意修改,降低干扰。

IWDG_WriteAccess_Enable 将写保护解除,后续可以设置预分频寄存器和重装寄存器

IWDG_Prescaler_16   设置预分频寄存器为16分频。

独立看门狗时钟是由一个 独立 的内部低速时钟LSI 提供。LSI = 40kHz,IWDG超时时间计算公式:T(IWDG) = 1 / LSI * PR预分频系数 * (RL重装值+1)

上面代码预分频器为16分频,40k/16=2500,即一秒可以计数2500,设置重装值为2499,最大定时时间为一秒。

IWDG_ReloadCounter(); 为喂狗操作,这里作用是重新计数,在每次循环都需要进行喂狗操作。

程序完整版:

#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);
	}
}

窗口看门狗(WWDG)初始化

窗口看门狗时钟是由APB1时钟分频得到,PCLK=36MHz。

预分频系数最小超时值最大超时值
1113 μs7.28 ms
2227 μs 14.56 ms
4455 μs29.12 ms
8910 μs58.25 ms

WWDG超时时间计算公式:T(WWDG) = 1 / PCLK * 4096 * WDG预分频系数 * (T[5:0]+1)

WWDG窗口时间计算公式:T(WIN) = 1 / PCLK * 4096 * WDG预分频系数 * ( T[5:0] - W[5:0] )

图中,想让T(WWDG) = 50 ms , 50 ms = 1 / 36 Mhz * 4096 * 8 *(T[5:0]+1),求得T[5:0]=54

想让T(WIN) = 30 ms , 30 ms = 1 / 36 Mhz * 4096 * 8 *(T[5:0]- W[5:0]),求得T[5:0]=21

WWDG_SetCounter(0x40 | 54);        为喂狗操作,这里作用是重新计数,在每次循环都需要进行喂狗操作。

循环程序时间应该在30ms和50ms之间,低于或者超过都会 让看门狗进行复位。

程序完整版:

#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/2133853.html

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

相关文章

解决项目启动时报“找不到符号”问题

前言 在Java开发过程中,遇到“找不到符号”的错误是非常常见的现象。这种错误往往意味着编译器无法识别你所引用的某个类、方法或变量。本文旨在提供一套详细的排查和解决思路,帮助开发者快速定位并解决此类问题。 问题描述 “找不到符号”错误通常出…

K8S - Volume - NFS 卷的简介和使用

在之前的文章里已经介绍了 K8S 中两个简单卷类型 hostpath 和 emptydir k8s - Volume 简介和HostPath的使用 K8S - Emptydir - 取代ELK 使用fluentd 构建logging saidcar 但是这两种卷都有同1个限制, 就是依赖于 k8s nodes的空间 如果某个service pod中需要的vol…

2024年职场人士都在用的PDF转换工具大赏

PDF文件已经变得越来越常见了,是不是不知不觉你收到的或者发出去的文件都是这个格式。它可以巩固格式,但是编辑起来还是有一定难度的。这篇文章我来分享一些可以从pdf转换器免费版官网下载的工具。 1.Foxit PDF转换大师 链接一下>>https://www.p…

sqlgun靶场漏洞挖掘

进入首页首先看到一个搜索框,那么我们试一下xss 用script弹了个一 接下来我们尝试一下sql注入 这里我们使用联合查询查到了他的数据库名,那么这里也就存在SQL注入了 这里存在SQL注入那么我们就尝试一下是否可以注入木马来getshell 首先我们扫描目录&…

YOLO介绍—datawhale

速度快:YOLO的设计目标是实现快速的对象检测,它在保持相对高准确度的同时,能够实现高帧率的实时检测。 易于实现:YOLO的架构相对简单,易于理解和实现,这使得它在学术和工业界都得到了广泛的应用。 版本迭…

机器学习(西瓜书)第 14 章 概率图模型

14.1 隐马尔可夫模型 机器学习最重要的任务,是根据一些已观察到的证据(例如训练样本)来对感兴趣的未知变量(例如类别标记)进行估计和推测。概率模型(probabilistic model)提供了一种描述框架&a…

快讯丨深蓝L07将于9月20日正式上市

9月13日获悉,继第二十七届成都车展首发亮相后,深蓝汽车全新“科技智享中型轿车”——深蓝L07,将于9月20日迎来正式上市! 作为深蓝汽车旗下第二款轿车力作,深蓝L07携#左手深蓝超级增程,右手华为乾崑智能#两…

自动驾驶:LQR、ILQR和DDP原理、公式推导以及代码演示(六、ILQR正则化和line search)

(六)ILQR正则化和line search 1. ILQR正则化 在iLQR中,我们通常线性化系统动力学并对目标函数进行二阶近似。在反向传播步骤中,我们需要计算逆矩阵(控制变量对目标函数的二阶导数矩阵),用以更…

通信工程学习:什么是FDMA频分多址

FDMA:频分多址 FDMA(Frequency Division Multiple Access,频分多址)是一种在无线通信领域广泛应用的多址技术。该技术通过将可用的频谱资源按频率划分,把传输频带划分为若干较窄且互不重叠的子频带(或称信道…

IP-Adapter学习

参考:https://baijiahao.baidu.com/s?id1803373544569190578&wfrspider&forpc IP-Adapter 是 SD中比较重要的controlnet,由腾讯公司出品。主要原理:提取图像特征,并嵌入预训练文本,最终加入到扩散图像中。简…

阿里云社区领积分自动打卡Selenium IDE脚本

脚本 感觉打卡比较麻烦,要点开点按钮这种机械化的操作。 所以就自己整了个脚本: { “id”: “f9999777-9ad6-40e0-9435-4f105919c982”, “version”: “2.0”, “name”: “aliyun”, “url”: “https://developer.aliyun.com”, “tests”: [{ “id”…

bp的模块被隐藏了

看我们现在没有代理那个模块了 我们点击查看 这里有被我们隐藏的模块,比如代理等,把前面的眼睛点一下 这个模块就出来了,如果想把他固定在任务栏里 拖动这个位置 就好了,如果有其他问题可以留言,看到可进我的努力给你…

【JUC并发编程系列】深入理解Java并发机制:Synchronized机制深度剖析、HotSpot下的并发奥秘(四、synchronized 原理分析)

文章目录 【JUC并发编程系列】深入理解Java并发机制:Synchronized机制深度剖析、HotSpot下的并发奥秘(四、synchronized 原理分析)1. 虚拟机环境2. 基本数据类型占多少字节3. JVM对象头3.1 Klass Pointer3.2 实例属性3.3 对齐填充3.4 查看Java对象布局3.5 论证压缩效…

Failed building wheel for opencv-python-headless

Failed building wheel for opencv-python-headless 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页,我是博主英杰,211科班出身,就职于医疗科技公司,热衷分享知识,武汉城市开发者社区主理人…

PD虚拟机的优点有哪些,哪个版本的 Parallels Desktop 最稳定?

在如今多元化的操作系统环境中,Parallels Desktop 作为一款强大的跨平台虚拟机软件,提供了一个无缝集成Mac与Windows操作系统的解决方案。这篇文章将深入探讨Parallels Desktop的优点以及 Parallels Desktop 版本哪个最稳定,帮助你做出更明智…

探索Python的神秘力量:Borb库的奇妙之旅

文章目录 探索Python的神秘力量:Borb库的奇妙之旅背景:为何选择Borb?Borb库是什么?如何安装Borb库?简单库函数使用方法场景应用常见Bug及解决方案总结 探索Python的神秘力量:Borb库的奇妙之旅 背景&#x…

基于SpringBoot的考研资讯平台设计与实现

需要项目源码请联系我,目前有各类成品 毕设 javaweb ssh ssm springboot等等项目框架,源码丰富。 专业团队,咨询就送开题报告,活动限时免费,有需要的朋友可以来留言咨询。 一、摘要 随着现在网络的快速发展&#xff…

Kafka入门-C#操作

目录 1. 安装 zookeeper 1.1、官网下载Zookeeper 1.2、创建data文件夹 1.3、修改配置文件 1.4 启动Zookeeper服务:zkServer 1.5 客户端连接Zookeeper:zkCli 2.安装kafka 2.1、官网下载kafka,解压 2.2、修改配置 2.3 运行 .\bin\windows\kafka-server-start.bat .\…

CI/CD持续集成和持续部署以及相关软件的使用

目录 一:CI/CD是什么? 1.1 持续集成(Continuous Integration) 1.2 持续部署(Continuous Deployment) 1.3 持续交付(Continuous Delivery) CI/CD 的好处包括: 二:git…

Holynix: v1

确认物理地址 00:0C:29:BC:05:DE ip扫描 arp-scan -l 端口扫描 nmap 192.168.48.167 访问一下80端口 burp抓包 找到一个登录框 想着burp抓包试试 将抓到的包放入kali中的文件中使用sqlmap注入试试 sqlmap 存在sql注入 sqlmap -r password --batch --random-agent 发现…