S3C2440看门狗

S3C2440看门狗
S3C2440看门狗

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

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

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

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

PCLK÷(Prescaler + 1)÷Division

其中Prescaler的取值范围为0~255,Division的取值为16,32,64和128。例如,当PCLK为50MHz时,设置Prescaler为249,Division为16,则看门狗定时器的时钟频率为12.5kHz。这两个参数由寄存器WTCON提供,除此以外,该寄存器还可以设置是否有效看门狗定时器的超时复位,是否有效看门狗定时器的超时中断等。看门狗定时器还有两个寄存器WTDAT和WTCNT,WTDAT用于确定超时期限,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

;

}

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 = 249,Division = 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); }

}

}

相关主题
相关文档
最新文档