STM32——看门狗通俗解析
笔者在学习看门狗的视频后,对看门狗仍然是一知半解,后面在实际应用中发现它是一个很好用的检测或者调试工具。所以总结一下笔者作为初学小白对看门狗的理解。
主函数初始化阶段、循环阶段和复位
众所周知,程序的运行一般是这样的:

程序在进入循环阶段之前,会在初始化阶段将每个寄存器或者某些变量赋值。初始化阶段的代码执行一次后,就不再执行了。而循环阶段的代码会执行很多次,一直循环反复的执行下去。这时,如果进行了 复位,程序就会从头开始,执行一次初始化代码,再反复执行循环代码。
而如何进行 复位 呢?常用的方法就是“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); //设置预分频为16IWDG_SetReload(2499); //设置重装值为2499,独立看门狗的超时时间为1000msIWDG_ReloadCounter(); //重装计数器,喂狗IWDG_Enable(); //独立看门狗使能while (1){Key_GetNum(); //调用阻塞式的按键扫描函数,模拟主循环卡死IWDG_ReloadCounter(); //重装计数器,喂狗OLED_ShowString(4, 1, "FEED"); //OLED闪烁FEED字符串Delay_ms(200); //喂狗间隔为200+600=800msOLED_ShowString(4, 1, " ");Delay_ms(600);}
}
窗口看门狗(WWDG)初始化

