datasheet

STM32小白入门(第十天)-------看门狗watchdog

2019-07-10来源: eefocus关键字:STM32  看门狗  watchdog

记得刚开始面试的时候,被面试官问了一个问题:stm32这个项目如果系统跑飞了,死机了,你是怎么处理的?


那时候没听懂他的意思,傻乎乎的回了一句,没遇到过这种情况。事后,才后悔莫及啊,他的意思不就是问我看门狗的作用吗?


然后就没有然后了,一个嵌入式工程师,如果看门狗都不知道人家是不敢用你的。


一、什么是看门狗?


看门狗是一个定时器,我们可以设置一个计数值,当看门狗启动后,计数值在一定的频率下不停的减1,当计数值减到0,看门狗会发出一个复位信号给CPU,这样会造成嵌入式系统复位。


软件系统在正常工作的过程中,需要在看门狗计数值减到0之前,给计数值重新赋值,这个看门狗就不会复位了,这个过程->“喂狗”。


当嵌入式系统,因为受到干扰或者出现错误,可能会造成软件“跑飞”--->死机。当系统发生死机的时候,看门狗喂狗的过程就没有了,看门狗计数值减到0,产生一个复位信号给CPU,造成系统复位,从错误的状态恢复了。



STM32有2个看门狗:独立看门狗和窗口看门狗。


独立看门狗IWDG----独立于系统之外,因为有独立时钟,所以不受系统影响的系统故障探测器,主要用于监视硬件错误。


窗口看门狗WWDG----系统内部的故障探测器,时钟与系统相同。如果系统时钟不走了,这个狗也就失去了作用了,主要用于监视软件错误。


简单的讲,看门狗就是检测系统故障的,如果因为系统故障而没有及时喂狗,则引发复位重启。


独立看门狗拥有自己的时钟源,不依赖PLL时钟输出的分频信号,能够独立运行,这样子的好处就是PLL假如受到干扰,导致运行异常,独立的看门狗还能正常地进行工作,如果没有正常的喂狗动作,就复位CPU。


IWDG程序设计


//用于定时喂狗

void Tim3_Init(void)

{

/* TIM3 clock enable ,定时器3的时钟使能*/

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

/* Enable the TIM3 global Interrupt,使能定时器3全局中断 */

NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

 

/* Time base configuration ,定时器的基本配置,用于配置定时器的中断频率为10Hz,也就是说100ms触发一次中断*/

TIM_TimeBaseStructure.TIM_Period = (10000/100)-1; //10000是10KHz,是定时器3的时钟源,100就是中断的频率

TIM_TimeBaseStructure.TIM_Prescaler = 8400-1; //预分频,也就是说第一次分频,降低频率

TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //第二次分频,当前是实现1分频,也就是不降低频率

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数方法,从0开始计算

TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

/* TIM Interrupts enable ,使能定时器3的更新中断事件,也代表说定时到达的事件*/

TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);

/* TIM3 enable counter,使能定时器3工作,开始计数 */

TIM_Cmd(TIM3, ENABLE);

}

void WatchDog_Init(void){

/* Clear reset flags,清空复位标志 */RCC_ClearFlag();/* Enable write access to IWDG_PR and IWDG_RLR registers ,独立看门狗的寄存器都是受到保护的,必须解除写保护*/IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);/* IWDG counter clock: LSI/256 ,设置看门狗的时钟频率 = 32KHz / 256 = 125Hz*/ 1s 计算125次IWDG_SetPrescaler(IWDG_Prescaler_256);//设置看门狗的超时时间,也代表说看门狗必须在2秒内进行喂狗(刷新计数值,不能等于0) IWDG_SetReload(250);/* Reload IWDG counter ,刷新计数值==喂狗*/IWDG_ReloadCounter();/* Enable IWDG ,使能看门狗 */IWDG_Enable();Tim3_Init();}void TIM3_IRQHandler(void){ //检查当前触发中断事件是否为更新中断事件 if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) {//添加用户代码 IWDG_ReloadCounter();//喂狗 //清空标志位 TIM_ClearITPendingBit(TIM3, TIM_IT_Update); }}


喂狗的动作其实就等同于银行取钱的原理,银行正常工作时间为上午9点到下午5点,其他时间都不能取钱。




WWDG程序设计


        /* WWDG configuration ,窗口看门狗的配置*/

/* Enable WWDG clock ,使能看门狗的时钟*/

RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);

 

/* 窗口看门狗的时钟 = (PCLK1 (42MHz)/4096)/8 = 1281 Hz (~780 us)  */

WWDG_SetPrescaler(WWDG_Prescaler_8);

 

/* Set Window value to 80; WWDG counter should be refreshed only when the counter

  is below 80 (and greater than 0x40) otherwise a reset will be generated 设置窗口的上限值为80*/

WWDG_SetWindowValue(80);

 

/* 设置计数值的初值为127,则窗口看门狗的最大超时时间 = 780 us * 64 = 49.92 ms 

这个时候窗口刷新时间如下

        ~780 * (127-80) = 36.6ms < refresh window < ~780 * 64 = 49.9ms */

WWDG_Enable(127);

//WWDG NVIC 配置

NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn; //窗口看门狗中断通道

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0; //抢占优先级0

NVIC_InitStructure.NVIC_IRQChannelSubPriority =0; //子优先级0

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能

NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器

//清空提前唤醒中断标志位

WWDG_ClearFlag();

//使能提前唤醒中断

WWDG_EnableIT();

void WWDG_IRQHandler(void)

