关于我对stm32看门狗的一些理解(基于正点原子)

关于我对stm32看门狗的一些理解(基于正点原子)咕咕咕之后想更会儿stm32哈哈哈,但是其实是之前自己写的笔记,想着以后就写在一起吧,我自己也更好去找到自己写的玩意~毕竟总所周知,博客都是写给自己的。(虽然好像现在自己都看不懂了我的天哪)一.什么是看门狗在stm32中,我们会学到独立看门狗和窗口看门狗的实验。第一眼肯定是一脸懵逼啊,啥是看门狗啊?看门狗在日常生活中,大概的印象就是,起到一个保证安全,防止外来人员搞事的作用。stm32中的看门狗也起着差不多的意思:看门狗就是起到一个监督单片机是否正在正常运行的作用。如果程序运行异常(跑飞),那么

大家好,又见面了,我是你们的朋友全栈君。

咕咕咕之后想更会儿stm32哈哈哈,但是其实是之前自己写的笔记,想着以后就写在一起吧,我自己也更好去找到自己写的玩意~毕竟总所周知,博客都是写给自己的。
(虽然好像现在自己都看不懂了我的天哪)

一.什么是看门狗

在stm32中,我们会学到独立看门狗和窗口看门狗的实验。第一眼肯定是一脸懵逼啊,啥是看门狗啊?

看门狗在日常生活中,大概的印象就是,起到一个保证安全,防止外来人员搞事的作用。

stm32中的看门狗也起着差不多的意思:

看门狗就是起到一个监督单片机是否正在正常运行的作用。如果程序运行异常(跑飞),那么让系统复位,程序重新执行。

看一下百科解释:

在由单片机构成的微型计算机系统中,由于单片机的工作常常会受到来自外界电磁场的干扰,造成程序的跑飞,而陷入死循环,程序的正常运行被打断,由单片机控制的系统无法继续工作,会造成整个系统的陷入停滞状态,发生不可预料的后果,所以出于对单片机运行状态进行实时监测的考虑,便产生了一种专门用于监测单片机程序运行状态的模块或者芯片,俗称“看门狗”(watchdog)

那么看门狗怎么去实现这些操作呢?再讨论这个之前,我们先来看看stm32中的看门狗有哪些?

1.两种看门狗

STM32F10xxx内置两个看门狗,提供了更高的安全性、时间的精确性和使用的灵活性。两个看门狗设备(独立看门狗和窗口看门狗)可用来检测和解决由软件错误引起的故障;当计数器达到给定的超时值时,触发一个中断(仅适用于窗口型看门狗)或产生系统复位。

独立看门狗(IWDG)

独立看门狗由专用的低速时钟(LSI)驱动,即使主时钟发生故障它也仍然有效。

IWDG最适合应用于那些需要看门狗作为一个在主程序之外,能够完全独立工作,并且对时间精度要求较低的场合。

窗口看门狗(WWDG)

窗口看门狗由从APB1时钟分频后得到的时钟驱动,通过可配置的时间窗口来检测应用程序非正常的过迟或过早的操作。

WWDG最适合那些要求看门狗在精确计时窗口起作用的应用程序。

但是单独看这个确实。。。有点迷,就有点印象哈。

但是大概应该也对看门狗有了一点概念,至少你知道了有两种看门狗。

那么我们现在详细来介绍一下独立看门狗(窗口看门狗留在下一个主题)

2.独立看门狗

之前看独立看门狗的介绍,我们知道他由一个专门的时钟驱动

这里给出更详细的介绍一下:

STM32 的独立看门狗由内部专门的 40Khz 低速时钟驱动,即使主时钟发生故障,它也仍然有效。这里需要注意独立看门狗的时钟是一个内部 RC 时钟,所以并不是准确的 40Khz,而是在 30~60Khz 之间的一个可变化的时钟,只是我们在估算的时候,以 40Khz 的频率来计算,看门狗对时间的要求不是很精确,所以,时钟有些偏差,都是可以接受的。

我们这里可以理解为:他在主程序之外工作,可以监视主程序是否正常运行。

ok,那么他是怎么工作的?

先简单一点:

独立看门狗可以先设置一个时间(比如1s),如果超过这个时间,那么就代表主程序出了异常,然后让系统复位,程序重新执行。–在这里这个时间的流逝我们理解成一个倒计时

