9.独立看门狗IWDG窗口看门狗WWDG编码思路

2023-12-26 21:01

本文主要是介绍9.独立看门狗IWDG窗口看门狗WWDG编码思路,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言:

        看门狗是维护系统稳定性的一向技术,可以让代码跑飞及时复位,在产品中非常常用,俗话说,重启能解决90%的问题,作为产品来说,你总不能因为一次bug就让程序卡死不动了,肯定要试着重启一下的。看门狗的原理简单的说就是它是一个倒数的计数器,倒数到某个数,它就重启,我们正常的程序当然不能莫名其妙重启,所以在它倒数的期间,往它的计数器写一个新的倒数的值,这样它就不会重启了。更简明地说,就是要定时地,往它的某个寄存器写一个值以防它重启。        

        独立看门狗和窗口看门狗原理一致,差异只在于倒数到哪个值就重启。独立看门狗是倒数到0就重启,而窗口看门狗是你只能在某一个时间区间给它的寄存器写重载值,提早写寄存器或者过晚写重载值,都会导致重启。

        我们说看门狗的本质是个定时器,所以对于定时器,要关注的有几个点:1.时钟频率2.重载值&&计数值3.中断事件4.定时器开关

独立看门狗:

1.时钟:由独立的内部RC时钟(32Khz)提供,即计数一次是1/32K 秒。当然时钟可以分频,对应的寄存器是IWDG_PR可以4,8,16,32.。。。256分频,这样就可以比较久再喂狗一次。

2.重载值&&计数值:

存重载值的寄存器是IWDG_RLR,只有12位有效即可以计数2^12-1 = 4095次,结合时钟频率,可知重启期限是    4095 / 时钟频率

只是,这个寄存器是有写保护的,要操作它需要先解锁,相关寄存器是IWDG_KR

IWDG_KR写0x5555,就可以修改重载值IWDG_RLR以及分频值IWDG_PR

对IWDG_KR写0xAAAA,能够刷新计数值(即将重载值赋给计数值)

对IWDG_KR写0xCCCC,就能够开启看门狗(3.时钟开关     开了就没法关掉了)

没了,这个定时器连中断都没有~

初始化步骤是:

1.配置时钟分频系数IWDG_PR,设置重载值IWDG_RLR

IWDG->KR=0X5555;//解锁
IWDG->PR=prer;  //设置分频系数   
IWDG->RLR=rlr;  //设置重载值
IWDG->KR=0XAAAA;//装载计数值

2. 开启独立看门狗

IWDG->KR=0XCCCC;

3.定时喂狗

IWDG->KR=0XAAAA;//就是将重载值赋给计数值

完整代码:

初始化:

void IWDG_Init(u8 prer分频值,u16 rlr重载值) 
{IWDG->KR=0X5555;//使能对IWDG->PR和IWDG->RLR的写		 										  IWDG->PR=prer;  //设置分频系数   IWDG->RLR=rlr;  //从加载寄存器 IWDG->RLR  IWDG->KR=0XAAAA;//reload											   IWDG->KR=0XCCCC;//使能看门狗	
}

喂狗:

void IWDG_Feed(void)
{IWDG->KR=0XAAAA;//reload											   
}

独立看门狗就是这么简单啦~

窗口看门狗:

窗口看门狗的原理,一个图就可以阐释清楚:

主要注意红色框的部分,只有在刷新窗口这个区间(W[6:0]~0X40)才能喂狗,否则无论是计数器还没倒数到W[6:0]之前就喂狗,亦或者计数器直到0X40还没喂狗,都会导致单片机复位。下面来看怎么配置。还是那样,关注定时器的核心要素:

初始化步骤是:

1.时钟频率

 很离谱的是没有在时钟树看到WWDG的时钟分支,只好来在总线结构这里找,可知WWDG是附属于APB1的,由时钟系统配置我们直到APB1时钟是主频的4分频,即168M/4 = 42M

查看手册我们可以得知WWDG_CFR[8:7]可以配置时钟分频,既然提到了这个寄存器,那顺便就配置一下吧。

WWDG_CFR解析:

[6:0]:        这7位是设置窗口值的,也就是上面窗口看门狗原理框图中的W[6:0]

[8:7]:        配置时钟分频的

[9]:           这个位设为1,那么每次定时器倒数到0x40就会产生中断,这时我们只要在中断服务函数中喂狗,就能维持程序正常运行了~ 要素3.中断事件 在这里,当然别忘了,凡是和中断有关就是和NVIC有关(这个是内部中断,所以没有额外操作)

 所以如果将分频设为8(42M/8 = 5.25M),窗口值设为0x5F,并且开启中断的话:

RCC->APB1ENR|=1<<11; 	//使能wwdg时钟 
WWDG->CFR = 1<<9 | 0x3<<7 | 0x5f<<0;
MY_NVIC_Init(2,3,WWDG_IRQn,2);//分组,中断号,优先级

2.重载值&&计数值

寄存器WWDG_CR控制着定时器开关以及计数值

[6:0]:        WWDG好像没有重载值,只有这个实时计数值,不过效果是类似的。在中断中要及时给它幅值,避免系统复位。

[7]:           置1就是打开WWDG 要素4.定时器开关 在这里

如果将计数值设为0x7f,并打开定时器就是:

WWDG_CR->CR = 1<<7 | 0x7f ;

除了这两个寄存器外,还有一个大材小用的,寄存器WWDG_SR 

 一共32个位,只有bit0是有用的,作用是产生中断时会置1,而且要手动清零~

完整代码:

