STM32-WWDG/IWDG看门狗

 WWDG/IWDG一旦开启不能关闭,可通过选项字节在上电时启动硬件看门狗,看门狗计数只能写入不能读取。看门狗启用时,T6bit必须置1,防止立即重置。

一、原理

独立看门狗-超时复位

窗口看门狗-喂狗(重置计数器,计数器最大12Bit,2^{12}-1 = 4095)早了或者晚了都复位

1、IWDG结构

 键寄存器负责键入重装载值,这个值是之前配置好的,每次喂狗会自动通过键寄存器使重装载寄存器的数值键入递减计数器。看门狗位于VDD供电区,所以在停机和待机模式时可以正常使用。

 2、IWDG超时时间计算公式

超时频率 = Fiwdg = Flsi(LSI频率)/PR预分频系数/(RL+1)。

默认Tlsi=40khz,频率=1/40000=0.025ms。分频后时间增加。只有固定的分频系数,若为2(分频16)。若RL=99,则为0.025ms*16 = 0.4ms*100 = 40ms。

表格内说明:例如第一行4分频,

Tiwdg = 0.025ms*4*(RL=0x000,最短时间)1 = 0.1ms

Tiwdg = 0.025ms*4*(RL=0xFFF,最长时间)4096= 409.6ms

3、WWDG结构

WDGTB同独立看门狗的PR和定时器的PSC都是预分频器。

WWDG_CR相当于把独立看门狗的计数器、KR(控制寄存器)合二为一了。没有重装寄存器,在直接在CNT写入数据即可(6bit递减计数器,T5-T0,T6为溢出标志位(为1表示没有溢出,为0时表示计数器溢出,例如从111 1111->100 0000 -0x40时在减一 -> 011 1111表示溢出),若将T6位当作计数器的一部分,那么减到0x40开始溢出。若把第六位当作计数器,那么位第六位减到0溢出)。

CFR为喂狗的最早时间界限。WDGA窗口看门狗使能。

工作流程:PCLK1提供时钟APB1(36MHz),通过WDGA使能窗口看门狗,当WWDG_CR减到0时溢出,提供复位信号。或者当写入WWDG_CR时,WWDG_CR喂狗时的剩余的计数值>WWDG_CFR配置寄存器,提供复位信号。即限制了最早喂狗时间值。

4、WWDG工作特征

 早期唤醒中断(EWI即死前复位),通过该中断提醒用户看门狗即将复位。可以做一些操作。

看门狗时序图显示了可刷新重装载看门狗时间的时间范围(W[6,0]>T[6,0]>0x3F)。

 5、WWDG时间计算公式

Tpclk1 = 0.028us。Tpclk1提供的时钟先进性了4096分频,所以要×4096=114.688us。114.688us×2^WDGTB×(T[5:0]+1)为超时时间根据表格可以查看最大超时时间和最小超时时间。

超时时间计算直接通过T[5,0],当T[5,0]递减到0溢出。窗口超时时间是指,窗口CFR寄存器所表示的最低喂狗时间,当T[5,0]>W[5,0]喂狗时的复位时间。即复位时间 :超时时间>正常喂狗时间>窗口时间。2^6bit最大为63。

6、WWDG/IWDG的差别

 窗口看门狗的递减计数器未使能也会一直递减。所以需要使能时进行喂狗。

二、实际程序

1、独立看门狗,超时复位

程序烧写入可以看到,程序正常执行,OLED不断显示喂狗操作,按下复位按键可以看到显示RET复位。

通过按住PB11按键(图中按钮接在PB11和地,和图上不一样)按住不停,使软件停在检测按键内。看门狗超时后OLED显示WWDGRET表示独立看门狗超时。

 

无需手动打开LSI 

测试方式:

1、不进行按键按下操作,此时应该能正常喂狗,OLED显示 IWDG_Reload。

2、持续按下PB11按键,此时应该不能正常喂狗,OLED显示 IWDG RST,表示看门狗复位。

3、STM32按键复位,可以看到OTHER RST,说明复位显示正常。

 main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "MyIWDG.h"
