51单片机(十三)—— 看门狗功能测试

一、看门狗介绍

        在由单片机构成的系统中,由于单片机的工作有可能受到外界电磁场的干扰,造成程序的跑飞,从而陷入死循环,程序的正常运行被打断,单片机控制的系统便无法继续工作,这样会造成整个系统陷入停滞状态,发生不可预测的后果,所以出于对单片机运行状态进行实时监测的考虑,便产生了一种专门用于监测单片机程序运行状态的芯片,俗称“看门狗(Watch Dog)”。

        加入看门狗电路的目的是使单片机可以在无人状态下实现连续工作,其工作过程为:看门狗芯片和单片机的一个I/O引脚相连,该I/O引脚通过单片机的程序控制,使它定时地往看门狗芯片的这个引脚上送入高电平(或低电平),这一程序语句是分散地放在单片机其它控制语句中间的,一旦单片机由于干扰造成程序跑飞而陷入某一程序段进入死循环状态时,给看门狗引脚送电平的程序便不能被执行到,这时,看门狗电路就会由于得不到单片机送来的信号,便对它与单片机复位引脚相连的引脚送出一个复位信号,使单片机复位,从而使单片机从程序存储器的起始位置重新开始执行程序,这样便实现了单片机的自动复位。

        通常,看门狗电路是通过将一个专门的看门狗芯片连接到单片机来实现的,不过这样会给电路设计带来复杂性,STC系列单片机内部自带了看门狗,看门狗有一个15位的计数器,在缺省状态下,看门狗计数器不计数,看门狗功能禁止。如果使能了看门狗功能,则计数器由0开始计数,计数到最大值32767时,则单片机便产生复位。因此程序要定时对看门狗计数器进行清零,以避免计数器溢出而引起系统复位,这称之为“喂狗”。如果程序跑飞陷入死循环,则无法喂狗,看门狗就可以迫使单片机复位。

        通过对相应的特殊功能寄存器的设置就可实现看门狗的应用。STC89系列单片机内部有一个专门的看门狗定时器寄存器WDT_CONTR,这个寄存器的定义如下

这个寄存器中各位的定义分别为:

EN_WDT:看门狗允许位,当这一位设置为1时,使能看门狗。

CLR_WDT:看门狗清0位,当这一位设置为1时,将看门狗的计数器清0。

IDLE_WDT:看门狗空闲模式位,当这一位置1时,看门狗计数器在空闲模式下计数,当这一位清0时,看门狗计数器在空闲模式下不计数。

PS2~PS0:看门狗计数器预分频系数。这三位用来设置看门狗计数器的计数周期。当采用12MHz的晶振,并采用12时钟模式时,PS2~PS0对预分频值和看门狗的溢出时间的设置如下表所示。

 

        溢出时间是如何计算的呢,这需要对单片机的时钟模式进行一定了解。

        单片机的厂家不同,单片机的时钟系统也会有些差别。我们只介绍STC单片机的时钟。单片机有一下几个周期概念:

(1)时钟周期:也称为震荡周期,它定义为时钟频率的倒数,例如单片机的外部晶振为12MHz,则它的时钟周期就是1/12us,时钟周期是单片机中最基本、最小的时间单位,在一个时钟周期内CPU仅完成一个最基本的动作。时钟脉冲是单片机最基本的工作脉冲,它控制着单片机的工作节奏。对于一个单片机来讲,时钟频率越高,单片机的工作速度就越快,但是,由于不同的单片机内部硬件电路和电器结构不同,所以需要的时钟频率范围也不一定相同,我们使用的STC89C系列单片机的时钟范围约为1MHz~40MHz。

(2)状态周期:它是时钟周期的两倍。

(3)机器周期:单片机基本操作周期,在一个操作周期内,单片机完成一项基本的操作,如取指令、存储器读写等。

(4)指令周期:它是CPU执行一条指令所需要的时间,一般一个指令周期含有1~4个机器周期。

        STC单片机有两种时钟模式,一种是单倍速,也就是12时钟模式,在该时钟模式下,12个时钟周期为一个机器周期;另一种是双倍速,又称为6时钟模式,在该时钟模式下,6个时钟器为一个机器周期,比12时钟模式快1倍。两种时钟模式可以通过烧写软件进行设置。如下图所示。一般情况我们用12时钟模式就可以了。

        看门狗计数器的时钟源为机器周期,采用12MHz晶振,则时钟源的频率为1MHz,时钟源的周期为1us。若PS2~PS0设置为100,则分频系数为32,那么看门狗计数器的计数周期为32us,计数器由0计数到32767的时间长度为32us*32768=1048576us。即溢出时间为1.0485秒。

二、实例测试

        这个实验的代码如下所示,

void main (void)
{
	WDT_CONTR=0x34;   //初始化看门狗,使能看门狗,溢出周期为1.0485s。 

	LED1=0;    //将P00口赋值0,对外输出低电平,灯点亮。
	delay1ms(500);   //延时0.5秒
	LED1=1;    //将P00口赋值1,对外输出高电平,灯熄灭。	
	for(;;)
	{
		WDT_CONTR=0x34;   //复位看门狗  
		delay1ms(500);    //延时0.5秒
	}
}

        烧写之后可以看到实验现象,开发板上的LED1闪1下之后熄灭。

        在这个实验中,程序首先使能了看门狗,并且让LED1闪一下,之后,程序不对LED1进行操作,只是每隔0.5秒喂一次看门狗。

        对程序进行一定修改,将for循环中的喂狗语句WDT_CONTR=0x34;   //复位看门狗  的前边打上双斜线//,将这一句隐去,这样程序只是使能了看门狗,而没有定时喂狗。将程序编译之后,将这个工程的HEX文件烧写到单片机中。烧写之后可以看到实验现象,开发板上的LED1每隔大约1秒闪一次,这是因为没有按时喂狗,单片机每隔1.0485s复位一次,每次复位之后LED1就闪一次。

        程序中使用了WDT_CONTR这个寄存器。而这个寄存器在reg52.h头文件中没有进行定义,因此程序在使用这个寄存器之前要对其进行定义。这个寄存器的地址为E1H,因此将其定义为:sfr  WDT_CONTR = 0xE1;

 

发布了97 篇原创文章 · 获赞 7 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/bhniunan/article/details/104399311