初始化WWDG:其实按上面我写的那个代码也是可以用的(实测),只是正点原子这个比较通用,了解了原理之后直接调用即可,也只有三个寄存器而已就没必要造轮子了

void WWDG_Init(u8 tr倒数值,u8 wr窗口值,u8 fprer分频) 
{    RCC->APB1ENR|=1<<11; 	//使能wwdg时钟 WWDG_CNT=tr&WWDG_CNT;   //初始化WWDG_CNT.     WWDG->CFR|=fprer<<7;    //PCLK1/4096再除2^fprer WWDG->CFR&=0XFF80;      WWDG->CFR|=wr;     		//设定窗口值      WWDG->CR|=WWDG_CNT; 	//设定计数器值 WWDG->CR|=1<<7;  		//开启看门狗      MY_NVIC_Init(2,3,WWDG_IRQn,2);//抢占2,子优先级3,组2     WWDG->SR=0X00; 			//清除提前唤醒中断标志位 WWDG->CFR|=1<<9;        //使能提前唤醒中断 
} 

调用:

WWDG_Init(0X7F,0X5F,3);	//计数器值为7f,窗口寄存器为5f,分频数为8	  

喂狗函数:

u8 WWDG_CNT=0x7f; //这个变量可以设置计数值//重设置WWDG计数器的值 
void WWDG_Set_Counter(u8 cnt) 
{ WWDG->CR =(cnt&0x7F);//重设置7位计数器 
}

WWDG中断服务函数:

//窗口看门狗中断服务程序 
void WWDG_IRQHandler(void) 
{      WWDG_Set_Counter(WWDG_CNT);//重设窗口看门狗的值!         WWDG->SR=0X00;//清除提前唤醒中断标志位 //业务代码
}

无论是开发哪个模块,都需要根据核心思想来编码。第一次学习应力争总结出模块对应的开发流程,日后碰到不同的单片机才不至于完全没有思路。

完~

这篇关于9.独立看门狗IWDG窗口看门狗WWDG编码思路的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/540762

相关文章

透彻!驯服大型语言模型(LLMs)的五种方法,及具体方法选择思路

引言 随着时间的发展,大型语言模型不再停留在演示阶段而是逐步面向生产系统的应用,随着人们期望的不断增加,目标也发生了巨大的变化。在短短的几个月的时间里,人们对大模型的认识已经从对其zero-shot能力感到惊讶,转变为考虑改进模型质量、提高模型可用性。 「大语言模型(LLMs)其实就是利用高容量的模型架构(例如Transformer)对海量的、多种多样的数据分布进行建模得到,它包含了大量的先验

poj 2594 二分图最大独立集

题意: 求一张图的最大独立集,这题不同的地方在于,间接相邻的点也可以有一条边,所以用floyd来把间接相邻的边也连起来。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <sta

poj 3692 二分图最大独立集

题意: 幼儿园里,有G个女生和B个男生。 他们中间有女生和女生认识,男生男生认识,也有男生和女生认识的。 现在要选出一些人,使得这里面的人都认识,问最多能选多少人。 解析: 反过来建边,将不认识的男生和女生相连,然后求一个二分图的最大独立集就行了。 下图很直观: 点击打开链接 原图: 现图: 、 代码: #pragma comment(

最大流=最小割=最小点权覆盖集=sum-最大点权独立集

二分图最小点覆盖和最大独立集都可以转化为最大匹配求解。 在这个基础上,把每个点赋予一个非负的权值,这两个问题就转化为:二分图最小点权覆盖和二分图最大点权独立集。   二分图最小点权覆盖     从x或者y集合中选取一些点,使这些点覆盖所有的边,并且选出来的点的权值尽可能小。 建模:     原二分图中的边(u,v)替换为容量为INF的有向边(u,v),设立源点s和汇点t

C++操作符重载实例(独立函数)

C++操作符重载实例,我们把坐标值CVector的加法进行重载,计算c3=c1+c2时,也就是计算x3=x1+x2,y3=y1+y2,今天我们以独立函数的方式重载操作符+(加号),以下是C++代码: c1802.cpp源代码: D:\YcjWork\CppTour>vim c1802.cpp #include <iostream>using namespace std;/*** 以独立函数

线性因子模型 - 独立分量分析(ICA)篇

序言 线性因子模型是数据分析与机器学习中的一类重要模型,它们通过引入潜变量( latent variables \text{latent variables} latent variables)来更好地表征数据。其中,独立分量分析( ICA \text{ICA} ICA)作为线性因子模型的一种,以其独特的视角和广泛的应用领域而备受关注。 ICA \text{ICA} ICA旨在将观察到的复杂信号

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

三相直流无刷电机(BLDC)控制算法实现:BLDC有感启动算法思路分析

一枚从事路径规划算法、运动控制算法、BLDC/FOC电机控制算法、工控、物联网工程师,爱吃土豆。如有需要技术交流或者需要方案帮助、需求:以下为联系方式—V 方案1:通过霍尔传感器IO中断触发换相 1.1 整体执行思路 霍尔传感器U、V、W三相通过IO+EXIT中断的方式进行霍尔传感器数据的读取。将IO口配置为上升沿+下降沿中断触发的方式。当霍尔传感器信号发生发生信号的变化就会触发中断在中断

form表单提交编码的问题

浏览器在form提交后,会生成一个HTTP的头部信息"content-type",标准规定其形式为Content-type: application/x-www-form-urlencoded; charset=UTF-8        那么我们如果需要修改编码,不使用默认的,那么可以如下这样操作修改编码,来满足需求: hmtl代码:   <meta http-equiv="Conte