#include "Button.h"
int main(void){
	OLED_Init();
	ButtonPB11_Init();
	
	OLED_ShowString(1,1,"IWDG TEST:");//
	
	if(RCC_GetFlagStatus(RCC_FLAG_IWDGRST) == SET){//判断是否是独立看门狗复位,该寄存器每次不会被清除
		OLED_ShowString(2,1,"IWDG RST");//显示看门狗复位
		Delay_ms(500);
		OLED_ShowString(2,1,"        ");
		RCC_ClearFlag();
	}else{//其他复位
		OLED_ShowString(2,1,"OTHER RST");//显示其他复位
		Delay_ms(500);
		OLED_ShowString(2,1,"         ");
	}
	
	MyIWDG_Init();//看门狗初始化 1000ms
	
	while(1){
		GetButtonPB11();//使用按钮延时来模拟程序异常
		
		IWDG_ReloadCounter();//喂狗
		OLED_ShowString(3,1,"IWDG_Reload");//显示喂狗操作
		Delay_ms(600);
		OLED_ShowString(3,1,"           ");
		Delay_ms(200);
	}
	
	return 0;
}

 MyWWDG.c

#include "stm32f10x.h"                  // Device header

void MyIWDG_Init(void){
	
	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
	
	//我们需要超时1s复位,根据手册选择最小16分频,充分利用寄存器防止除数有误差
	IWDG_SetPrescaler(IWDG_Prescaler_16);
	
	//根据公式:重装值 = ( 1000ms / Tlsi(4KHz = 0.025ms) / PR预分频数(16) )-1
	IWDG_SetReload(2499);
	
	IWDG_ReloadCounter();//重装值装载
	IWDG_Enable();//独立看门狗启动
	
}











 MyWWDG.h

#ifndef __MYIWDG_H
#define __MYIWDG_H
#include "stm32f10x.h"                  // Device header


void MyIWDG_Init(void);

#endif

 Button.c

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


/**
  * @brief 初始化引脚PB11地开信号接收Button,用于辅助测试看门狗
  * @param  
  *     @arg 
  * @param  
  *     @arg 
  * @retval None
  */
void ButtonPB11_Init(void){
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	
	GPIO_InitTypeDef  GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
}


/**
  * @brief 获取PB11的Button是否按下
  * @param  
  *     @arg 
  * @param  
  *     @arg 
  * @retval None
  */
uint8_t GetButtonPB11(void){
	if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11) == RESET){
		Delay_ms(20);
		while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11) == RESET);
		Delay_ms(20);
		return 1;
	}
	return 0;
}

Button.h

#ifndef __BUTTON_H
#define __BUTTON_H
#include "stm32f10x.h"                  // Device header

uint8_t GetButtonPB11(void);
void ButtonPB11_Init(void);

#endif

 

2、窗口看门狗,超时或提前都会复位。

读改写操作的优点:

1、可以单独改变寄存器的某几位,而不影响其他寄存器的值。

2、如果连续修改多次不同/相同的位,操作效率比较高。

3、所有更改的位,最终写回到寄存器时同时生效

程序测试方式:

1、将while内延时程序时间改成小于17ms,可以看到有窗口时间复位。

2、将while内延时程序时间改成大于35ms,可以看到有超时时间复位。

3、将while内延时程序时间改成(17,35),可以看到持续喂狗,没有复位产生。

4、通过STM32复位按键可以看到复位正常。通过按键持续按住PB11按键可以看到,持续产生窗口看门狗复位。

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "MyWWDG.h"
#include "Button.h"
int main(void){
	OLED_Init();
	ButtonPB11_Init();
	
	OLED_ShowString(1,1,"WWDG TEST:");//
	
	if(RCC_GetFlagStatus(RCC_FLAG_WWDGRST) == SET){//判断是否是独立看门狗复位,该寄存器每次不会被清除
		OLED_ShowString(2,1,"WWDG RST");//显示看门狗复位
		Delay_ms(500);
		OLED_ShowString(2,1,"        ");
		RCC_ClearFlag();
	}else{//其他复位
		OLED_ShowString(2,1,"OTHER RST");//显示其他复位
		Delay_ms(500);
		OLED_ShowString(2,1,"         ");
	}
	
	MyWWDG_Init();//窗口看门狗初始化 超时时间50ms,窗口时间30ms
	
	while(1){
		GetButtonPB11();//使用按钮延时来模拟程序异常
		OLED_ShowString(3,1,"WWDG_Reload");//显示喂狗操作
		Delay_ms(20);
		OLED_ShowString(3,1,"           ");
		Delay_ms(15);
		WWDG_SetCounter(0x40 | 54);//喂狗
		/*
		经测试本程序和个人的硬件,
		窗口时间30ms,但是使用延时小于17ms就会触发窗口时间复位。
		超时时间50ms,但是使用延时大于35ms就会触发超时时间复位。
		说明其他程序延时可以达到13ms-15ms。
		
		也可注释所有程序,使用延时测试,经测试窗口时间30ms,超时时间50ms无异常。
		*/
	}
	
	return 0;
}

 MyWWDG.c

