STM32独立看门狗

时钟频率

40KHZ

看门狗简介

STM32F10xxx 内置两个看门狗,提供了更高的安全性、时间的精确性和使用的灵活性。两个看
门狗设备 ( 独立看门狗和窗口看门狗 ) 可用来检测和解决由软件错误引起的故障;当计数器达到给
定的超时值时,触发一个中断 ( 仅适用于窗口型看门狗 ) 或产生系统复位。
独立看门狗 (IWDG) 由专用的 40kHz 的低速时钟驱动,即使主时钟发生故障它也仍然有效。窗口
看门狗由从 APB1 时钟分频后得到的时钟驱动,通过可配置的时间窗口来检测应用程序非正常的
过迟或过早的操作。
IWDG 最适合应用于那些需要看门狗作为一个在主程序之外,能够完全独立工作,并且对时间精
度要求较低的场合。 WWDG 最适合那些要求看门狗在精确计时窗口起作用的应用程序。

IWDG主要性能

● 自由运行的递减计数器
● 时钟由独立的 RC 振荡器提供 ( 可在停止和待机模式下工作 )
● 看门狗被激活后,则在计数器计数至 0x000 时产生复位

IWDG功能描述

在键寄存器 (IWDG_KR) 中写入 0xCCCC ,开始启用独立看门狗;此时计数器开始从其复位值
0xFFF 递减计数。当计数器计数到末尾 0x000 时,会产生一个复位信号 (IWDG_RESET)
无论何时,只要键寄存器 IWDG_KR 中被写入 0xAAAA IWDG_RLR 中的值就会被重新加载到
计数器中从而避免产生看门狗复位 。

键寄存器(IWDG_KR)

预分频寄存器(IWDG_PR)

重装载寄存器(IWDG_RLR)

IWDG库函数

看门狗蜂鸣器

main.c


/*看门狗*/
#include"iwdg.h"
#include"led.h"
#include"fmq.h"
#include"key.h"
#include"delay.h"int main(void)
{int i=0,j=0;Led_Init();	Key_Init();Fmq_Init();delay_init();iwdg_init(5);Fmq_On();delay_ms(2000);Fmq_Off();for(i=0;i<3;i=(i+1)%3){iwdg_fee_dog();Led_On(i);delay_ms(500);Led_Off(i);delay_ms(500);}return 0;
}

iwdg.h

#ifndef _IWDG_H
#define _IWDG_H
#include "stm32f10x_conf.h"
extern void iwdg_init(int nu);
extern void iwdg_fee_dog(void);
#endif

iwdg.c

#include"iwdg.h"void iwdg_init(int nu) 
{IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); //关闭寄存器写保护 IWDG_SetPrescaler(IWDG_Prescaler_64); //625设置预分频值IWDG_SetReload(nu*625); //设置重装载值IWDG_ReloadCounter(); //重载计数值喂狗IWDG_Enable(); //启动关门狗
}void iwdg_fee_dog(void)
{ IWDG_ReloadCounter();//喂狗
}

delay.c