窗口看门狗时钟是由APB1时钟分频得到,PCLK=36MHz。
| 预分频系数 | 最小超时值 | 最大超时值 |
| 1 | 113 μs | 7.28 ms |
| 2 | 227 μs | 14.56 ms |
| 4 | 455 μs | 29.12 ms |
| 8 | 910 μs | 58.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); //设置预分频为8WWDG_SetWindowValue(0x40 | 21); //设置窗口值,窗口时间为30msWWDG_Enable(0x40 | 54); //使能并第一次喂狗,超时时间为50mswhile (1){Key_GetNum(); //调用阻塞式的按键扫描函数,模拟主循环卡死OLED_ShowString(4, 1, "FEED"); //OLED闪烁FEED字符串Delay_ms(20); //喂狗间隔为20+20=40msOLED_ShowString(4, 1, " ");Delay_ms(20);WWDG_SetCounter(0x40 | 54); //重装计数器,喂狗}
}
相关文章:
STM32——看门狗通俗解析
笔者在学习看门狗的视频后,对看门狗仍然是一知半解,后面在实际应用中发现它是一个很好用的检测或者调试工具。所以总结一下笔者作为初学小白对看门狗的理解。 主函数初始化阶段、循环阶段和复位 众所周知,程序的运行一般是这样的࿱…...
点亮第一盏LED灯 5): stm32CubeMX生成Keil代码
嵌入式入门,继续点亮第一盏LED灯,前面文章已经配置了GPIO引脚和时钟,那么基本上stm32CubeMX的配置就完成了,还有一点就是可以对PC13这个引脚起个别名, 这里起的别名是 LED_PC13,还有注意地方就是GPIO mode…...
ollama语言大模型部署使用
ollama语言大模型部署使用 前言一、下载安装maxkb1、下载解压赋权2、安装 二、安装ollamadocker运行 三、无需获取api_keymaxkb安装ollama模型对,就是这,你选好基础模型后,只需要给他地址,添加完成后自行调用ollama安装你选择好的…...
redis 基本数据类型—string类型
一、介绍 Redis 中的字符串,直接就是按照二进制数据的方式存储的,不会做任何的编码转换。 Redis对于 string 类型,限制了大小最大是512M 二、命令 SET 将 string 类型的 value 设置到 key 中。如果 key 之前存在,则覆盖&#…...
Git 使用教程:从入门到精通
Git 是一个开源的分布式版本控制系统,由 Linus Torvalds 创建,用于有效、高速地处理从小到大的项目版本管理。本教程将带你从 Git 的安装开始,逐步学习到如何使用 Git 进行日常的版本控制操作。 安装 Git Windows 访问 Git 官方网站 下载 …...
ES查询的一些优化方式
ES查询的一些优化方式 filter和query Query会计算得分,filte不是, 整体上query会更耗时 字段方式: KEYWORD 和 text, Text检索的方式往往会占用更多性能,它往往需要伴随着模糊匹配和分词 分页的大小 From 和size的大小合理设置…...
计算左边(比自己小的元素)的最长距离
前言:一般做的题目都是使用单调栈来求出距离这个点最近的那个比这个数大或小的元素,但是如果是需要找到最远的那个元素呢?我们可以用到类似逆序对的思路,我们先进行排序从小到大,接着我们先处理左边,每次维…...
【C++算法】二分查找
二分查找 题目链接 二分查找https://leetcode.cn/problems/binary-search/ 算法原理 代码步骤 代码展示 class Solution { public:int search(vector<int>& nums, int target) {int left 0, right nums.size() - 1;while(left < right){// 防止溢出int mid …...
红日靶场通关
初始准备 首先是网络配置,看教程来的,我配置完的效果如下 windows7:(内:192.168.52.143 / 外:192.168.154.136) windows2003:(内:192.168.52.141)windows2008:(内:192.…...
用Python爬虫制作一个简易翻译器
我们通常是通过requestsBS4的方法来获取网页内容,这种方法导入模块较多,速度相对有点儿慢,此时我们可以用requests的post方法向指定服务器发送请求,获取数据后格式化为json,然后获取相关键值。这种方法用到了requests和…...
Shader Graph Create Node
一、Artistic 1、Adjustment 1)、Channel Mixer(通道混合) 根据权重对每个通道进行混合。 Contrast(对比度) 可调整对比度 调整对比度可以改变图像的鲜明度和层次感。增加对比度会使图像中的明暗差异更加显著,使图像看起来更加清晰、明亮;减少对比…...
共模干扰的形成和滤除
1、共模就是共同对地的干扰: 如图,我们可以看到共模的原理图。UPQ就是共模电压,ICM1 ICM2 就是共模电流。 ICM1 ICM2 大小不一定相同,方向相同。 2、共模信号和差模信号的区别: 通常电源线有三根线:火线L、…...
(计算机网络)运输层
一.运输层的作用 运输层:负责将数据统一的交给网络层 实质:进程在通信 TCP(有反馈)UDP(无反馈) 二.复用和分用 三. TCP和UDP的特点和区别 进程号--不是固定的 端口号固定--mysql--3306 端口--通信的终点 …...
基于深度学习的信号滤波:创新技术与应用挑战
一、引言 1.1 研究背景 随着科技的不断发展,信号处理领域面临着越来越复杂的挑战。在众多信号处理技术中,基于深度学习的信号滤波技术逐渐崭露头角,成为研究的热点。 基于深度学习的信号滤波在信号处理领域具有至关重要的地位。如今&#…...
MFC工控项目实例之十一板卡测试信号输入界面
承接专栏《MFC工控项目实例之十添加系统测试对话框》 相关代码 1、在BoardTest.h文件中添加代码 class CBoardTest : public CDialog { // Construction public:CBoardTest(CWnd* pParent NULL); // standard constructorCButtonST m_btnStart[16];CWinThread* pThread…...
sql中索引查看是否生效
在pg数据库中有多种索引存在,在一般情况下我们取使用普通索引 以下是一些常见导致索引未命中的原因和优化策略 1.如果查询中的条件与索引字段的顺序不匹配,或者索引字段没有完全包含在查询条件中,索引可能不会被使用。 2.在查询中使用函数…...
SpringBoot常见面试题
1.请说一说Spring Boot的自动装配原理? SpringBootApplication EnableAutoConfiguration AutoConfigurationImportSelector组件 SpringFactoriesLoader读取 (1)META-INF/spring.factories 或者 (2)org.springframework…...
springboot优雅停机无法关闭进程,kill无法停止springboot必须kill -9,springboot线程池使用
背景最近项目在jenkins部署的时候发现部署很慢,查看部署日志发现kill命令执行后应用pid还存在,导致必须在60秒等待期后kill -9杀死springboot进程 应用环境 springboot <dependency><groupId>org.springframework.boot</groupId>&l…...
【系统架构设计师-2015年真题】案例分析-答案及详解
更多内容请见: 备考系统架构设计师-核心总结索引 文章目录 【材料1】问题1问题2【材料2】问题1问题2问题3【材料3】问题1问题2问题3【材料4】问题1问题2问题3【材料5】问题1问题2问题3【材料1】 阅读以下关于软件架构评估的说明,在答题纸上回答问题1和问题2。 【说明】某软件…...
MongoDB设置系统服务启动教程
1、编辑mongodb.service文件 将MongoDB设置成系统服务,就可以通过systemctl进行启动停止重启,在目录/etc/systemd/system下编写mongodb.service文件: [Unit] DescriptionMongoDB Database Server Documentationhttps://www.mongodb.com/docs…...
别再乱装CUDA了!用Anaconda为你的3060 Ti一键搞定PyTorch GPU环境(含CUDA 11.3实战)
3060 Ti显卡玩家的PyTorch环境配置指南:用Anaconda避开CUDA版本地狱 在深度学习领域,GPU加速已经成为提升模型训练效率的标配。然而,对于许多刚入门的开发者来说,配置PyTorch的GPU支持往往成为第一道门槛——尤其是当涉及到CUDA版…...
告别内置ADC的烦恼:用ADS1119搞定STM32/DSP的高精度电压采样(附完整代码)
告别内置ADC的烦恼:用ADS1119搞定STM32/DSP的高精度电压采样(附完整代码) 在嵌入式系统开发中,电压采样是基础却至关重要的环节。许多工程师在使用STM32或DSP内置ADC时,常会遇到精度不足、抗干扰能力差、无法测量差分信…...
告别Python依赖!手把手教你用C++复现Librosa的Mel频谱和MFCC特征提取
高性能C音频特征提取实战:从Librosa原理到嵌入式部署优化 在语音识别和音频分析领域,Mel频谱和MFCC特征提取是基础但关键的技术环节。许多开发者习惯使用Python的Librosa库快速实现原型,但当需要部署到生产环境时,Python的解释器性…...
5大优势解析:如何高效使用免费离线OCR工具
5大优势解析:如何高效使用免费离线OCR工具 【免费下载链接】Umi-OCR OCR software, free and offline. 开源、免费的离线OCR软件。支持截屏/批量导入图片,PDF文档识别,排除水印/页眉页脚,扫描/生成二维码。内置多国语言库。 项目…...
NVIDIA Profile Inspector深度解析:解锁显卡隐藏性能的实战指南
NVIDIA Profile Inspector深度解析:解锁显卡隐藏性能的实战指南 【免费下载链接】nvidiaProfileInspector 项目地址: https://gitcode.com/gh_mirrors/nv/nvidiaProfileInspector 你是否曾为游戏卡顿而烦恼?是否觉得显卡性能总差那么一点&#x…...
Copaw_dev:AI编程助手增强框架,提升代码生成与自动化开发效率
1. 项目概述:Copaw_dev 是什么,以及它为何值得关注如果你是一名开发者,尤其是对自动化、代码生成或者AI辅助编程感兴趣,那么“Copaw_dev”这个项目标题很可能已经引起了你的注意。乍一看,这个由“G-Divine”维护的项目…...
Obsidian智能模板终极指南:3步打造高效笔记自动化系统
Obsidian智能模板终极指南:3步打造高效笔记自动化系统 【免费下载链接】Templater A template plugin for obsidian 项目地址: https://gitcode.com/gh_mirrors/te/Templater Templater插件是Obsidian生态系统中功能最强大的智能模板解决方案,它能…...
飞书自动化开发实战:从脚本编写到事件驱动架构设计
1. 项目概述:飞书自动化,从“手动挡”到“自动驾驶”的进化 如果你每天的工作,有超过30%的时间是在飞书里重复着“点击-填写-发送”的枯燥操作,比如手动拉取数据生成日报、定时向群聊推送消息、或者根据特定条件审批流程…...
构建通用Docker工具镜像:从设计到实践的全流程指南
1. 项目概述:一个“反重力”的Docker镜像?看到这个镜像名runzhliu/docker-antigravity,很多人的第一反应可能是好奇和疑惑。在Docker Hub上,以“antigravity”(反重力)命名的镜像并不常见,它不像…...
Biomni项目解析:大语言模型与生物医学知识图谱融合实践
1. 项目概述:当大语言模型遇见生物医学知识图谱最近在探索如何让大语言模型(LLM)在专业领域,特别是生物医学这种信息密集、关系复杂的领域,变得更“靠谱”一点。相信很多同行都遇到过类似的问题:直接问Chat…...