但是很多时候主程序本身就是一个死循环–肯定运行不止1s啊

于是我们需要在主程序之中重置这个时间(倒计时重新开始),如果主程序出现了问题—那么倒计时无法重置,但是我们的看门狗任然在运行,最终超过时间,看门狗让系统复位,程序重新执行。

我觉得我大概是理解了。。。

那么怎么去开启看门狗,又怎么去重置时间呢?

身为单片机—那只能用相关的寄存器去操作了

二.独立看门狗相关寄存器

咱先不去分析单独的寄存器啊,先去直接上框图:

img

先总体把握一下:这里我觉得官方说的就很好:

在键寄存器(IWDG_KR)中写入0xCCCC,开始启用独立看门狗;此时计数器开始从其复位值0xFFF递减计数。当计数器计数到末尾0x000时,会产生一个复位信号(IWDG_RESET)。

无论何时,只要在键寄存器IWDG_KR中写入0xAAAA, IWDG_RLR中的值就会被重新加载到计数器,从而避免产生看门狗复位 。

其实这里也就是看门狗原理的实现,倒计时就是计数器计数到末尾的时间

并且应该注意一下的是–

IWDG_PR和IWDG_RLR寄 存 器 具 有 写 保 护 功 能 。

要 修 改 这 两 个 寄 存 器 的 值 , 必 须 先 向IWDG_KR寄存器中写入0x5555。

以不同的值写入这个寄存器将会打乱操作顺序,寄存器将重新被保护。

重装载操作(即写入0xAAAA)也会启动写保护功能。

那先看一下键寄存器:

1.键寄存器(IWDG_KR)

img

但是我们会发现键寄存器其实只是写这三个值–那怎么自己设置时间呢?

所以主要看另外两个寄存器了–IWDG_PRIWDG_RLR

2.设置倒计时的两个寄存器–**IWDG_PR,**IWDG_RLR

先看图吧

img

img

ok,重点都标出来了,但是好像看了跟没看一样

再结合一下公式:

*Tout=(4*2^prer)rlr / 40 ms

(其中prer是IWDG_PR寄存器2进制化为十进制的值,rlr就是IWDG_RLR中的值)

Tout就是看门狗每次的倒计时T

公式的推导参考:https://blog.csdn.net/qq_37957854/article/details/105644138

所以通过对两个寄存器写入,我们就可以设置倒计时了—不要忘了写入之前的操作

还有一个寄存器来着。。这个就看一下就行:

3.状态寄存器(IWDG_SR)

状态寄存器指示预分频值和递减计数器是否正在被更新。

img

疑问:这个寄存器需要我们自己操作吗?

三.看门狗相关库函数讲解

1.看门狗相关库函数

void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess);

//取消写保护:0x5555使能

void IWDG_SetPrescaler(uint8_t IWDG_Prescaler);

//设置预分频系数:写PR

void IWDG_SetReload(uint16_t Reload);

//设置重装载值:写RLR

void IWDG_ReloadCounter(void);

//喂狗:写0xAAAA到KR

void IWDG_Enable(void);

//使能看门狗:写0xCCCC到KR

FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG);

//状态:重装载/预分频 更新


大概有些印象就行

几乎传入的参数也全都是具体的数值–分别就是设置那几个寄存器的值

我们现在直接看实验,首先是实验的目的:

2.实验目的

我们会在main.c函数中创建主程序:

开始实验后,先延迟一会,然后让一个LED亮起。

并在死循环中设置–如果按下按键,那么喂狗。

一般情况下应该就是直接喂狗,这里是为了检验看门狗,就显得很不符合常理

如果不按下按键,那么就不会喂狗,也就是说—程序会一直重启,LED呈现闪烁的效果

如果按时按下按键,程序开始喂狗,那么程序不会重启,LED灯常亮

3.开始写代码(源码分析)–运行看门狗步骤

ps:这里不分析在哪个文件,直接分析函数和代码

首先还是得

启动看门狗(初始化)

void IWDG_Init(u8 prer,u16 rlr) 
{ 
   	
 	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);  //使能对寄存器IWDG_PR和IWDG_RLR的写操作
	
	IWDG_SetPrescaler(prer);  //设置IWDG预分频值:设置IWDG预分频值为64
	
	IWDG_SetReload(rlr);  //设置IWDG重装载值
	
	IWDG_ReloadCounter();  //按照IWDG重装载寄存器的值重装载IWDG计数器
	
	IWDG_Enable();  //使能IWDG
}

