1、单片机的看门狗 - 及系列为什么要看门狗? 你家的看门狗是做什么的? “看门狗定时器”是这样一种东西,从功能上 说它可以让微控制器在意外状况下(比如软件 陷入死循环或跑飞)重新回复到系统上电状态, 以保证系统出问题的时候重启一次 。 就跟我们现在用电脑一样,死机了你就按一下 reset 键重启一次电脑,看门狗就是负责干这个 事儿的。它是52 单片机增加的一个功能,以前 Intel 8031 、AT 89C51 时代单片机片内 都没有“看门狗”功能,需要我们外扩看门狗 芯片,比如X5045 。 “看门狗”就是一个计数器,由于位数有限计 数器能够装的数值是有限的(比如8位的最多装 256个数、16
2、位的最多装65536个数),从开 启“看门狗”那刻起,它就开始不停的数机器 周期,数一个机器周期就计数器加,加到计 数器盛不下了(术语叫溢出)就就产生一个复 位信号,重启系统 。注解: 这里顺便说一下,一般教材上叫“看门狗定时 器”,其实定时器原理还是计数器,只是计的 是时钟周期,所以我为了初学者好理解叫统一 叫“计数器”,这里阐明一下。看门狗的看门原理 我们在设计程序时,先根据看门狗计数器的位 数 和系统的时钟周期 算一下计满数需要的时间, 就是说在这个时间内“看门狗”计数器是不会 装满的,然后在这个时间内告诉它重新开始计 数,就是把计数器清零,这个过程叫“喂狗 ”, 这样隔一段时间喂一次狗
3、,只要程序正常运行 他就永远计不满,一旦出现死循环之类的故障, 没有及时来清零计数器,就会导致装满了溢出, 他就重启系统,这就是 举个例子说:8051 单片机选用12MHz 晶振, 一个时钟周期为1us ,如果“看门狗计数器” 是16 位的,最大计数65536 个,那么从0开始 计到65535 需要约65ms,所以我们可以在程序 的50ms 左右清零一次计数器(“喂狗”), 让他重新从0 开始计,再过50ms ,再清, 这样下去只要程序正常运行,计数器永远不会 计满,也就永远不会被“看门狗”复位。 当然这个喂狗的时间是大家自己选的,只要不 超过65ms ,你选多少都可以,一般不要喂得 太勤,这
4、样单片机运行时间浪费了,比如你 1ms 喂一次就太勤了,也不要说那我65ms 喂一 次,这样太边缘,这样抗干扰能力就下降了, 最好是留一定的余量,这个就是设计者自己掌 握了,我一般是让计到90%左右就清一次。 每种单片机的“看门狗”实现方法不尽相同, 但是原理都一样,而且“看门狗”都是启动了 之后就不能被关闭,只能系统复位(重新断电 在上电)才能关闭 。设置 看门狗 的一般步骤如 下: 1. 设置“看门狗”相关寄存器, 启动 “看门狗”; 2. 隔一段时间清零一次,“喂狗”; 3. 如果程序正常,一直运行;如果程序出 错,没有按时“喂狗”,“看门狗”就在溢出 的时候复位系统。的看门狗 AT89
5、S52 单片机看门狗定时器是14 位的,最大 计数214=16384 个数,每计16384 个时钟周期 就溢出一次。也就是说如果使用12M 晶振的话, 至少应该在16.384ms 内喂一次狗。 STC89C5X 系列单片机由于采用了“预分频技 术”,它的溢出时间是=(N*Prescale*32768)/ 晶振频率 (不要问我为什么,他们就是这么设计的,我 们就这么用就行)。 其中N 是单片机的时钟周期,STC89C5X 系列单 片机提供6时钟周期和12时钟周期两种时钟周 期,可以在烧写程序时修改; Prescale 是预分频数,通过设置【看门狗控制 寄存器】 可以设置为2、4、8、16 、32
6、 、64 、 128 、256 ;怎么设置演示程序中有介绍; 晶振频率就是系统选用的晶振。 所以如果同样选择12MHz晶振,使用传统的12 时钟周期,它最小的溢出时间是 (12*2*32768 )/(12*106)=65.536ms ,最大 溢出时间是(12*256*32768 ) /(12*106) 8.38s 。如果选择256 分频,也就是 说只要在8.38 秒之内喂一次狗就可以了。 对于我们用户来说,看门狗的时间是越长越好, 这样可以节省更多的单片机资源,尤其是对时 间要求精准的系统,如果执行过程中我们不停 地“喂狗”,那么是比较浪费时间的。 所以 STC89C5X 系列单片机的看门狗更
7、有优势一些。 当然这个也是个人的选择,如果对时间要求的 不苛刻的话,勤喂几次狗也没关系。看门狗应用举例 STC89C52 最小单片机系统+ 两个指示灯串行口接口(用于下载程序和测试本次试验 关于实验的注意事项: 1. 本次试验使用的是11.0592MHz 晶振,设置 WDT_CONTR=(0011 0100)B ,32预分频,单片机使 用12指令周期模式。 计算看门狗溢出时间: 12*32*32768/(11059200) 1s 。 2. 本次试验的硬件电路很简单,就是最小系统上增 加两个LED 灯,原理图见正文,用户可以很容易实现。 * */ #include sfr WDT_CONTR=0
8、xE1; / 定义特殊 功能寄存器:STC 单片机看门狗控制寄存器 #define uchar unsigned char #define true 1 #define false 0 #define WEIGOU WDT_CONTR=0x34 / 看门狗启动设置 和“喂狗”操作 sbit LED=P16; / 信号灯, 系统正常工作就一闪一闪的 sbit LED_busy=P17; / 工作灯, 上电灭一会儿(约800ms ),然后正常工作的时候一直亮着;用于指示系 统是否重启 uchar timer0_ctr,i; const uchar str=“I love MCU!“; / 定义一句
9、话,让他从串口输出,只 有系统重启的时候才输出一次,所以也是用于验证看门狗有没有重启系统 / 延时函数,11.0592MHz 晶振下延时约xms 毫 秒 void delay_ms(unsigned xms) unsigned x,y; for(x=xms; x0; x-) for(y=110; y0; y-); / 主程序初始化函数 void InitMain() / 初始化时两盏灯都熄灭 LED=1; LED_busy=1; TMOD=0x21; / 定时器0 工作在方式1 ,作 为16 位定时器;定时器1 工作在方式2 ,作为串行口波特率发生器 TH0=0x4C; / 定时器0 装初值:
10、每隔 50ms 溢出一次 TL0=0x00; IE=0x82; /IE=(1000 0010)B, 使能定 时器0 中断 TR0=1; / 启动定时器0 / 串行口初始化程序 void InitCOM() SCON=0x50; /SCON=(0101 0000)B ,波特率不加倍,允许接收 TH1=0xFD; / 设置波特率 =9600bps TL1=TH1; TR1=1; / 启动定时器1 / 定时器0 中断服务程序程序,控制信号灯闪烁。如果系统正常运行,信号灯1.5 秒 闪一次 void Timer0_isr() interrupt 1 TH0=0x4C; TL0=0x00; timer0
11、_ctr+; if(timer0_ctr=30) TR0=0; / 定时器0 暂停,否则再次来中断会冲断程序 timer0_ctr=0; LED=0; delay_ms(100); LED=1; TR0=1; / 定时器0 重新启动 void main() WEIGOU; / 上来第一步设置看 门狗定时器,并且启动 InitMain(); InitCOM(); / 开机通过串口发送一次“I love MCU!” ,使用串口调试助手可以查看 / 由于在while 大循环外边,所以只要系统不重新启动,则上电后只会发送一 次,用于判断系统是否重启 i=0; while(stri!=0) SBUF=s
12、tri; while(TI=0); TI=0; i+; /while 大循环 while(true) / 约每隔800ms 喂一次狗,可以通过调整这里的喂 狗时间来验证看门狗是否有效 / 我们设置的看门狗约1 秒。所以可以用800 和2000 分别做一次试验,看是否会被看门狗复位 delay_ms(800); LED_busy=0; / 第一次上电约延时 800ms 工作灯点亮,如果系统不重启,他将一直亮着,用于指 示系统是否重启 WEIGOU; 89S52 看门狗使用方法 在ATMEL 的89S52 系列的89S52 与89C51 功能相 同。指令兼容。HEX 程序无需任何转换可以直 接使用
13、。89S52 比89C51 增加了一个看门狗功 能。89S52 的其它功能可以参见89C52 的资料。 看门狗具体使用方法如下: 在程序初始化中向看门狗寄存器 (WDTRST 地址是0A6H )中先写入01EH ,再 写入0E1H 。即可激活看门狗。的看门狗应用 在C 语言中要增加一个声明语句。 在AT89X51.h 声明文件中增加一行 sfr WDTRST = 0xA6; 程序代码 sfr WDTRST = 0xA6; main() WDTRST=0x1E; WDTRST=0xE1;/初始化看门狗。 While (1) WDTRST=0x1E; WDTRST=0xE1;/ 喂狗指令 注意事项: 1 89S51 的看门狗必须由程序激活后才开始 工作。所以必须保证CPU 有可靠的上电复位。 否则看门狗也无法工作。 2 看门狗使用的是CPU 的晶振。在晶振停振 的时候看门狗也无效。 3 89S51 只有14 位计数器。在16383 个机器 周期内必须至少喂狗一次。而且这个时间是固 定的,无法更改。当晶振为12M 时每16 个毫秒 需喂狗一次。