{

if(WWDG_GetFlagStatus()==SET)

{

//进行喂狗

WWDG_SetCounter(127);

 

//清空提前唤醒中断标志位

WWDG_ClearFlag();

}

}

思考,如果窗口看门狗的中断优先级是低于定时器中断的抢占优先级出现什么问题?

回答:会出现窗口看门狗喂狗超时,导致发送“IWDG RESETn”的时候,定时器进入while(1)死循环,由于窗口看门狗的抢占优先级低于定时器,同时独立看门狗的喂狗时间是1秒以内的,而窗口看门狗的喂狗时间40ms以内的,结果导致窗口看门狗喂狗超时直接复位,详细分析如下图。



关键字:STM32  看门狗  watchdog

编辑:什么鱼 引用地址:http://www.eeworld.com.cn/mcu/ic467311.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:STM32小白入门(第11天)-------SPI协议
下一篇:STM32小白入门(第九天)-------温湿度模块

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

STM32开发笔记20: STM32L053R8T6的keil配置

单片机型号:STM32L053R8T6    使用STM32CubeMX生成STM32L053R8T6相关的应用程序代码后,使用Keil开发环境第1次下载的时候,提示如下错误,我使用F0和F4的单片机,没有遇到过。    仔细查看工程设置,原因在工程设置中,我们需加入相应的Flash配置信息,如下图所示,具体的选择,要根据单片机的类型,我们可以仔细查看数据手册。    但下载的时候,偶尔还会提示如下错误:    这件事情网上说了很多的解决方法,我自己测试,更改2处Keil的设置既可以解决,如下图所示。    此2处更改后,反复
发表于 2019-07-16
STM32开发笔记20: STM32L053R8T6的keil配置

STM32开发笔记21: USB驱动的移植

单片机型号:STM32L053R8T6    现在使用的STM32L053R8T6单片机带有USB接口,原先一直使用UART转USB芯片来完成USB功能的支持,现在这款单片机带了就希望使用以下。由于已经建立了自己的工程目录,再重新使用STM32CubeMX生成的工程文件,重新建立是不显示的,所以本文探索将USB驱动文件移植到自己项目中的方法,我使用的是USB的CDCD类,步骤如下:    1、使用STM32CubeMX使能USB,如下图所示:    2、设置时钟,USB需要48M时钟,使用内部和外部均可,我这里使用外部时钟。    3、生成工程文件
发表于 2019-07-16
STM32开发笔记21: USB驱动的移植

STM32开发笔记22: 手动添加驱动文件

单片机型号:STM32L053R8T6    我们可以通过STM32CubeMX生成工程代码,但是如果我们的工程已经建立完毕了,或者说我们在原有的工程上,开始新的项目设计,此时又需加入新的驱动,该如何呢?本文探讨其解决方法。    1、STM32CubeMX的驱动路径如下图所示,我们希望加入什么驱动,就直接将其对应的.c文件加入到工程中即可。    2、为了使该模块生效,我们还学将其使能。其使能宏,在stm32l0xx_hal_conf.h中,如下图所示。    3、上述工作完成后,我们就可以对工程进行编译了,至于驱动的具体调用方法,我们可以参看ST
发表于 2019-07-16
STM32开发笔记22: 手动添加驱动文件

STM32开发笔记23: 使用__weak修饰符

单片机型号:STM32L053R8T6在 HAL 库中,很多回调函数前面使用__weak 修饰符。 weak 顾名思义是“弱”的意思,所以如果函数名称前面加上__weak 修饰符,我们一般称这个函数为“弱函数”。加上了__weak 修饰符的函数,用户可以在用户文件中重新定义一个同名函数,最终编译器编译的时候,会选择用户定义的函数,如果用户没有重新定义这个函数,那么编译器就会执行__weak 声明的函数,并且编译器不会报错。 举个例子:我们打开工程模板,找到并打开文件stm32f4xx_hal.c 文件,里面定义了一个函数 HAL_MspInit,定义如下:__weak void 
发表于 2019-07-16

STM32开发笔记24:STM32L0低功耗设计——需求概述

单片机型号:STM32L053R8T6    这几篇日志将详细记录,自己应用stm32进行低功耗设计的全过程。    使用芯片:STM32L053R8T6    运行模式:        Range 1:电源电压限制在1.71-3.6V,CPU最大运行频率为32MHz。        Range 2:CPU最大运行频率为16MHz。        Range 3:CPU最大运行频率4.2MHz    低功耗模式: 
发表于 2019-07-16
STM32开发笔记24:STM32L0低功耗设计——需求概述

STM32开发笔记25:STM32L0低功耗设计-使用Keil和ST-Link下载程序

单片机型号:STM32L053R8T6    继续项目的开发工作,突然发现,程序不能够正常下载到单片机中了,提示如下图所示的错误,我使用的是keil和ST-Link。    这个问题在我第1次调试的时候发生过1次,我认为是我误操作将芯片烧坏了,因为当时又反复的焊接了一下芯片,也没有修好,就把这件事情放下了。    今天再次出现,自己感觉可能和低功耗有关,仔细查看刚刚下载的程序,里面上来程序就进入低功耗,没有任何退出语句,所以应该是CPU不响应下载命令了。    按照这种思路,先将单片机的复位引脚接地,然后点击下载按钮的同时,放开复位引脚,居然成功
发表于 2019-07-16
STM32开发笔记25:STM32L0低功耗设计-使用Keil和ST-Link下载程序

小广播

何立民专栏

单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved