近日李工发现,在调试过程中存在疑似单片机死机的情况,死机后必须重新上电,虽然不常见,但是作为一个bug还是需要修复一下。作为一个偏软件的人员,我首先想到了看门狗。
看门狗从功能上说它可以让单片机在意外状况下(比如程序陷入死循环)重新回复到系统上电状态,以保证系统出问题的时候重启一次。就跟我们用电脑一样,死机了你就按一下reset键重启一次电脑,看门狗就是负责干这个事儿的。
说明白点:“看门狗”就是一个计数器,由于位数有限计数器能够装的数值是有限的(比如8位的最多装256个数、16位的最多装65536个数),从开启“看门狗”那刻起,它就开始不停的数机器周期,数一个机器周期就计数器加1,加到计数器盛不下了(术语叫溢出)就就产生一个复位信号,重启系统。
每种单片机的“看门狗”实现方法不尽相同,但是原理都一样,而且“看门狗”都是启动了之后就不能被关闭(经过实验,及时是能为置低也不行),只能系统复位(重新断电在上电)才能关闭。设置“看门狗”的一般步骤如下:
1. 设置“看门狗”相关寄存器, 启动“看门狗”;
2. 隔一段时间清零一次,“喂狗”;
3. 如果程序正常,一直运行;如果程序出错,没有按时“喂狗”(计数器清零),“看门狗”就在溢出的时候复位系统。
对于STC单片机来说,启动看门狗功能很简单。
第一步:sfr WDT_CONTR=0xE1;//定义特殊功能寄存器:
第二步:配置 WDT_CONTR 寄存器 [-] [-] [EN_WDT] [CLR_WDT] [IDLE_WDT] [PS2] [PS1] [PS0]
EN_WDT: 看门狗允许位,置1启动看门狗,看门狗不能自动启动,需要设置该位后启动,一旦启动不能关闭(只能系统重新上 电和看门狗复位可以关闭)
CLR_WDT: 看门狗计数器清零位,置1清零看门狗计数器,当计数器开始重新计数,硬件清零该位.
IDLE_WDT: 单片机IDLE模式看门狗允许位,当IDLE_WDT=1时,单片机在IDLE模式(空闲模式)依然启用看门狗
PS2 PS1 PS0 Prescale
0 0 0 2
0 0 1 4
0 1 0 8
0 1 1 16
1 0 0 32
1 0 1 64
1 1 0 128
1 1 1 256
然后查手册可得看门狗时间(见图片),一般公式为看门狗溢出时间:(N*Prescale*32768)/晶振频率,其中N表示指令周期数N=12表示12时钟周期模式;N=6表示6时钟周期模式 。(可以不必计算手册上已经给出了20M 12M 11.0592M晶振对应的看门狗时间)
启动和喂狗只需 WDT_CONTR=0B 0011 0??? =0X3? (?为0-7越大时间越长) ( 空闲模式一般不关心,所以IDLE=0)
为了使用方便: #define WEIGOU WDT_CONTR=0x3? //看门狗启动设置和“喂狗”操作
第三步:在合适的地方喂狗,需要注意的是:在查询等待串口接受数据的时候,时间可能很长,这是只需要在串口接收程序中while(!RI){WEIGOU;}即可。 |