#include "delay.h"//利用系统滴答定时,编写的延时函数static u8  fac_us=0; //us延时倍乘数			   
static u16 fac_ms=0; //ms延时倍乘数/****************************************************************************
* 名    称: delay_init()
* 功    能:延时函数初始化
* 入口参数:无
* 返回参数:无
* 说    明:
****************************************************************************/
void delay_init(void)
{SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);//为系统定时器选择时钟为	HCLK 8分频	72MHz / 8 = 9MHzfac_us = SYSCLK / 8;//微秒的倍乘数 = 72 / 8 = 9//X * fac_us就相当于有X个微妙fac_ms = (u16)fac_us * 1000; //每个ms需要的systick时钟数(1ms = 1000us),所以fac_us*1000//X * fac_ms就相当于有X个毫妙
}								    /****************************************************************************
* 名    称: void delay_us(u32 nus)
* 功    能:延时nus
* 入口参数:要延时的微秒数
* 返回参数:无
* 说    明:nus的值,不要大于1864135us
****************************************************************************/
/*
通过相关手册我们了解到,备份值寄存器和当前值寄存器的值最大为16M - 1
我们的微秒级的延时函数的倍乘数为9所以16M - 1 / 9 = 1864135
*/
void delay_us(u32 nus)
{u32 midtime;																			//保存寄存器的状态SysTick->LOAD = nus * fac_us;											//时间加载(相当于有nus个微妙)SysTick->VAL = 0x00;															//清空计数器SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;					//使能系统定时器计数do{midtime = SysTick->CTRL;}while((midtime & 0x01) && !(midtime & (1 << 16)));//等待时间到达SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;				//关闭计数器SysTick->VAL = 0X00;															//清空计数器	 
}
/****************************************************************************
* 名    称: void delay_xms(u16 nms)
* 功    能:延时nms
* 入口参数:要延时的毫妙数
* 返回参数:无
* 说    明:SysTick->LOAD为24位寄存器,所以,最大延时为: nms<=0xffffff*8*1000/SYSCLK对9M条件下,nms<=1864ms 
****************************************************************************/
void delay_xms(u16 nms)
{	 		  	  u32 midtime;		   SysTick->LOAD = (u32)nms*fac_ms;									//时间加载(SysTick->LOAD为24bit)SysTick->VAL = 0x00;															//清空计数器SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;					//开始倒数do{midtime = SysTick->CTRL;}while((midtime & 0x01) && !(midtime & (1 << 16)));//等待时间到达SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;				//关闭计数器SysTick->VAL = 0X00;															//清空计数器
} 
/****************************************************************************
* 名    称: void delay_ms(u16 nms)
* 功    能:延时nms
* 入口参数:要延时的毫妙数
* 返回参数:无
* 说    明:nms:0~65535
****************************************************************************/
void delay_ms(u16 nms)
{	 	 u8 repeat = nms / 540;	//记录有多少个整的540msu16 remain = nms % 540;	//记录有多少个不够540mswhile(repeat){delay_xms(540);repeat--;}if(remain)delay_xms(remain);
} 

delay.h

#ifndef __DELAY_H
#define __DELAY_H#include "stm32f10x_conf.h" #define SYSCLK 72				//系统时钟的基数(注:是72而不是72M)typedef uint32_t  u32;
typedef uint16_t  u16;
typedef uint8_t   u8;void delay_init(void);	//延时函数的初始化
void delay_ms(u16 nms);	//毫秒级的延时函数(参数为毫秒数)
void delay_us(u32 nus);	//微秒级的延时函数(参数为微秒数)#endif

fmq.h

#ifndef __FMQ_H
#define __FMQ_H
#include "stm32f10x_conf.h"
extern void Fmq_Init(void);//初始化FMQ
extern void Fmq_On(void);//蜂鸣器响
extern void Fmq_Off(void);//蜂鸣器不响
#endif 

fmq.c

#include"key.h"
void Key_Init(void)
{GPIO_InitTypeDef GPIO_VALUE; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOA,ENABLE);GPIO_VALUE.GPIO_Mode=GPIO_Mode_IPU;GPIO_VALUE.GPIO_Pin=GPIO_Pin_9|GPIO_Pin_8;GPIO_Init(GPIOC,&GPIO_VALUE);	GPIO_VALUE.GPIO_Mode=GPIO_Mode_IPD;GPIO_VALUE.GPIO_Pin=GPIO_Pin_0;GPIO_Init(GPIOC,&GPIO_VALUE);	
}
int Key_status(int nu)
{int ret=0;switch(nu){case 0:ret=GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_9);break;case 1:ret=GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_8);break;case 2:ret=GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0);ret=!ret;break;}return !ret;}

led.h

#ifndef __LED_H
#define __LED_H
#include "stm32f10x_conf.h"extern void Led_Init(void);
extern void Led_On(int opt);
extern void Led_Off(int opt);
#endif 

led.c


