STM32F103五分钟入门系列(十三)独立看门狗IWDG

参考:STM32F103五分钟入门系列(十三)独立看门狗IWDG
作者:自信且爱笑‘
发布时间:2021-07-31 19:50:28
网址:https://blog.csdn.net/Curnane0_0/article/details/119269391?utm_source=app&app_version=4.12.0&code=app_1562916241&uLinkId=usr1mkqgl919blen

参考:STM32 独立看门狗实验
作者:追兮兮
发布时间: 2020-12-25 10:14:21
网址:https://blog.csdn.net/weixin_44234294/article/details/111661281

学习板:STM32F103ZET6

独立看门狗

  • 一、独立看门狗(IWDG)简介
    • 1、什么是看门狗
    • 2、独立看门狗应用场合
  • 二、独立看门狗时钟
  • 三、独立看门狗的相关寄存器
    • (1)键寄存器(IWDG_KR)
    • (2)预分频寄存器(IWDG_PR)
    • (3)重装载寄存器(IWDG_RLR)
    • (4)状态寄存器(IWDG_SR)
  • 四、独立看门狗编程顺序
  • 五、例子(寄存器版)
  • 六、独立看门狗常用库函数
    • (1)取消PR、RLR寄存器写保护函数IWDG_WriteAccessCmd()
    • (2)设置分频因子函数IWDG_SetPrescaler()
    • (3)设置重装载值函数IWDG_SetReload()
    • (4)重装载初值函数(喂狗)IWDG_ReloadCounter
    • (5)启动独立看门狗函数IWDG_Enable()
    • (6)独立看门狗状态获取函数IWDG_GetFlagStatus()
  • 七、例子(库函数版)

一、独立看门狗(IWDG)简介

1、什么是看门狗

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

首先我们得讲解一下看门狗的原理。这个百度百科里面有很详细的解释。我们总结一下:单片机系统在外界的干扰下会出现程序跑飞的现象导致出现死循环,看门狗电路就是为了避免这种情况的发生。看门狗的作用就是在一定时间内(通过定时计数器实现)没有接收喂狗信号(表示 MCU 已经挂了),便实现处理器的自动复位重启(发送复位信号)。

总结:看门狗是为了避免程序跑飞而设置的,在程序正常运行情况下,会一直“喂狗”,使程序不会复位。可以这样理解:在一个定时器中断中,中断服务函数里是整个程序的复位,在定时器之外,会一直给定时器重装载初值(相当于喂狗),程序一直执行正常的话,定时器不会发生中断,即不会进入中断服务函数,不会执行复位程序;当程序跑飞时,由于没有“喂狗”,定时器计数到0(如向下计数时),发生中断,执行中断服务函数里的复位程序,程序重新开始执行。

2、独立看门狗应用场合

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

二、独立看门狗时钟

在这里插入图片描述

从时钟框图可以看到,看门狗的时钟为内部低速时钟40KHZ,我们知道LSI和HSI都是有内部RC振荡电路生成的,输出不稳定,所以这个时钟大约为40KHZ,并不精准。

三、独立看门狗的相关寄存器

(1)键寄存器(IWDG_KR)

在这里插入图片描述

该寄存器是低16位有效的32位寄存器。从上图得到以下信息:

①IWDR_KR寄存器是只写寄存器
②IWDR_KR写入0XAAAA,才算“喂狗”,且一定时间间隔必须写入,否则程序复位
③IWDR_KR写入0X5555表示允许访问IWDG_PR和IWDG_RLR寄存器,未写入时这两个寄存器处于保护状态,无法进行写操作
④IWDR_KR写入0XCCCC,启动看门狗

所以一般程序可以如下:

	IWDG->KR=0x5555;//取消IWDG_PR和IWDG_RLR寄存器保护IWDG->PR=   //设置这俩个寄存器IWDG->RLR=IWDG->KR=0xAAAA;//开始时给重装载寄存器装载初值IWDG->KR=0xCCCC;//启动看门狗//程序中喂狗(程序其它地方)IWDG->KR=0xAAAA;//喂狗
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

(2)预分频寄存器(IWDG_PR)

在这里插入图片描述

该寄存器是只有低3位有效的32位寄存器,之前的IWDG_KR寄存器中也强调过,要对IWDG_PR寄存器操作,必须先对IWDG_KR写入0x5555。