首先就是这个init函数的两个参数,表明自己没有设置rlr和prer,

要我们在初始化的时候自己设置**(自己设置倒计时)**

主体上:

    • 先解除对两个寄存器的写操作,
    • 然后再分别设置寄存器,
    • 并重新加载一遍两个寄存器—这里的代码是 *IWDG_ReloadCounter();* (这里可以留意一下吧)
    • 最后让看门狗开始执行。

然后

在main函数里面

 int main(void)
 { 
   	
 
	delay_init();	    	 //延时函数初始化 
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2 
	uart_init(9600);	 //串口初始化为9600
	LED_Init();		  	 //初始化与LED连接的硬件接口 
  KEY_Init();          //按键初始化 
	delay_ms(300);   	 //让人看得到灭
	IWDG_Init(4,625);    //与分频数为64,重载值为625,溢出时间为1s 
	LED0=0;				 //点亮LED0
	while(1)
	{ 
   
		if(KEY_Scan(0)==WKUP_PRES)IWDG_ReloadCounter();	//如果WK_UP按下,则喂狗
		delay_ms(10);
	};
}

就两个操作和看门狗有关

第10行,引用初始化函数 并引入两个需要的数值— 套公式(寄存器的文章里面)

第14行 喂狗

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/145930.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 拓扑图怎么看_拓扑排序算法图解

    拓扑图怎么看_拓扑排序算法图解一条单向的铁路线上,依次有编号为 1, 2, …, n 的 n 个火车站。每个火车站都有一个级别,最低为 1 级。现有若干趟车次在这条线路上行驶,每一趟都满足如下要求:如果这趟车次停靠了火车站 x,则始发站、终点站之间所有级别大于等于火车站 x 的都必须停靠。(注意:起始站和终点站自然也算作事先已知需要停靠的站点)例如,下表是 5 趟车次的运行情况。其中,前 4 趟车次均满足要求,而第 5 趟车次由于停靠了 3 号火车站(2 级)却未停靠途经的 6 号火车站(亦为 2 级)而不满足要求。现有 m

  • Android IBinder的linkToDeath介绍及情景模拟

    最近查看Framework源码的时候,读到了AudioService处理音量的流程,在这里碰到了IBinder的linkToDeath()这个知识点,比较感兴趣,所以记录下来,并自己写demo尝试了一下。我们简单来看下AudioService处理静音这一块。/frameworks/base/media/java/android/media/AudioManager.javapublicclas

  • java文件上传总结[通俗易懂]

    java文件上传总结[通俗易懂]前言文件上传是各类应用中经常碰到的需求,不管是上传图片、文件、音频、视频等,或者其他类型的文件,都是后端需要解决的,采用什么样的方式进行上传,或者对上传后的文件如何进行存储,甚至如何更加高效的上传文件等问题,都是在实际开发中需要解决的,本文将对常用的文件上传使用进行一下简单的小结以springboot为例,下面我们就开始撸码吧,开工前我们还是做一下简单的准备吧,本文的演示demo框架为springboot2.2.1版本,只需简单引入一个下面的依赖即可,其他需要用到的,我们增量添加即可 <de

  • windows下查看dns缓存和刷新缓存

    windows下查看dns缓存和刷新缓存

  • iis 启动不了,提示发生意外错误0x8ffe2740 解决最好方法 心得

    iis 启动不了,提示发生意外错误0x8ffe2740 解决最好方法 心得最近总出来两个错误1。每次启动IIS时,总报 “外错误0x8ffe2740 ”2。打开Vs.net2003时,又出来什么目前Asp.net不是1.1什么的。总之不能运行。查www.google.com发现  IIS的错误是因为80端口被占用的缘故。网上侠客,只是说先改IIS的端口。解决最好方法:A)我用“FPort.exe”找到占用端口的程序。B)然后将它

  • google软件测试之道_gtest测试框架

    google软件测试之道_gtest测试框架gtest提供了一套优秀的C++单元测试解决方案,简单易用,功能完善,非常适合在项目中使用以保证代码质量。

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号