#include"led.h"void Led_Init(void)
{GPIO_InitTypeDef GPIO_VALUE; //???RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//???GPIO_VALUE.GPIO_Mode=GPIO_Mode_Out_PP;//???? ????GPIO_VALUE.GPIO_Pin=GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;//????GPIO_VALUE.GPIO_Speed=GPIO_Speed_50MHz;//????GPIO_Init(GPIOC,&GPIO_VALUE);//???	
}
void Led_On(int nu)
{switch(nu){case 0:GPIO_SetBits(GPIOC,GPIO_Pin_1);break;case 1:GPIO_SetBits(GPIOC,GPIO_Pin_2);break;case 2:GPIO_SetBits(GPIOC,GPIO_Pin_3);break;}}
void Led_Off(int nu)
{switch(nu){case 0:GPIO_ResetBits(GPIOC,GPIO_Pin_1);break;case 1:GPIO_ResetBits(GPIOC,GPIO_Pin_2);break;case 2:GPIO_ResetBits(GPIOC,GPIO_Pin_3);break;}	
}/*
#include"led.h"
#include"bitband.h"
void Led_Init(void)
{GPIO_InitTypeDef GPIO_VALUE; //???RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//???GPIO_VALUE.GPIO_Mode=GPIO_Mode_Out_PP;//???? ????GPIO_VALUE.GPIO_Pin=GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;//????GPIO_VALUE.GPIO_Speed=GPIO_Speed_50MHz;//????GPIO_Init(GPIOC,&GPIO_VALUE);//???	
}
void Led_On(int nu)
{switch(nu){case 0:PCOut(1)=1;break;case 1:PCOut(2)=1;break;case 2:PCOut(3)=1;break;}}
void Led_Off(int nu)
{switch(nu){case 0:PCOut(1)=0;break;case 1:PCOut(2)=0;break;case 2:PCOut(3)=0;break;}	
}
*/

main.c


/*看门狗*/
#include"iwdg.h"
#include"led.h"
#include"fmq.h"
#include"key.h"
#include"delay.h"int main(void)
{int i=0,j=0;Led_Init();	Key_Init();Fmq_Init();delay_init();iwdg_init(5);Fmq_On();delay_ms(2000);Fmq_Off();for(i=0;i<3;i=(i+1)%3){iwdg_fee_dog();Led_On(i);delay_ms(500);Led_Off(i);delay_ms(500);}return 0;
}

看门狗过程

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

通过这步,我们取消 IWDG_PR 和 IWDG_RLR 的写保护,使后面可以操作这两个寄存器,设置 IWDG_PR 和 IWDG_RLR 的值。这在库函数中的实现函数是:

IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
这个函数的功能开启/取消写保护,即使能/失能写权限。

        2)设置独立看门狗的预分频系数和重装载值

        设置看门狗的分频系数的函数是:

void IWDG_SetPrescaler(uint8_t IWDG_Prescaler); //设置 IWDG 预分频值
        设置看门狗的重装载值的函数是:

        

void IWDG_SetReload(uint16_t Reload); //设置 IWDG 重装载值
        设置好看门狗的分频系数 prer 和重装载值就可以知道看门狗的喂狗时间(也就是看门狗溢出时间),该时间的计算方式为:

                                                        Tout=((4×2^prer) ×rlr) /40

        其中 Tout 为看门狗溢出时间(单位为 ms);prer 为看门狗时钟预分频值(IWDG_PR 值),范围为 0~7;rlr 为看门狗的重装载值(IWDG_RLR 的值);

        比如我们设定 prer 值为 4,rlr 值为 625,那么就可以得到 Tout=64×625/40=1000ms,这样,看门狗的溢出时间就是 1s,只要你在一秒钟之内,有一次写入 0XAAAA 到 IWDG_KR,就不会导致看门狗复位(当然写入多次也是可以的)。这里需要提醒大家的是,看门狗的时钟不是准确的 40Khz,所以在喂狗的时候,最好不要太晚了,否则,有可能发生看门狗复位。

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

        库函数里面重载计数值的函数是:

IWDG_ReloadCounter(); //按照 IWDG 重装载寄存器的值重装载 IWDG 计数器
        通过这句,将使 STM32 重新加载 IWDG_RLR 的值到看门狗计数器里面。即实现独立看门狗的喂狗操作。

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

        库函数里面启动独立看门狗的函数是:

IWDG_Enable(); //使能 IWDG
        通过这句,来启动 STM32 的看门狗。

        注意 IWDG 在一旦启用,就不能再被关闭!想要关闭,只能重启,并且重启之后不能打开 IWDG,否则问题依旧,如果不用 IWDG 的话,就不要去打开它,免得麻烦。
 

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

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

