看门狗原理及51运用

您所在的位置:网站首页 看门狗定时器的作用有哪些 看门狗原理及51运用

看门狗原理及51运用

2024-07-12 11:23| 来源: 网络整理| 查看: 265

本文在http://www.360doc.com/content/11/1124/13/854187_166998577.shtml的基础上进行删改整理,侵删。

作用

程序发生死循环的时候(跑飞),能够自动复位

原理

启动看门狗计数器 计数器计时 指定时间内不对计数器赋值(喂狗)(主程序跑死,无法喂狗) 溢出,发出复位信号

“看门狗”就是一个计数器,由于位数有限计数器能够装的数值是有限的(比如8位的最多装256个数、16位的最多装65536个数),从开启“看门狗”那刻起,它就开始不停的数机器周期,数一个机器周期就计数器加1,加到计数器盛不下了(术语叫溢出)就就产生一个复位信号,重启系统。

设置步骤

1、设置“看门狗”相关寄存器, 启动“看门狗”; 2、隔一段时间清零一次,“喂狗”; 3、如果程序正常,一直运行;如果程序出错,没有按时“喂狗”,“看门狗”就在溢出的时候复位系统

以STC89C5X系列单片机为例

时间设置 它的溢出时间是=(NPrescale32768)/晶振频率(不要问我为什么,他们就是这么设计的,我们就这么用就行)。

其中: 1、N是单片机的时钟周期,STC89C5X系列单片机提供6时钟周期和12时钟周期两种时钟周期,可以在烧写程序时修改; 2、Prescale是预分频数,通过设置【看门狗控制寄存器】可以设置为2、4、8、16、32、64、128、256。 3、 晶振频率就是系统选用的晶振。

所以如果同样选择12MHz晶振,使用传统的12时钟周期,它最小的溢出时间是(12232768)/(12106)=65.536ms,最大溢出时间是(1225632768)/(12106)≈8.38s。

看门狗寄存器 WDT_CONTR位置0xE1; [-] [-] [EN_WDT] [CLR_WDT] [IDLE_WDT] [PS2] [PS1] [PS0]

1、EN_WDT: 看门狗允许位,置1启动看门狗,看门狗不能自动启动,需要设置该位后启动,一旦启动不能关闭(只能系统重新上电和看门狗复位可以关闭) 2、 CLR_WDT: 看门狗计数器清零位,置1清零看门狗计数器,当计数器开始重新计数,硬件清零该位。 3、 IDLE_WDT: 单片机IDLE模式看门狗允许位,当IDLE_WDT=1时, 单片机在IDLE模式(空闲模式)依然启用看门狗 4、 PS2~PS0: 看门狗定时器预分频器,下表中Prescale表示预分频数

PS2 PS1 PS0 Prescale 0 0 0 2 0 0 1 4 0 1 0 8 0 1 1 16 1 0 n0 32 1 0 1 64 1 1 0 128 1 1 1 256

程序

/*************************************************************************** ★下面是关于ATMEL-51单片机看门狗的描述 【看门狗计数器】(watchdog timer)是一个14位的计数器,它以机器周期(晶振频率/12)增加, 当计数值计满(16383/0x3FFF)了就使单片机软复位; 当启动了【看门狗计数器】之后,我们需要在它计数没有满之前复位计数器强制它不能够溢出, 这个过程称作喂狗。 "看门狗"原理: 1. 系统上电并不启动看门狗计数器,通过设置【看门狗重置寄存器(WDTRST SFR)】 启动【看门狗计数器】,一般设置是给WDTRST写入0x1E和0xE1启动; 2. 【看门狗计数器】一旦启动不可停止,除非是硬件RST或者看门狗的软复位才能使其停止; 3. 设计程序在适当的时间喂狗一次,使其不能计满,程序就能不间断执行; 4. 如果程序中出现死循环或者执行某一步超时,看门狗计数器就会计满溢出, (这个时候我们认为程序没有按照预定计划执行--程序跑飞),则复位系统。 本次实验说明: 1. 本次试验使用的是11.0592MHz晶振,设置WDT_CONTR=(0011 0101)B,64预分频, 单片机使用12指令周期模式。计算看门狗溢出时间:[12*64*32768/(11059200)]≈2s。 2. 本次实验,程序复位led会闪烁,程序正常工作时led熄灭,可以通过改变延迟时间看效果 ***************************************************************************/ #include sfr WDT_CONTR=0xe1; sbit led=P1^0; void delayms(unsigned int xms) { unsigned int i,j; for (i=xms;i>0;i--) for(j=110;j>0;j--); } void main() { WDT_CONTR=0x35; led1=0; delayms(500); led1=1; while(1) { delayms(1000); WDT_CONTR=0x35; } }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3