#include "stm32f10x.h"                  // Device header

void MyIWDG_Init(void){
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE);//开启窗口看门狗时钟
	
	WWDG_SetPrescaler(WWDG_Prescaler_8);//设置预分频
	
	/*设置窗口时间30ms
	计算公式为:Twin = Tpclk1*4096*WWDGpcs*(T[5:0]-W[5:0])。
	带入T[5:0] = 55 , Tpclk1 = 36MHz = 0.028us , WWDGpcs = 8 
	得到30ms = 917.504us*(55-W[5:0]) ; 54-W[5:0]=32.7 ;W[5:0]= 21.3。
	*/
	WWDG_SetWindowValue(0x40 | 21);//设置窗口时间,也需要|0x40,因为电路中对比超时时间和窗口时间使用的T[6:0]>W[6:0]
	
	/*
	超时时间是50ms
	计算公式为:Twwdg = Tpclk1(36MHz = 0.028us)*4096*WWDGpcs(8)*(T[5:0]-1)。
	50ms = 917.504us*(T[5:0]-1),T[5:0]=53.5=54。
	T6溢出位位2^7=64 = 0x40。T7使能位函数自动置位。所以需要输入64+54=0x76=0x40 | 54
	*/
	WWDG_Enable(0x40 | 54);//设置超时时间,在使能时需要同时设置(溢出位也要置1  0x40),因为窗口看门狗递减计数器为自由递减,不使能也会递减
	
	
}



MyIWDG.h

#ifndef __MyIWDG_H
#define __MyIWDG_H
#include "stm32f10x.h"                  // Device header

void MyIWDG_Init(void);


#endif



 Button.c

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


/**
  * @brief 初始化引脚PB11地开信号接收Button,用于辅助测试看门狗
  * @param  
  *     @arg 
  * @param  
  *     @arg 
  * @retval None
  */
void ButtonPB11_Init(void){
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	
	GPIO_InitTypeDef  GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
}


/**
  * @brief 获取PB11的Button是否按下
  * @param  
  *     @arg 
  * @param  
  *     @arg 
  * @retval None
  */
uint8_t GetButtonPB11(void){
	if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11) == RESET){
		Delay_ms(20);
		while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11) == RESET);
		Delay_ms(20);
		return 1;
	}
	return 0;
}

Button.h

#ifndef __BUTTON_H
#define __BUTTON_H
#include "stm32f10x.h"                  // Device header

uint8_t GetButtonPB11(void);
void ButtonPB11_Init(void);

#endif

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于JAVA+SSM的车辆运输管理

基于JAVASSM的车辆运输管理 前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末附源码下载链接🍅 哈喽兄弟们&#…

【Linux系列】Vim 编辑器中的高效文本编辑技巧:删除操作

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

win10 VS2019上libtorch库配置过程

win10 VS2019上libtorch库配置过程 0 引言1 获取libtorch2 在VS上配置使用libtorch库3 结语 0 引言 💻💻AI一下💻💻   libtorch库是一个用于深度学习的C库,是PyTorch的官方C前端。它提供了用于构建和训练深度学习模…

通过gradle发布aar或jar携带sources-jar到maven nexus

找了很久,没有找到满意的。终于找到一个好的办法。 gradle7.x适用。比以前的写法简洁。 发布传统的jar工程 比如okhttp,fastjson等项目,纯java工程。 直接创建新文件publish.gradle: apply plugin: maven-publishProperties properties …

STM32-笔记38-I2C-oled实验

一、什么是I2C? I2C总线,全称Inter-Integrated Circuit(互连集成电路),是一种由Philips(现NXP半导体)公司在1980年代初开发的同步 串行 半双工通信总线。 二、有了串口通信为什么要使用I2C&…

【Linux系列】并发与顺序执行:在 Linux 脚本中的应用与选择

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

“AI 视频图像识别系统,开启智能新视界

咱老百姓现在的生活啊,那是越来越离不开高科技了,就说这 AI 视频图像识别系统,听起来挺高大上,实际上已经悄无声息地融入到咱们日常的方方面面,给咱带来了超多便利。 先讲讲安防领域吧,这可是 AI 图像识别的…

Burpsuite20241102macM1版安装