相关文章

腾讯云2核4G服务器CVM标准型S5实例5年优惠价格表

腾讯云服务器续费贵所以一次性买3年或5年&#xff0c;腾讯云轻量应用服务器3年价格有优惠&#xff0c;CVM云服务器5年有特价&#xff0c;腾讯云3年轻量和5年云服务器CVM优惠活动入口&#xff0c;3年轻量应用服务器配置可选2核2G4M和2核4G5M带宽&#xff0c;5年CVM云服务器可以选…

陈可之|三峡|《河水不犯井水的游戏》

《河水不犯井水的游戏》 尺寸&#xff1a;130x90cm 陈可之2007年绘 油画《河水不犯井水的游戏》是陈可之先生三峡系列作品之一&#xff0c;巧借古代传说&#xff0c;并具象化为螃蟹、乌龟、长江水&#xff0c;描绘了一幅和谐共生的画面。 画面右侧&#xff0c;蜿蜒宽阔的长江水…

强化学习_06_pytorch-TD3实践(CarRacing-v2)

0、TD3算法原理简介 详见笔者前一篇实践强化学习_06_pytorch-TD3实践(BipedalWalkerHardcore-v3) 1、CarRacing环境观察及调整 Action SpaceBox([-1. 0. 0.], 1.0, (3,), float32)Observation SpaceBox(0, 255, (96, 96, 3), uint8) 动作空间是[-1~1, 0~1, 0~1]&#xff0c…

网络安全选择题20道——附答案

一.网络安全选择题&#xff08;20道&#xff09; 1.常见的网络攻击类型中&#xff0c;以下哪个是一种拒绝服务&#xff08;DoS&#xff09;攻击&#xff1f; A. 木马 B. SQL注入 C. 垃圾邮件 D. SYN洪水攻击 2.下列哪项不是网络安全的三要素之一&#xff1f; A. 机密性 B. 可…

解决国内大模型痛点的最佳实践方案

1.前言 自AI热潮掀起以来&#xff0c;国内互联网大厂躬身入局&#xff0c;各类机构奋起追赶&#xff0c;创业型企业纷至沓来。业内戏称&#xff0c;一场大模型的“百模大战”已经扩展到“千模大战”。 根据近期中国科学技术信息研究所发布的《中国人工智能大模型地图研究报告…

【2023下算法课设】Gray码的分治构造算法

Gray码是一个长度为2ⁿ的序列&#xff0c;序列中无相同元素&#xff0c;且每个元素都是长度为n位的二进制位串&#xff0c;相邻元素恰好只有1位不同。例如长度为2的格雷码为&#xff08;000,001,011,010,110,111,101,100&#xff09;&#xff0c;设计分治算法对任意的n值构造相…

iOS设备信息详解

文章目录 ID 体系iOS设备信息详解IDFA介绍特点IDFA新政前世今生获取方式 IDFV介绍获取方式 UUID介绍特点获取方式 UDID介绍获取方式 OpenUDID介绍 Bundle ID介绍分类其他 IP地址介绍获取方式 MAC地址介绍获取方式正常获取MAC地址获取对应Wi-Fi的MAC地址 系统版本获取方式 设备型…

云HIS源码 云HIS解决方案 支持医保功能

云HIS系统重建统一的信息架构体系&#xff0c;重构管理服务流程&#xff0c;重造病人服务环境&#xff0c;向不同类型的医疗机构提供SaaS化HIS服务解决方案。 云HIS作为基于云计算的B/S构架的HIS系统&#xff0c;为基层医疗机构&#xff08;包括诊所、社区卫生服务中心、乡镇卫…

【华为数据之道学习笔记】6-7打造业务自助分析的关键能力

华为公司将自助分析作为一种公共能力&#xff0c;在企业层面进行了统一构建。一方面&#xff0c;面向不同的消费用户提供了差异性的能力和工具支撑&#xff1b;另一方面&#xff0c;引入了“租户”概念&#xff0c;不同类型的用户可以在一定范围内分析数据、共享数据结果。 1. …

【力扣100】199.二叉树的右视图