我们知道,独立看门狗的时钟是40KHZ的LSI,经过本寄存器设置预分频系数后,独立看门狗的时钟会变为40KHZ/预分频因子。

(3)重装载寄存器(IWDG_RLR)

在这里插入图片描述

该寄存器并不像SysTick定时器的重装载寄存器一样,该寄存器不需要手动装载初值,只需设置好装载值后,每次给IWDG_KR寄存器写入0xAAAA,即可装载初值。

(4)状态寄存器(IWDG_SR)

在这里插入图片描述

该寄存器只有位0和位1有效,位0指示预分频值更新、位1指示重装载值更新;置1时表示正在更新,置0时表示更新完成。

通过该寄存器还可以获取目前看门狗装载值、预分频器更新状态:

while(IWDG->SR|0x00000002)
{}//重装载值更新中f(!(IWDG->SR|0x00000002))
{}//重装载值更新完成
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

四、独立看门狗编程顺序

①取消寄存器写保护(向 IWDG_KR 写入 0X5555)

②设置独立看门狗的预分频系数和重装载值(IWDG_PR和IWDG_PLR)

③重载计数值喂狗(向 IWDG_KR 写入 0XAAAA)

④启动看门狗(向 IWDG_KR 写入 0XCCCC)

⑤程序的其他地方喂狗(向 IWDG_KR 写入 0XAAAA)

五、例子(寄存器版)

例:按下KEY_UP后,喂狗,正常状态下,LED0处于亮灯状态。(当没有喂狗时,程序被复位,此时LED0会灭了再被点亮)

LED和KEY的代码之前总结过了,可以详见:STM32F103五分钟入门系列(五)按键实验(库函数+寄存器)

这里直接附代码:

//led.h
#ifndef LED_H
#define LED_H
void LED_Init(void);#endif
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
//led.c
#include "sys.h"
#include "stm32f10x.h"
#include "led.h"
void LED_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct_B;GPIO_InitTypeDef GPIO_InitStruct_E;RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE ,ENABLE);GPIO_InitStruct_B.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_InitStruct_B.GPIO_Pin=GPIO_Pin_5;GPIO_InitStruct_B.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOB,&GPIO_InitStruct_B);GPIO_InitStruct_E.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_InitStruct_E.GPIO_Pin=GPIO_Pin_5;GPIO_InitStruct_E.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOE,&GPIO_InitStruct_E);GPIO_SetBits(GPIOB, GPIO_Pin_5);//PB5置高电平//GPIO_WriteBit(GPIOB, GPIO_Pin_5,1);//GPIO_Write(GPIOB,0x0020);              //慎用//PBout(5)=1;GPIO_SetBits(GPIOE, GPIO_Pin_5);//PE5置高电平//GPIO_WriteBit(GPIOE, GPIO_Pin_5,1);//GPIO_Write(GPIOE,0x0020);              //慎用//PEout(5)=1;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
//key.h
#ifndef KEY_H
#define KEY_H
void KEY_Init(void);
#endif
  • 1
  • 2
  • 3
  • 4
  • 5
//key.c
#include "stm32f10x.h"
#include "sys.h"
#include "key.h"
void KEY_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct_A;GPIO_InitTypeDef GPIO_InitStruct_E;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE , ENABLE);//使能GPIOA和GPIOE(PA0 PE2、3、4)GPIO_InitStruct_A.GPIO_Mode=GPIO_Mode_IPD;GPIO_InitStruct_A.GPIO_Pin=GPIO_Pin_0 ;GPIO_InitStruct_A.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStruct_A);//PA0 key_up  下拉输入GPIO_InitStruct_E.GPIO_Mode=GPIO_Mode_IPU;GPIO_InitStruct_E.GPIO_Pin=GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;GPIO_InitStruct_E.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOE, &GPIO_InitStruct_E);//PE2、3、4 key0、key1、key2 上拉输入GPIO_SetBits(GPIOE,GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4);GPIO_ResetBits(GPIOA, GPIO_Pin_0);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

接下来写独立看门狗实验,寄存器版比较简单

首先看一下预分频系数和重装载值怎么搞。

LSI约为40KHZ,就当它是准确的40KHZ,预分频系数为4、8、16…
如预分频系数为16时,设置1s喂狗。

