zoukankan      html  css  js  c++  java
  • Zigbee之旅(八):几个重要的CC2430基础实验——看门狗(转)

    一、承上启下

      再好的操作系统,不管是现在的Win7还是以后Win8、Win9,总会出现BlueScreen的时候,更何况是小小的单片机呢~ 电气噪声、电源故障、静电放电等不可预知的原因,都可能造成嵌入式系统的运行出现异常。

      而看门狗(Watch Dog),准确的说应该是看门狗定时器,则正是专门用来监测单片机程序运行状态的电路结构。其基本原理是:启动看门狗定时器后,它就会从0开始计数,若程序在规定的时间间隔内没有及时对其清零,看门狗定时器就会复位系统(相当于重启电脑),如下图所示(word画的,画得比较eggache~):

      查看原图(大图)

      下面我们就来介绍简单的看门狗应用方法:怎么放狗?怎么喂?若不喂,会出现什么情况?

      二、看门狗的故事

      (1)实验简介

      若喂狗,系统正常运行;若不喂狗,系统不断重启。

      (2)程序流程图

      (3)实验源码及剖析

    /*
        实验说明:看门狗实验,若不喂狗,系统一直重启。
    */
    
    #include <ioCC2430.h>
    
    #define led1 P1_0        
    #define led2 P1_1        
    #define led3 P1_2        
    #define led4 P1_3  
    
    /*系统时钟初始化
    -------------------------------------------------------*/
    void xtal_init(void)
    {
      SLEEP &= ~0x04;             //都上电
      while(!(SLEEP & 0x40));     //晶体振荡器开启且稳定
      CLKCON &= ~0x47;            //选择32MHz 晶体振荡器
      SLEEP |= 0x04;
    }
    
    /*LED初始化
    -------------------------------------------------------*/
    void led_init(void)
    {
      P1SEL  = 0x00;              //P1为普通 I/O 口
      P1DIR |= 0x0F;              //P1.0 P1.1 P1.2 P1.3 输出
     
      led1 = 1;                   //关闭所有LED
      led2 = 1;
      led3 = 1;
      led4 = 1;
    }
    
    /*看门狗初始化
    -------------------------------------------------------*/
    void watchdog_Init(void) 
    {
      WDCTL = 0x00;              //看门狗模式,时间间隔一秒
      WDCTL |= 0x08;             //启动看门狗
    }
    
    /*喂狗程序
    -------------------------------------------------------*/
    void FeetDog(void)  
    {
      WDCTL = 0xa0;
      WDCTL = 0x50;
    }
    
    /*延时函数(小于1秒。读者可以想一下,若大于1秒,会出现什么情况)
    -------------------------------------------------------*/
    void Delay(void)
    {
      unsigned int n;
      for(n=50000;n>0;n--);
      for(n=50000;n>0;n--);
      for(n=50000;n>0;n--);
      for(n=50000;n>0;n--);
      for(n=50000;n>0;n--);
      for(n=50000;n>0;n--);
      for(n=50000;n>0;n--);
    }
    
    /*主函数
    -------------------------------------------------------*/
    void main(void)
    {
      xtal_init();
      led_init();
      watchdog_Init();
    
      Delay();
      led1 = 0;         //点亮led1
     
      while(1)
      {
        FeetDog();      //喂狗指令(加入后系统不复位,小灯不闪烁;若注释,则系统不断复位,小灯每隔1s闪烁一次)
      }
    }

      从上面的源码可以看出,看门狗的操作方法非常简单,整个过程仅涉及一个新的SFR,即 WDCTL。下面给出CC2430中文手册里对其的具体描述:

      查看原图(大图)

      看门狗的使用可以总结为:选择模式 → 选择定时器间隔 → 放狗 → 喂狗

      (1)选择模式:

      看门狗定时器有两种模式,即“看门狗模式”和“定时器”模式。

      在定时器模式下,它就相当于普通的定时器,达到定时间隔会产生中断(你可以在ioCC2430.h文件中找到其中断向量为WDT_VECTOR);在看门狗模式下,当达到定时间隔时,不会产生中断,取而代之的是向系统发送一个复位信号。

      本实验中,通过 WDCTL.MODE=0 来选择为看门口模式。

      (2)选择定时间隔:

      如上图所示,有四种可供选择的时钟周期,为了测试方便,我们选择时间间隔为1s(即令 WDCTL.INT=00 )。

      (3)放狗:

      令 WDCTL.EN=1 ,即可启动看门狗定时器。

      (4)喂狗:

      定时器启动之后,就会从0开始计数。在其计数值达到32768之前(即<1s),若我们用以下代码喂狗:  

      WDCTL = 0xa0;

      WDCTL = 0x50;  

      则定时器的计数值会被清0,然后它会再次从0x0000开始计数,这样就防止了其发送复位信号,表现在开发板上就是:LED1会一直亮着,不会闪烁;

      若我们不喂狗(即把此代码注释掉),那么当定时器计数达到32768时,就会发出复位信号,程序将会从头开始运行,表现在开发板上就是:LED1不断闪烁,闪烁间隔为1s。(注:喂狗程序一定要严格与上述代码一致,顺序颠倒/写错/少写一句都将起不到清0的作用。)

      CC2430 小贴士

      做两点额外说明:

      (1)在 看门狗模式 下,若看门狗定时器已经使能,则对WDCTL.EN置0是无效的(即此位不能起到停止定时器的作用);

      (2)在 定时器模式 下,可以对WDCTL.CLR[0]写1来对定时器清零;写0到使能位WDCTL.EN将停止定时器,而写1到使能位将重新启动定时器从0x0000开始运行。

      (4)实验结果:

      若加上FeedDog函数,运行代码,发现LED1一直亮着(系统不复位);

      若注释掉FeedDog函数,运行代码,发现LED1以1s的间隔闪烁(系统每隔1s复位一次)。

      三、结语

      本节介绍了看门狗定时电路的原理和使用方法。在实际应用中,若需要较高的可靠性,则可将看门狗运用到系统中。当系统因某种原因出现停机状况(不能喂狗了)时,没人喂的狗就会狂吠起来:“主人,有异常,有异常!”

      对一个无线传感器网络来说,其运行时功耗的高低,是性能评价的至关重要的一方面。下一节,我们来讨论关于CC2430系统睡眠,以及其中断唤醒。

  • 相关阅读:
    一些对数学领域及数学研究的个人看法(转载自博士论坛wcboy)
    dynamic与var
    转载-V.I.Arnold, beyond a mathematician
    转载---青年问禅师
    转载-傅里叶级数的几何意义 – 巧妙记忆公式的方法
    转载--柯尔莫哥洛夫
    转载--黎曼
    动态规划复习
    几匹单调队列水题
    fastIO
  • 原文地址:https://www.cnblogs.com/zhangleiccst/p/2271056.html
Copyright © 2011-2022 走看看