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

  在系统运行以后就启动了看门狗的计数器,看门狗就开始自动计数,如果到了一定的时间还不去清看门狗,那么看门狗计数器就会溢出从而引起看门狗中断,造成系统复位。所以在使用看门狗的时候要注意清除看门狗;

  看门狗是恢复系统的正常运行及有效的监视管理器(具有锁定光驱,锁定任何指定程序的作用,可用在家庭中防止小孩无节制地玩游戏,上网等)具有很好的应用价值;

独立看门狗:(使用的是独立时钟)

  IWDG由专用的32KHZ的低速时钟来驱动;因此,即使主时钟发生故障它仍然有效。IWDG最适合应用于那些需要看门狗做为一个在主程序之外,能够完全独立工作,并且对时间精度要求较低的场合; 

  重要寄存器:

    键值寄存器(IWDG_KR):与喂狗、允许访问IWDG_PR\IWDG_RLR寄存器、启动看门狗相关    

    预分频寄存器(IWDG_PR):设置分频值

    重装载寄存器(IWDG_RLR):        

    状态寄存器(IWDG_SR)

操作步骤:(将独立看门狗使能、开启)

  1、向IWDG_KR写入0x5555.

    通过这部,我们取消IWDG_PR和IWDG_RLR的写保护,使后面可以操作这两个寄存器。设置IWDG_PR和IWDG_RLR的值;

    这两步设置看门狗的分频系数,和重装载的值。由此,就可以知道看门狗的喂狗时间,该事件的计算方式:Tout = 40khz/(4×2^rlr)当然这个值是粗略的计算值,因为时钟不准确,所以无法得到准确的喂狗时间;

  2、向IWDG_KR写入0xAAAA

    通过这句,将使stm32重新加载IWDG_RLR的值到看门狗计数器里面,也是用该命令来喂狗。

  3、向IWDG_KR写入0XCCCC

    通过这句,启动看门狗;

 通过上面3步,我们启动了stm32的看门狗,使能了看门狗,在程序里面就必须间隔一定时间来喂狗,否则将导致程序复位。

 配置实例: 

 void IWDG_Configuration(void)
{
//使能对寄存器IWDG_PR和IWDG_RLR的写操作
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
//设置IWDG预分频值256:
//40K/256 = 156HZ(6.4ms) 5s/6.4ms=781;
IWDG_SetPrescaler(IWDG_Prescaler_256); //设置IWDG重装载值,要小于0xfff(因为寄存器是12位的)
IWDG_SetReload();
//按照IWDG重装载寄存器的值 重新载入IWDG计数值;
IWDG_ReloadCounter();
IWDG_Enable(); //使能IWDG
} 

窗口看门狗: 

  windowWD由APB1时钟分频后得到的时钟驱动,通过可配置的时间窗口来检测应用程序非正常的过迟或过早的行为。WWDG最适合那些要求看门狗在精确计时窗口起作用的应用程序; 

  窗口看门狗通常被用来检测由外部干扰或不可预见的逻辑条件造成的应用程序背离正的运行序列而产生的软件故障;除非递减计数器的值在T6位(第6位)变成0前被刷新,此看门狗电路在达到可编程的时间周期时,会产生一个MCU复位。在递减计数器达到窗口寄存器之前,如果递减计数器值的第7位(在控制寄存器中)被刷新,那么也将产生一个MCU复位。这表明递减计数器需要一个有限的窗口中被刷新;

  T6即窗口看门狗的自减计数器的第六位(最高位),该计数器的时钟来源于PCLK/4096/预设分频数。在该计数器的T6变为0后(小于0X40, 100 0000)就会引发复位。这个窗口的下限。而当计数器的值在大于窗口寄存器的窗口值之前就被修改的话,也会引发一场复位,这个窗口值的上限,窗口值是由用户自己设定的,根据实际要求要设计窗口值,但一定要确保窗口值大于0X40,否则窗口就不存在了;

  计算超时的公式如下:

    Twwdg = Tpclk1×4096×2^WDTB×(T[5:0]+1); (ms)

    其中:

        Twwdg:WWDG超时时间  WDTB:寄存器配置的值,可取:0、1、2、3

        Tpclk1:APB1以ms位单位的时钟间隔;一般是确定的,为36Mhz;

  控制寄存器:WWDG_CR 低8位有效,T[6:0]用来存储看门狗的计数值,随时间更新的;每个PCLK1周期减1.当该计数器的值从0X40变为0X3F的时候,将产生看门狗复位;(这个是喂狗太晚了,已经减到了下限)

  WDGA位则是看门狗的激活位,该位由软件置1,以启动看门狗,并且一定注意该位一旦设置,就只能在硬件复位后才能清零了;

  配置寄存器:WWDG_CFR:低10位有效

    低7位设置的是复位最早值W(这个是窗口上限);

    第8,9位是:时基,可取00,01、10、11

    第10位是提前唤醒中断;