添加链接描述 # Definition for a binary tree node. # class TreeNode: # def __init__(self, val0, leftNone, rightNone): # self.val val # self.left left # self.right right class Solution:def rightSideView(self, root: Optional[Tr…

【贪心算法】专题练习一

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;那个传说中的man的主页 &#x1f3e0;个人专栏&#xff1a;题目解析 &#x1f30e;推荐文章&#xff1a;题目大解析&#xff08;3&#xff09; 前言 1.什么是贪心算法&#xff1f;——贪婪鼠目寸光 贪心策…

stat模块--python

在Python中,stat模块提供了一些用于解释os.stat(), os.lstat()和os.fstat()返回的结果的函数和常量。这些函数可以获取文件或文件系统节点的信息。 以下是一些stat模块中的函数和常量: stat.S_ISDIR(mode):如果mode是目录,则返回True。 stat.S_ISREG(mode):如果mode是普通…

在pyqt5界面中直接设置图标icon,不需要python程序代码!!一步搞定!!

小白轻松玩转pyqt5 1. 第一步&#xff1a;点击mainwindow,然后在windowicon中上传图片即可2. 设置成功总结&#xff08;对于小白入门pyqt5的一些忠告&#xff09; 1. 第一步&#xff1a;点击mainwindow,然后在windowicon中上传图片即可 2. 设置成功 总结&#xff08;对于小白入…

【Java 进阶篇】Jedis 操作 List:Redis中的列表类型

Redis中的列表&#xff08;List&#xff09;是一种有序的、可重复的数据类型&#xff0c;支持在列表的两端进行元素的插入和删除操作。Jedis作为Java开发者与Redis交互的工具&#xff0c;提供了丰富的API来操作List类型。本文将深入介绍Jedis如何操作Redis中的List类型数据&…

linux java环境安装

linux java1.8环境安装 下载 官方下载页面&#xff1a;https://www.oracle.com/cn/java/technologies/downloads/ 选择[jdk-8u391-linux-x64.tar.gz]下载&#xff0c;解压到/usr/local下。 # 建立软连接&#xff0c;以后如果更换版本&#xff0c;只需要解压&#xff0c;并更…

嵌入式-stm32-用PWM点亮LED实现呼吸灯

一&#xff1a;知识前置 1.1、LED灯怎么才能亮&#xff1f; 答&#xff1a;LED需要低电平才能亮&#xff0c;高电平是灯灭。 1.2、LED灯为什么可以越来越亮&#xff0c;越来越暗&#xff1f; 答&#xff1a;这是用到不同占空比来实现的&#xff0c;控制LED实现呼吸灯&…

陈可之油画|《远古河谷》,古老的三峡

《远古河谷》 尺寸&#xff1a;90x66cm 陈可之2002年绘 《远古河谷》是陈可之先生“白垩纪组画七千万年三峡原生映象”系列作品之一&#xff0c;通过细腻的笔触所呈现的神秘&#xff0c;去体会自然的历史、生命的历史以及人文的历史&#xff01; 三峡&#xff0c;沉淀了7000多…

AI赋能金融创新:ChatGPT引领量化交易新时代

文章目录 一、引言二、ChatGPT与量化交易的融合三、实践应用&#xff1a;ChatGPT在量化交易中的成功案例四、挑战与前景五、结论《AI时代Python量化交易实战&#xff1a;ChatGPT让量化交易插上翅膀》&#x1f4da;→ [当当](http://product.dangdang.com/29658180.html) | [京东…

web前端 JQuery下拉菜单的案例

浏览器运行结果&#xff1a; JQuery下载&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/17LXZigLQ8yau0toTGj4P_Q?pwd4332 提取码&#xff1a;4332 代码&#xff1a; <!doctype html> <html> <head> <meta charset"UTF-8"><…

南大通用使用jdbc插入time时间类型为00:00:00的问题解析

问题场景&#xff1a; 数据库数据类型&#xff1a; datetime HOUR TO SECOND -- 代表时分秒类型 hh:mm:ss&#xff0c;例如&#xff1a;10:58:13 在使用 PreparedStatement 进行set数据的时候执行结果为00:00:00 问题原因&#xff1a; 在setObject的时候&#xff0c;set的…