s3c2440看门狗定时器的应用

来源:互联网 发布:蓝光播放器软件 mac 编辑:程序博客网 时间:2024/05/16 14:59

 

看门狗定时器的主要作用是在程序因为干扰而跑飞后,能够使系统复位,不至于使系统永远的死下去。

 

它的原理与一般的定时器没有多大区别,就是先要设置好一段时间,当超过这段时间后,就从当前运行的程序中跳出进入中断处理程序中。但两者的主要差别是,一般的定时器中断是我们希望它发生的,因此我们不会在定时器中断发生前的那个时间段内干预它;而看门狗定时器中断是我们不希望它发生的,因此我们要想方设法地避免其发生。主要的方法就是在中断发生前,重新对看门狗定时器的寄存器进行赋值,使它的定时器重新开始计时。这种方法俗称喂狗,形象地比喻就是一条看门狗每隔一段时间(比如说一个小时)就会饿,所以就要叫唤,唯一使它不叫的方法就是给它喂食,那么下次叫唤的时间就是从当前喂食起的一个小时后。因此只要在上次喂食后的一个小时内再给它喂食,它就永远不会叫唤。

 

s3c2440的看门狗定时器不仅可以引起系统复位,还可以引起一般的中断,因此s3c2440的看门狗定时器可以当作一般的定时器使用。

 

s3c2440看门狗定时器的时钟频率的公式为:

PCLK÷(Prescaler + 1)÷Division

其中Prescaler的取值范围为0~255Division的取值为163264128。例如,当PCLK50MHz时,设置Prescaler249Division16,则看门狗定时器的时钟频率为12.5kHz。这两个参数由寄存器WTCON提供,除此以外,该寄存器还可以设置是否有效看门狗定时器的超时复位,是否有效看门狗定时器的超时中断等。看门狗定时器还有两个寄存器WTDATWTCNTWTDAT用于确定超时期限,WTCNT为当前看门狗定时器的计数值,在第一次设置看门狗超时时间时,这两个寄存器都要被写入超时时间的初始值。当要启动超时中断时,还要设置必要的中断寄存器,

 

下面这个程序就是一个看门狗定时器的实例。该程序就是正常的跑马灯程序,但加了一个看门狗定时器。我们设置的看门狗定时器超时时,只会触发中断,不会引起系统复位。在中断函数内,蜂鸣器会响。我们设置看门狗定时器的超时期限为4秒,为了不让程序进入看门狗中断,必须在该期限内,往寄存器WTCNT内写数,迫使看门狗定时器重新开始计时。

 

 

#define _ISR_STARTADDRESS 0x33ffff00

#define pISR_WDT_AC97           (*(unsigned *)(_ISR_STARTADDRESS+0x44))  

#define U32 unsigned int

 

#define rGPBCON    (*(volatile unsigned *)0x56000010)      //Port B control

#define rGPBDAT    (*(volatile unsigned *)0x56000014)       //Port B data

#define rGPBUP     (*(volatile unsigned *)0x56000018) //Pull-up control B

#define rSRCPND     (*(volatile unsigned *)0x4a000000)     //Interrupt request status

#define rINTMSK     (*(volatile unsigned *)0x4a000008)      //Interrupt mask control

#define rINTPND     (*(volatile unsigned *)0x4a000010)      //Interrupt request status

#define rSUBSRCPND  (*(volatile unsigned *)0x4a000018)    //Sub source pending

#define rINTSUBMSK  (*(volatile unsigned *)0x4a00001c)    //Interrupt sub mask

 

#define rWTCON   (*(volatile unsigned *)0x53000000)   //Watch-dog timer mode

#define rWTDAT   (*(volatile unsigned *)0x53000004)   //Watch-dog timer data

#define rWTCNT   (*(volatile unsigned *)0x53000008)   //Eatch-dog timer count

 

void delay(int a)

{

       int k;

       for(k=0;k<a;k++)

              ;

}

 

void __irq watchdog(void)

{

       rGPBDAT |= 1;             //蜂鸣器响

      

       //清中断标志位

       rSRCPND = 0x1<<9;

       rSUBSRCPND = 0x1<<13;

       rINTPND = 0x1<<9;

}

 

void Main(void)

{

       int light;

       int temp;

       int i;

       rGPBCON = 0x015551;                     //B0输出,给蜂鸣器;B5~B8输出,给LED

       rGPBUP  = 0x7ff;

 

       rWTCON = 0xf9<<8;                  //Prescaler = 249Division = 16,时钟频率为12.5kHz

                                                        //禁止看门狗复位

       rWTDAT = 50000;               //设置看门狗定时器超时时间为4秒(50÷12.5

       rWTCNT = 50000;

       rWTCON |= (1<<5)|(1<<2);         //开启看门狗定时器中断

       rSRCPND = 0x1<<9;

       rSUBSRCPND = 0x1<<13;

       rINTPND = 0x1<<9;

       rINTSUBMSK = ~(0x1<<13);      //打开中断子屏蔽

       rINTMSK = ~(0x1<<9);                     //打开中断屏蔽

 

       pISR_WDT_AC97 = (U32)watchdog;

 

       light = 0x10;

       light = light<<1;

       temp = light | 1;

       rGPBDAT = ~temp;

       delay(500000);

       while(1)

       {

              for (i=0;i<3;i++)

              {

                     light = light<<1;

                     temp = light | 1;

                     rGPBDAT = ~temp;

                     delay(500000);

              }

 

              rWTCNT = 50000;               //喂狗,重新赋值,防止中断

 

              for (i=0;i<3;i++)

              {

                     light = light>>1;

                     temp = light | 1;

                     rGPBDAT = ~temp;

                     delay(500000);

              }

       }

}

 

如果我们把程序中红色的那条语句注释掉,则看门狗定时器可以被看成是一个一般的定时器,即每隔4秒钟,蜂鸣器会响一下。如果我们使能看门狗定时器超时复位,则一定要加上这一句,否则系统会每隔4秒钟复位一次。