操作步骤:

  1、使能WWDG时钟

    WWDG不同于IWDG,IWDG有自己独立的40khz的时钟,不存在使能问题。而WWDG使用的是PCLK1的时钟,需要先使能时钟;

  2、设置WWDG_CFR和WWDG_CR寄存器

    在时钟使能完后,我们设置WWDG的CFR和CR两个寄存器,对WWDG进行配置。包括使能窗口看门狗、开启中断、设置计数器初始值T、设置窗口值并设置分频数WDGTB等;

  3、开启WWDG中断并分组

    在设置完WWDG后,需要配置该中断的分组及使能;

  4、编写中断服务函数

    若没有在规定时间段内喂狗,就引起软件复位。在中断服务函数里将状态寄存器的EWIF位清空;

    如果启动了看门狗并且允许中断,当递减计数器等于0x40时产生早期唤醒中断(EWI) ,它可以被用于重装载计数器以避免WWDG复位。

 void WWDG_Configuration(void)
{
//使能APB1外设WWDG时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE); //看门狗节拍=(36/4096)/8 = 1098hz 略等1ms
WWDG_SetPerscaler(WWDG_Prescaler_8);
//窗口上限值为0x45
WWDG_SetWindowValue(0x45);
//看门狗使能并初始化定时器为0x7f
//计数器一直随时间递减;
//减到0x45到0x40之间必须喂狗(重新载入初值)
//否则复位,
WWDG_Enable(0x7f);
//clear EWI flag
WWDG_ClearFlag();
//Enable EWI interrupt
WWDG_Enable(); }

stm32之watchdog的更多相关文章

  1. STM32之EXTI——外部中断

    互联网的广大网友,大家早上中午晚上好.EXTI...故名思义..EX表外,出..I表示Intrrupt..所以合起来就是外部中断...说到这..我觉得我最近的六级水平(背单词)又进了一步,稍微自夸了下 ...

  2. 【转】keil+stm32+jlink利用swd方式进行printf输出

    出处:http://www.douban.com/note/248637026/ ----------------------------------------------------------- ...

  3. STM32学习笔记(六) SysTick系统时钟滴答实验(stm32中断入门)

    系统时钟滴答实验很不难,我就在面简单说下,但其中涉及到了STM32最复杂也是以后用途最广的外设-NVIC,如果说RCC是实时性所必须考虑的部分,那么NVIC就是stm32功能性实现的基础,NVIC的难 ...

  4. stm32中断服务函数

    你打开stm32的启动文件,例如startup_stm32f10x_hd.s 里面有很多中断跳转的入口.用白话说就是固件库帮你写好了发生什么中断时跳转到哪里,这些名字是一个函数名,你要把这些函数写出来 ...

  5. STM32 NVIC

    在stm32中是要配置nvic的.何为nvic,对于我这样的初学者来说,直观感受就是在设置为中断后 还需要配置 中断的优先级nvic就是搞这个的. 那么具体的需要配置些什么那? void NVIC_C ...

  6. MDK+硬件仿真器实现debugprintf()-stm32

    MDK+硬件仿真器实现debugprintf()-stm32 1MDK工程设置如下 2其中stm32debug.ini文件内容为 /********************************** ...

  7. Qt 控制watchdog app hacking

    /************************************************************************** * Qt 控制watchdog app hack ...

  8. STM32启动过程--启动文件--分析

    一.概述 1.说明 每一款芯片的启动文件都值得去研究,因为它可是你的程序跑的最初一段路,不可以不知道.通过了解启动文件,我们可以体会到处理器的架构.指令集.中断向量安排等内容,是非常值得玩味的. ST ...

  9. STM32工程中出现 error: A1163E: Unknown opcode R0, , expecting opcode or Macro错误分析及处理

    最近测试以前的一个程序,一般都是打开以前写的程序修改参数直接测试 但是发现以前的编译后出现错误. 奇怪了,以前的出现都是调试好了的啊,一般都是没有错误的,迅速找问题 跳转到错误代码行 代码区域 Hea ...

随机推荐

  1. Structs 2

    1  redirect.redirectaction和chain 的区别 当使用type="redirectAction" 或type="redirect"提交 ...

  2. ZYB's Premutation(有逆序数输出原序列,线段树)

    ZYB's Premutation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

  3. 入门Html

    html 超文本标记语言(Hypertext Markup Language),用于描写网页文档的标记语言,最新的版本为5.0.由万维网制定 和更新,其实它本质还是文本文件,只不过需要浏览器来解释显示 ...

  4. SASS安装的那些事

    *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...

  5. 关于left join 和 inner join

    今天遇到一个逻辑很复杂的SQL,虽然写出来了,但是并没有完全体会,找了找资料,算是摸清楚了left join和inner join 的实际意义. 感谢PCJIM的文章,写的非常明白,原文地址:http ...

  6. KMP算法的一个C++实现

    本文参考阮一峰老师的KMP算法,重点是“部分匹配表”的建立.算法可参考 http://kb.cnblogs.com/page/176818/ . /* * kmp.cpp * Author: Qian ...

  7. android设置按钮按下的不同效果图

    <!-- 按钮设置按下去的不同效果的方式,设置android:background属性, 下面的 button_select实际上是button_select.xml --> <Bu ...

  8. virtual host

    <VirtualHost *:80>     ServerAdmin webmaster@dummy-host.php100.com     DocumentRoot "G:/w ...

  9. 高级UNIX环境编程2

    perror("error:") ;  strerror 日历时间:time_t (1970.1.1开始的秒数)     struct timeval (秒数和微秒)  struc ...

  10. Apache中RewriteCond规则参数介绍(转)

    CodeIgniter2.0已经出来有20多天了呢~也就是我一直用的php框架(CI).一直都在研究jquery,倒是把CI给忘到一边去了,呵呵~~今天公司事情不是很多,于是开始熟悉一下CI2.0的一 ...