1、安装jdk11 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" brew update brew install openjdk11 echo export PATH"/opt/homebrew/opt/openjdk11/bin:$PATH" >> ~/.zshrc source ~/.zshrc j…

NVIDIA在CES 2025上的三大亮点:AI芯片、机器人与自动驾驶、全新游戏显卡

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

PDFMathTranslate: Star13.8k,一款基于AI的PDF文档全文双语翻译PDF文档全文双语翻译,保留格式神器,你应该需要它

嗨,大家好,我是小华同学,关注我们获得“最新、最全、最优质”开源项目和高效工作学习方法 PDFMathTranslate是一个开源项目,旨在为用户提供便捷的PDF科学论文翻译解决方案。它不仅能够翻译文本,还能保留公式、图表、目…

h264之多视点mvc编码及解码过程(JMVC平台举例)

h264标准参考平台JMVC是针对MVC标准的,JMVC支持多视点编码、合流、多视点解码操作。可以利用JMVC生成h264 mvc码流和解码。 JMVC的下载地址是:jvet / JMVC GitLabH.264/AVC multi-view coding (MVC) extension JMVC reference softwarehttps://vcgit.hh…

LabVIEW软件侵权分析与应对

问:如果涉及到LabVIEW软件的仿制或模仿,特别是在功能、界面等方面,如何判断是否构成侵权?该如何应对? 答:LabVIEW软件的侵权问题,尤其是在涉及到仿制或模仿其功能、界面、设计等方面&#xff0…

条款07:为多态基类声明virtual析构函数

1.工厂方法举例&#xff1a;多态基类析构函数不声明为virtual会发生什么 #include <iostream> using namespace std;class Base { public:~Base(){} };class Box :public Base { public:const static int s_i 0; };class Box1 :public Base { public:const static int …

【C++】字符数|组输入与处理全解析

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af;1. 基础方法&#xff1a;scanf 和 cin 的使用1.1 使用 scanf 实现简单字符串输入示例代码行为分析示例输入与输出优缺点改进建议 1.2 使用 cin 实现字符串输入示例代码行为…

Python爬虫教程——7个爬虫小案例(附源码)_爬虫实例

本文介绍了7个Python爬虫小案例&#xff0c;包括爬取豆瓣电影Top250、猫眼电影Top100、全国高校名单、中国天气网、当当网图书、糗事百科段子和新浪微博信息&#xff0c;帮助读者理解并实践Python爬虫基础知识。 包含编程资料、学习路线图、源代码、软件安装包等&#xff01;【…

apex安装

安装过程复杂曲折&#xff0c;网上说的很多办法&#xff0c;貌似成功了&#xff0c;实际还是没起作用。 先说成功过程&#xff0c;执行下面命令&#xff0c;安装成功&#xff08;当然&#xff0c;前提是你要先配置好编译环境&#xff09;&#xff1a; &#xff08;我的环境&a…

谷粒商城-高级篇-Sentinel-分布式系统的流量防卫兵

1、基本概念 1.1、熔断降级限流 1、什么是熔断 A 服务调用 B 服务的某个功能&#xff0c;由于网络不稳定问题&#xff0c;或者 B 服务卡机&#xff0c;导致功能时间超长。如果这样子的次数太多。我们就可以直接将 B 断路了&#xff08; A 不再请求 B 接口&#xff09;&#…

Django的runserver

当年执行 python manage runserver命令时 1. 先执行 runserver 中的 handle方法 2. 执行 self.run()方法 3. 执行 self.inner_run() 3.1 inner_run 下 run方法的封装 3.1.1 接着看 handle 怎么来的 封装了一个方法 接着找返回函数 3.1.2在 basehttp 下 3.1.3 get_wsgi_appl…

MySQL 如何赶上 PostgreSQL 的势头?

原文地址 我与 MySQL 社区的前辈交谈时&#xff0c;经常遇到这个问题&#xff1a;「为什么 MySQL 这么棒&#xff0c;而且&#xff08;至少根据 DB-Engines 的计算&#xff09;仍然比 PostgreSQL 更流行&#xff1b;但它的地位在下降&#xff0c;PostgreSQL 却势不可挡地越来越…

微信小程序中的 storage(本地存储)和内存是两个完全不同的存储区域

这是一个非常关键且容易混淆的概念 既然 this.globalData.appId appId 是将 appId 存储在内存中&#xff0c;为什么微信小程序中的 wx.getStorage 和 wx.setStorage&#xff08;本地存储&#xff09;中没有 appId&#xff0c;并且您提出了一个非常重要的疑问&#xff1a;stor…