看门狗是一种能够在程序正常执行出现异常时自动重置程序的功能
在需要长期执行的代码中代码总是不可避免的因为某些原因导致执行异常,如果不能从异常中恢复正常执行过程可能会导致项目的停止。所以为程序代码添加上看门狗功能是很有用的。
在51单片机中,头文件并没有定义这个寄存器地址,不过查看单片机手册可以发现是有这个功能的(在STM32单片机中可以直接使用),看门狗的寄存器地址是 0xe1,在代码中直接定义即可
sfr WDT_CONTR = 0xe1;
这个寄存器使用0-5位共6位可以设置
其中
第6位是看门狗是否开启位,为1打开看门狗
第5位是看门狗清零位,设置为1表示重新计数,硬件会自动将此位清零
第4位是看门狗执行环境,设置为1表示在空闲模式计数,0为在空闲模式不计数
第1-3位是看门狗的定时器预分配值,也就是看门狗重置的时长,超过这个时间没有重置看门狗的寄存器就会直接导致程序被重置
以下是12M晶振下的溢出时间
000 = 2分频 = 65.5毫秒
001 = 4分频 = 131毫秒
010 = 8分频 = 262.1毫秒
011 = 16分频 = 524.2毫秒
100 = 32分频 = 1.0485秒
101 = 64分频 = 2.0971秒
110 = 128分频 = 4.1943秒
111 = 256分频 = 8.3886秒
计算公式 = (12 X 预分频 X 32768)/12000000
所以这里设置为 0x111110 = 0x3e;
表示开启看门狗,设置为重新计数,设置为在空闲模式计数,预分频110=大概4秒溢出时间
代码如下:
#include <reg52.h>
//看门狗的寄存器地址
sfr WDT_CONTR = 0xe1;
//LED灯展示效果
#define LED P2
unsigned char P32_STATUS = 1; //外部中断1的状态
sbit K1 = P1^4;
sbit K2 = P1^5;
sbit K3 = P1^6;
sbit K4 = P1^7;
sbit K5 = P3^5;
void delay10ms(unsigned int);
void main(void){
unsigned char num = 0;
WDT_CONTR = 0x3e;
IT0 = 1;
EX0 = 1; //允许中断
IT1 = 1;
EX1 = 1; //允许中断
EA = 1; //开启总中断
//开机闪烁
P2 = 0xff;
delay10ms(100);
P2 = 0xaa;
delay10ms(100);
P2 = 0x55;
delay10ms(100);
while(1){
//如果看门狗没有起效,将在这里死循环
P2 = num;
num++;
delay10ms(10);
WDT_CONTR = 0x3e;//重置看门狗计数值,防止程序被重置
}
}
void delay10ms(unsigned int c)
{
unsigned char a,b;
for(;c>0;c--)
for(b=38;b>0;b--)
for(a=130;a>0;a--);
}