则独立看门狗时钟为40kHZ/16,,每计数一次的时间:16/40ms,则1s需要计数:40000/16=2500;所以可以设置:

分频系数为16,即IWDG_PR寄存器的值为010,即0x02
重装载初值为2500,即IWDG_RLR寄存器的值为:2500

需要注意的是,重装载值寄存器IWDG_RLR只有低12位有效,所以最大重装载值为:2^12-1=4095

mian.c中代码:

//main.c
#include "stm32f10x.h"
#include "led.h"
#include "key.h"
#include "sys.h"
#include "delay.h"int main(void){	KEY_Init();LED_Init();delay_init();delay_ms(500);//为了看到程序复位PBout(5)=0;//点亮LED0IWDG->KR=0x5555;//取消IWDG_PR和IWDG_RLR寄存器保护IWDG->PR=0x02;IWDG->RLR=2500;//设置分频系数和重装载值//正常操作应该是先位与运算清空寄存器,再位或运算赋值IWDG->KR=0xAAAA;//初始状态下,装载初值IWDG->KR=0xCCCC;//启动看门狗while(1){if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0))//检测key_up按下{IWDG->KR=0xAAAA;//喂狗}}}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

上述程序需要注意的是一定要延时一个时间,否则没有喂狗导致程序重新执行,但是LED灭一下,根本看不出变化。

通过上述代码,下载调试后发现:在KEY_UP未按下时,LED0每亮1s,灭0.5s,当长按KEY_UP时,LED0保持常亮状态。

六、独立看门狗常用库函数

独立看门狗的常用库函数定义在stm32f10x_iwdg.h中:
在这里插入图片描述

(1)取消PR、RLR寄存器写保护函数IWDG_WriteAccessCmd()

参数:
在这里插入图片描述

操作:

在这里插入图片描述

可以看到该函数就是将KR写入0x5555,来取消PR、RLR寄存器写保护

(2)设置分频因子函数IWDG_SetPrescaler()

在这里插入图片描述

参数:
在这里插入图片描述

操作:
在这里插入图片描述

可以看到,该函数是将16进制数写入PR寄存器,其分频因子对应的16进制数:

在这里插入图片描述

(3)设置重装载值函数IWDG_SetReload()

在这里插入图片描述

参数:
在这里插入图片描述

该参数由我们计算得来,由于RLR寄存器是低12位有效,所以该值<=0xFFF

操作:
在这里插入图片描述

直接将重装载初值写入到RLR寄存器

(4)重装载初值函数(喂狗)IWDG_ReloadCounter

在这里插入图片描述

参数:

操作:
在这里插入图片描述
在这里插入图片描述

直接对KR寄存器写入0xAAAA,喂狗。

(5)启动独立看门狗函数IWDG_Enable()

在这里插入图片描述

参数:

操作:
在这里插入图片描述

在这里插入图片描述

给KR寄存器写入0xCCCC,启动独立看门狗。

(6)独立看门狗状态获取函数IWDG_GetFlagStatus()

在这里插入图片描述

参数:

在这里插入图片描述

参数FLAG=0x0001|0x0002=0x0003

在这里插入图片描述

当独立看门狗处于更新状态时:(IWDG->SR & IWDG_FLAG) != (uint32_t)RESET,返回SET,表示正在更新,否则不在更新状态。

操作:
直接获取SR寄存器位0和位1的值

返回值:

返回SET(!0)表示处于更新中
返回RESET(0)表示不在更新中

七、例子(库函数版)

库函数版也比较简单,直接把刚刚例子中寄存器部分替换为库函数

代码如下:

//mian.c
#include "stm32f10x.h"
#include "led.h"
#include "key.h"
#include "sys.h"
#include "delay.h"
int main(void){	KEY_Init();LED_Init();delay_init();delay_ms(500);//为了看到程序复位PBout(5)=0;//点亮LED0//IWDG->KR=0x5555;//取消IWDG_PR和IWDG_RLR寄存器保护IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);//IWDG->PR=0x02;//设置重装载值IWDG_SetPrescaler(IWDG_Prescaler_16);//IWDG->RLR=2500;//设置分频系数和重装载值IWDG_SetReload(2500);//设置分频系数和重装载值//正常操作应该是先位与运算清空寄存器,再位或运算赋值//IWDG->KR=0xAAAA;//初始状态下,装载初值IWDG_ReloadCounter();//IWDG->KR=0xCCCC;//启动看门狗IWDG_Enable();while(1){if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0))//检测key_up按下{//IWDG->KR=0xAAAA;//喂狗IWDG_ReloadCounter();}}  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

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

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

相关文章

android自动软键盘,Android自定义软键盘

MyKeyboardAndroid自定义键盘的使用实现步骤第一步&#xff1a;1、新建一个xml文件夹放在res目录下面&#xff0c;然后新建xml文件:money_keyboard.xml2、然后在XML文件中添加按钮布局&#xff0c;这个布局就是键盘的样子了android:horizontalGap"1dp"android:keyWid…

Bootstrap使用-1

目录 结构&#xff1a;1. 视图函数2. 模板3. 登陆4. 怎样发生的添加模板基础模板提供的block定制基础模板结构&#xff1a; $ tree -I "__pycache*|*.pyc|*.xlsx" -FCL 3 . |-- templates/ | -- h1.html -- test-boostracp.py 1. 视图函数 test-boostracp.py from …

段错误、内存溢出、内存泄漏(区别)、堆溢出、栈溢出

参考&#xff1a;内存泄漏、内存溢出、段错误、堆溢出、栈溢出 作者&#xff1a;焦木白 发布时间&#xff1a;2019-10-22 网址&#xff1a;https://blog.csdn.net/jiaomubai/article/details/102680705?spm1001.2014.3001.5501 目录段错误内存溢出内存泄漏栈溢出堆溢出段错误 …

C语言中指针的地址和内容

参考&#xff1a;C语言中指针的地址和内容 作者&#xff1a;wallying 发布时间&#xff1a;2018-10-18 09:47:54 网址&#xff1a;https://blog.csdn.net/qq_36631580/article/details/89375140?spm1001.2014.3001.5502 #include <stdio.h>//一般用"地址"表示…

android运行过程简书,android 启动过程(一)

1、由init.rc调用 app_main.cpp的main方法&#xff0c;启动zygote进程3、调用AndroidRuntime.cpp 的start方法传递ZygoteInit类路径5、AndroidRuntime.cpp的start方法主要启动java虚拟机跟注册虚拟机&#xff0c;调用ZygoteInit的main方法6、ZygoteInit的main方法主要 把zygote…

回调函数 —— 借助中间通用函数(形参里有函数指针,实现函数注册)调用不同的回调函数 (多态/分层)

回调函数传参&#xff1a;函数指针做函数参数&#xff08;回调函数&#xff09; 目录背景回调函数是实现函数分层且单向依赖的好办法&#xff0c;使用函数指针运行struct结构体回调函数代码更清晰简单理解回调函数Demo其他回调函数博文背景 这是我在实际工作中遇到的问题&…

ESP8266等模块

模块讲解学习视频可参照&#xff1a;https://space.bilibili.com/323745961?spm_id_from333.788.b_765f7570696e666f.1 作者&#xff1a;叁议电子 目录ESP8266 WIFI模块介绍电脑操作ESP8266单片机上网ESP8266 WIFI模块介绍 电脑操作ESP8266 单片机上网

html5在线音乐列表播放器,HTML5列表音乐播放器SMusic

插件描述&#xff1a;一款基于HTML5、Css3的列表式音乐播放器&#xff0c;包含列表&#xff0c;音量&#xff0c;进度&#xff0c;时间&#xff0c;歌词展示以及模式等功能&#xff0c;不依赖任何库SMusic使用方法这是一款基于HTML5以及CSS3的列表式音乐播放器&#xff0c;增加…

unzipping/Users/xq/.gradle/wrapper /dists/gradle-3.3-all/55gk2rcmfc6p2dg9u9ohc3hw9/gradle-3.3-all.zi

unzipping/Users/xq/.gradle/wrapper /dists/gradle-3.3-all/55gk2rcmfc6p2dg9u9ohc3hw9/gradle-3.3-all.zip to /Users/xq/.gradle/wrapper/dists/gradle-3.3-all/55gk2rcmfc6p2dg9u9ohc3hw9 可能是下载时网络原因造成文件缺失 解决方法&#xff1a; cd /Users/xq/.gradle/w…

WIFI小车APP

对应这篇文章&#xff1a;433M射频遥控灯、震动感应灯、WIFI避障小车 目录代码概要activity_contrl.xmlContrlActivity.javaNetUtils.java详细工程代码下载代码概要 activity_contrl.xml <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android&qu…

[Web App]必胜客宅急送产品设计思路介绍[转]

O2O模式是餐饮业在移动消费趋势下主动拥抱互联网的方向&#xff0c;迎合餐饮消费者从以往经验判断为主转变为依靠移动设备、LBS、社交网络进行立体决策的过程。App成为联系消费者和餐饮业的重要纽带&#xff0c;承载着在O2O双向流程的闭环中加深消费者对品牌的认同和感情认知的…

使用Raphael实现html中绘图

2019独角兽企业重金招聘Python工程师标准>>> 首先&#xff1a;下载Raphael的javascript库&#xff1a;http://raphaeljs.com/。或者在html页面<head></head>&#xff1a;如下 <script src"http://www.zfanw.com/blog/raphael.js"></…

vivo手机刷机鸿蒙,捡到vivo手机如何刷机

捡到手机&#xff0c;首先建议归还给失主&#xff01;然后如果需要刷机的话&#xff0c;建议可以清除账户密码&#xff1a;可以尝试在手机关机状态同时按住音量上键以及电源键3到4秒手机出现vivo手机标志后&#xff0c;放开按键进入recovery模式&#xff0c;先选择wipe data/fa…

详解ROM和RAM

参考&#xff1a;详解ROM和RAM 作者&#xff1a;嵌入式实验楼 网址&#xff1a;https://mp.weixin.qq.com/s/FhUxMLeAxkhWe5m-gV_hMw 目录1、只读存储器&#xff1a;ROM2、随机访问存储器&#xff1a;RAM内存是计算系统最重要的元素&#xff0c;因为没有它&#xff0c;计算机就…

深入理解STM32内存管理

更多干货推荐可以去牛客网看看&#xff0c;他们现在的IT题库内容很丰富&#xff0c;属于国内做的很好的了&#xff0c;而且是课程刷题面经求职讨论区分享&#xff0c;一站式求职学习网站&#xff0c;最最最重要的里面的资源全部免费&#xff01;&#xff01;&#xff01;点击进…

html 手写字效果,canvas画布实现手写签名效果的示例代码

最近项目中涉及到移动端手写签名的功能需求&#xff0c;将实现代码记录于此&#xff0c;供小伙伴们参考指摘哦~HTML代码&#xff1a;手写区清除确定CSS样式&#xff1a;.mSign_signMark_box{padding: 15px 15px 26px 15px;}.mSign_signMark_footer{max-width:640px;margin:0 au…

FTP云盘

参考&#xff1a;FTP云盘项目 作者&#xff1a;糯米啊啊 发布时间&#xff1a; 2021-08-19 10:34:05 网址&#xff1a;https://blog.csdn.net/weixin_43732386?spm1001.2014.3001.5509 参考&#xff1a;自制FTP云盘项目 作者&#xff1a;不说话的小脑斧 发布时间&#xff1a; …

html transform属性,css3 transform属性详解

CSS3变形是一些效果的集合&#xff0c;比如平移translate() 、旋转rotate()、缩放scare()和倾斜skew()效果&#xff0c;每个效果都被称作为变形函数(Transform Function),它们可以操控元素发生旋转、缩放、和平移等变化。CSS3的2D transform函数包括了translate()、scale()、ro…

PHP调用新浪API 生成短链接

我们经常收到类似于这样的短信&#xff08;如下图&#xff09;&#xff0c;发现其中的链接并不是常规的网址链接&#xff0c;而是个短小精悍的短链接&#xff0c;产品中经常需要这样的需求&#xff0c;如果在给用户下发的短信中是一个很长的连接&#xff0c;用户体验肯定很差&a…

Chrome如何下载网页视频

目录第一步&#xff1a;右键&#xff0c;选择「检查」指令&#xff0c;进入代码控制面板第二步&#xff1a;单击代码面板左上角红色标出来的按钮&#xff0c;然后鼠标移到左边视频上第三步&#xff1a;双击src后面的代码&#xff08;全部展开&#xff09;&#xff0c;复制粘贴到…