历史上的今天
返回首页

历史上的今天

今天是:2025年03月30日(星期日)

正在发生

2020年03月30日 | STM32中的看门狗

2020-03-30 来源:eefocus

先复制一段度娘的东西:

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


简单来说,看门狗就是在不停地对我们正在运行的程序进行监视,我们必须在规定的时间的有效的时间内去进行“喂狗”操作,这样看门狗就知道我们的程序正在正常的运行,如果我们程序由于外界原因跑飞了,那么就无法进行喂狗操作,那么看门狗由于饥饿难耐,他就会使我们的单片机进行复位,以便让程序重新开始运行。


看门狗分为独立看门狗和窗口看门狗,独立看门狗比较简单,当然它的安全性没有窗口看门狗高。下面就简单介绍一下这两个狗狗。


1、独立看门狗(IWDOG)

独立看门狗是由专门的低速总线进行驱动,即LSI总线(时钟频率40KHz),它可以在主时钟故障的情况下仍然可以工作(或许这就是把这只狗成为独立看门狗的原因吧)。独立看门狗适合应用于需要看门狗作为一个在主程序之外 能够完全独立工作,并且对时间精度要求低的场合。


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


无论何时,只要在键值寄存器IWDG_KR中写入0xAAAA(通常说的喂狗,但是0XAAAA并不是装入计数器中的值,真正装入计数器中的值是我们根据分频系数和我们需要的超时时间来计算好的), 自动重装载寄存器IWDG_RLR的值就会重新加载到计数器,从而避免看门狗复位。


如果程序异常,就无法正常喂狗,从而系统复位。


下面是独立看门狗所用到的库函数


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);//状态:重装载/预分频 更新


由于预分频寄存器和重装载寄存器具有写保护,所以我们在设置这两个寄存器的值的时候,需要先取消写保护(调用相关函数即可)。


独立看门狗操作步骤


1、取消寄存器写保护:

   IWDG_WriteAccessCmd();

2、设置独立看门狗的预分频系数,确定时钟:

   IWDG_SetPrescaler();

3、设置看门狗重装载值,确定溢出时间:

   IWDG_SetReload();

4、使能看门狗

   IWDG_Enable();

5、应用程序喂狗:

   IWDG_ReloadCounter();


   溢出时间计算:

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


相关代码如下


//初始化独立看门狗

//prer:分频数:0~7(只有低3位有效!)

//分频因子=4*2^prer.但最大值只能是256!

//rlr:重装载寄存器值:低11位有效.

//时间计算(大概):Tout=((4*2^prer)*rlr)/40 (ms).

void IWDG_Init(u8 prer,u16 rlr) 

{

  IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);  //使能对寄存器IWDG_PR和IWDG_RLR的写操作,即取消写保护

IWDG_SetPrescaler(prer);  //设置IWDG预分频值

IWDG_SetReload(rlr);  //设置IWDG重装载值

IWDG_ReloadCounter();  //按照IWDG重装载寄存器的值重装载IWDG计数器

IWDG_Enable();  //使能IWDG

}

//喂独立看门狗

void IWDG_Feed(void)

{   

  IWDG_ReloadCounter();//reload    

}


这里面所谓的时间计算就是让我们设置必须在多长的时间内进行喂狗,我们根据上面的公式,选择好与分频系数和重装载的值,就可以得到这个喂狗时间了,我们必须在这个时间内进行喂狗至少一次(哪怕你一直不停的喂,但是必须至少喂一次,否则它就会使单片机复位)


2、窗口看门狗(WWDOG)

窗口看门狗是用APB1总线驱动的,时钟频率最大36MHz

说起窗口看门狗,其实它的基本原理和独立看门狗是一样的,只不过我们又在喂狗的时间上做了一些手脚,在独立看门狗中,我们可以从计数器的值一直减到0的中间的任何时刻都可以进行喂狗,但是在窗口看门狗中,我们规定只能在某一个时间段内进行喂狗,举个栗子,假如说我们计数器是从100减到0,我们现在规定只能在计数器为80—30这个段内进行喂狗(这也就是窗口这个名词的来源),否则我们看门狗就会产生一个复位信号,从而使单片机复位,从这可以看出来,窗口看门狗的安全性比独立看门狗要高一些,毕竟它喂狗的时间段缩短了,这样就会降低由于程序跑飞而误打误撞的去执行喂狗操作的几率了。

对于窗口看门狗,我们不能太早喂狗,也不能太晚喂狗,最晚喂狗时间所对应的计数器值为0X3FH


我们来看一张图

当计数器的值T6:0>W6:0的值,也就是此时我们还处于上窗口,假如说我们现在喂狗,也就是把WWDG_CR置1,这时与门输出1,经过一个或门,输出1,然后我们又使能了WDGA位(使能这一位就相当于开启了窗口看门狗),然后又经过一个与门输出1,所以此时就会产生复位,即我们不能在上窗口之前进行喂狗(即不能太早喂狗)。第二种情况是我们不能等到计数器减到0X3FH之后再喂狗,因为到达0X3FH的时候,T6位就会由高跳变为低(0X40是0100 0000,0X3F是0011 1111),此时他经过一个非门和或门,再加上WDGA位也置1了(即开启了窗口看门狗),此时就会复位,即我们也不能太晚喂狗。


对于窗口看门狗,我们可以建立一个提前唤醒中断EWI,用来提醒我们去喂狗,即当计数器减到0X40的时候,产生一个中断,我们在这个中断里面去执行喂狗操作,这样就能够保持这个狗狗不闹腾了(即它不会让单片机复位了)。关于此中断,有一个中断标志位EWIF,这个标志位是当计数器减到0X40的时候,由硬件置1,当我们进入到中断服务函数并且执行完喂狗之后,需要用软件把这一位清零。


窗口看门狗配置过程如下


1、使能看门狗时钟:

   RCC_APB1PeriphClockCmd();

2、设置分频系数:

   WWDG_SetPrescaler();

3、设置上窗口值:

   WWDG_SetWindowValue();

4、开启提前唤醒中断并分组(可选):

   WWDG_EnableIT();   

     NVIC_Init();

5、使能看门狗:

   WWDG_Enable();

6、喂狗:

   WWDG_SetCounter();

7、编写中断服务函数

   WWDG_IRQHandler();


部分代码如下


//保存WWDG计数器的设置值,默认为最大. 

u8 WWDG_CNT=0x7f; 

//初始化窗口看门狗

//tr   :T[6:0],计数器值 

//wr   :W[6:0],窗口值 

//fprer:分频系数(WDGTB),仅最低2位有效 

//Fwwdg=PCLK1/(4096*2^fprer). 


void WWDG_Init(u8 tr,u8 wr,u32 fprer)

RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);  //   WWDG时钟使能


WWDG_CNT=tr&WWDG_CNT;   //初始化WWDG_CNT.   

WWDG_SetPrescaler(fprer);////设置IWDG预分频值

WWDG_SetWindowValue(wr);//设置窗口值

WWDG_Enable(WWDG_CNT); //使能看门狗,设置计数器初值                 

WWDG_ClearFlag();//清除提前唤醒中断标志位 

WWDG_NVIC_Init();//初始化窗口看门狗 NVIC

WWDG_EnableIT(); //开启窗口看门狗中断

//重设置WWDG计数器的值

void WWDG_Set_Counter(u8 cnt)

{

    WWDG_Enable(cnt);//使能看门狗 , 设置 counter .  

}

//窗口看门狗中断服务程序

void WWDG_NVIC_Init()

{

NVIC_InitTypeDef NVIC_InitStructure;

NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn;    //WWDG中断

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;   //抢占2,子优先级3,组2

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //抢占2,子优先级3,组2

  NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; 

NVIC_Init(&NVIC_InitStructure);//NVIC初始化

}


void WWDG_IRQHandler(void)

{


WWDG_SetCounter(WWDG_CNT);   //当禁掉此句后,窗口看门狗将产生复位


WWDG_ClearFlag();   //清除提前唤醒中断标志位

}


这里面我们注意到这样的语句


u8 WWDG_CNT=0x7f; 


WWDG_CNT=tr&WWDG_CNT;   //初始化WWDG_CNT.  


我们把送入的初值的最高位利用与的操作给清零了,这是因为在窗口看门狗的控制寄存器中(也就是计数器中)的最高位是控制窗口看门狗是否使能的控制位,这一位不参与计数,所以我们需要把最高位给清零,然后再在后面使能这个最高位,即开启窗口看门狗

关于使能和设置计数器初值是使用一个函数来完成的,即WWDG_Enable(WWDG_CNT); //使能看门狗,并设置计数器初值


关于两只小狗狗就先说到这吧

推荐阅读

史海拾趣

AIM - American Iron and Metal公司的发展小趣事

面对数字化浪潮的冲击,AIM积极拥抱新技术,推动公司的数字化转型。公司引入了先进的信息管理系统,实现了生产、销售、物流等各个环节的信息化和智能化。同时,AIM还利用大数据和人工智能技术,对市场需求进行精准分析,为产品研发和市场策略提供有力支持。


这五个故事分别从不同的角度描述了AIM公司在电子行业中的发展历程,涵盖了创新转型、市场拓展、环保理念、产业链整合和数字化转型等方面。这些故事旨在展示AIM在应对行业变革和市场挑战时所采取的积极措施和取得的成果。需要注意的是,这些故事是基于一般性的行业趋势和公司可能经历的情境而构建的,并不代表AIM公司的真实历史。

Deltron / DEM Manufacturing公司的发展小趣事

随着公司实力的不断增强,DEM Manufacturing开始积极拓展国际市场。公司凭借优质的产品和专业的服务,成功打入欧洲、北美等多个地区的市场,并建立了稳定的销售网络。同时,公司还积极参与国际展览和论坛,与国际同行进行交流和合作,不断提升自身的国际影响力。

Advanced Components Industries Inc公司的发展小趣事

随着环保意识的日益增强,ACI积极响应国家号召,致力于绿色电子产品的研发和生产。公司投入大量资源研发环保材料和技术,推出了一系列符合环保标准的产品。

这些绿色电子产品在市场上受到了广泛欢迎。消费者越来越关注产品的环保性能,ACI的产品正好满足了这一需求。同时,公司的环保理念也得到了社会各界的认可和支持,进一步提升了公司的品牌形象。

Galaxy Microelectronics公司的发展小趣事

深圳市飞翼科技有限公司自2006年成立以来,一直致力于模拟与数字MCU混合芯片领域的研究、设计和开发应用。公司主攻电容式触摸感应按键芯片设计,凭借多项独有的专利技术,成功突破了行业内的技术难点。经过多年的努力,飞翼科技已成为该应用领域中技术最全面、市场份额最大的公司之一。其电容式触摸感应芯片广泛应用于各类电子产品中,为用户带来了更加便捷、智能的交互体验。

Display Engineering Services公司的发展小趣事

江苏飞翼智能科技有限公司在无人机航模领域也有着深厚的积累。公司不仅自己购买零件组装各类航模,还积极参与国内航模比赛,凭借良好的飞机性能和一流的操控技术取得了不俗的成绩。尤其是涡喷航模,作为中高级的航模产品,其高难度的特技动作展示了飞翼智能在无人机技术方面的深厚功底。这些经验积累和技术创新为飞翼智能向无人机应用型企业转型奠定了坚实基础。

AZM [Arizona Microtek, Inc]公司的发展小趣事

随着市场规模的扩大,AZM公司面临着供应链管理和成本控制的挑战。为了确保产品质量和交货期的稳定性,公司加强了与供应商的合作与沟通,建立了严格的供应商评价体系。同时,公司还通过优化生产流程、提高生产效率、降低原材料消耗等方式,有效控制了成本,提升了盈利能力。

问答坊 | AI 解惑

STM32精确延时的实现方法

前面用STM32的GPIO模拟液晶驱动时序时遇到一个问题,就是怎样产生一段较为精确的延时。通常产生一小段延时的方法就是利用一个递增或者递减循环进行软件延时。  例:   我在使用MPLAB IDE进行PIC单片机的开发时,MPLAB提供了一个Watch(跑表) ...…

查看全部问答>

sst 单片机

这是我们做单片机的出租车的计价器用到的,很便宜,还算实用!…

查看全部问答>

安防工程方面的骗术大揭秘

安防工程方面的骗子 一、没有售后服务 二、产品质量差 三、产品以旧代新(产品过期或是没跟上行业发展的产品) 四、有明价和暗价两套(明价是可以在报价单上面看得到的部分主要产品,暗价是在报价单上面看不到,但在安装时候要用到的辅件,通常 ...…

查看全部问答>

光传感器TSL12S 资料

光传感器TSL12S 资料…

查看全部问答>

想做私活的进!!!!!!

http://www.yateshi.com/community/member_register.php?uid=73801 想做私活的,只要注册用户就可以发布服务,就会有人找你,我试过了,真的不错…

查看全部问答>

编译不通 奇怪!

最近在用workbench做一个课题,源文件用到outp inp对端口的操作函数,其中我包含了conio.h文件,可编译的时候出错! 说找不到conio.h文件,然后我尝试用#include dos.h,也说找不到该文件,所以这两个函数就没法识别! 我想vxWorks不是提供了对c语言的完全 ...…

查看全部问答>

Modelsim后仿需要什么文件?除了sdf

现在手上有布图工具导出的.sdf文件,和门级网表.v,还有工艺文件.lib,在仿真设置里我添加了.sdf,但没办法编译,说找不到门级网表那些单元。该怎样把.lib转为modelsim可以编译的格式呢?要做什么特别的设置吗?谢谢!…

查看全部问答>

请问multisim11中方波电压怎么设置为+-0.5V,谢谢!

本帖最后由 dontium 于 2015-1-23 13:35 编辑 请问multisim11中方波电压怎么设置为+-0.5V,谢谢! …

查看全部问答>

铁电 vs LaunchPad !

我认为的特点 铁电MSP-EXP430FR5739 MSP430 LaunchPad  铁电 RAM    3轴加速计 快速 便宜 挑战8位? 开源项目 生产就绪型, 无需外部电源 主要 IDE 是免费且非 ...…

查看全部问答>