您的位置 首页 元件

STC89C5X单片机“看门狗”原理详解

看门狗定时器是这样一种东西,从功能上说它可以让微控制器在意外状况下(比如软件陷入死循环)重新回复到系统上电状态,以保证系统出问题的

看门狗定时器”是这样一种东西,从功用上说它能够让微操控器在意外情况下(比方软件堕入死循环)从头回复到体系上电状况,以确保体系出问题的时分重启一次。就跟咱们现在用电脑相同,死机了你就按一下reset键重启一次电脑,看门狗便是担任干这个事儿的。它是52单片机添加的一个功用,曾经Intel 8031、……、AT 89C51年代单片机片内都没有“看门狗”功用,需求咱们外扩看门狗芯片,比方X5045。

  很多人初度触摸不太了解怎样用,书上也讲的含含糊糊,成心说的很杂乱很奥妙(可能是现在写书人的通病,生怕写的简略的他人觉得他没水平)。其实要是说理解点:“看门狗”便是一个计数器,因为位数有限计数器能够装的数值是有限的(比方8位的最多装256个数、16位的最多装65536个数),从敞开“看门狗”那刻起,它就开端不断的数机器周期,数一个机器周期就计数器加1,加到计数器盛不下了(术语叫溢出)就就发生一个复位信号,重启体系。

  注解:这儿趁便说一下,一般教材上叫“看门狗定时器”,其实定时器原理仍是计数器,仅仅计的是时钟周期,所以我为了初学者好了解叫统一叫“计数器”,这儿说明一下。

  理解了上面的原理,咱们在规划程序时,先依据看门狗计数器的位数和体系的时钟周期算一下计满数需求的时刻,便是说在这个时刻内“看门狗”计数器是不会装满的,然后在这个时刻内告知它从头开端计数,便是把计数器清零,这个进程叫“喂狗”,这样隔一段时刻喂一次狗,只需程序正常运转他就永久计不满,一旦呈现死循环之类的毛病,没有及时来清零计数器,就会导致装满了溢出,他就重启体系,这便是看门狗的看门原理,其实想想傻傻的、笨笨的。

  举个比方说:8051 单片机选用12MHz晶振,一个时钟周期为1us,假如“看门狗计数器”是16位的,最大计数65536个,那么从0开端计到65535需求约65ms,所以咱们能够在程序的50ms左右清零一次计数器(“喂狗”),让他从头从0开端计,再过50ms,再清,……,这样下去只需程序正常运转,计数器永久不管帐满,也就永久不会被“看门狗”复位。当然这个喂狗的时刻是咱们自己选的,只需不超越65ms,你选多少都能够,一般不要喂得太勤,这样单片机运转时刻浪费了,比方你1ms喂一次就太勤了,也不要说那我65ms喂一次,这样太边际,这样抗干扰才干就下降了,最好是留必定的余量,这个便是规划者自己把握了,我一般是让计到90%左右就清一次。

  每种单片机的“看门狗”完成办法不尽相同,可是原理都相同,而且“看门狗”都是发动了之后就不能被封闭,只能体系复位(从头断电在上电)才干封闭。设置“看门狗”的一般进程如下:
  1. 设置“看门狗”相关寄存器,发动“看门狗”;
  2. 隔一段时刻清零一次,“喂狗”;
  3. 假如程序正常,一向运转;假如程序犯错,没有准时“喂狗”,“看门狗”就在溢出的时分复位体系。

值得提一下:

  因为现在AT89S52运用比较广泛,所以我先说说ATMEL的看门狗;再说说本次实验用的STC89C52RC的看门狗;留意两个不相同!!!

  AT89S52单片机看门狗定时器是14位的,最大计数214=16384个数,每计16384个时钟周期就溢出一次。也便是说假如运用12M晶振的话,至少应该在16.384ms内喂一次狗。

  STC89C5X系列单片机因为采用了“预分频技能”,它的溢出时刻是=(N*Prescale*32768)/晶振频率(不要问我为什么,他们便是这么规划的,咱们就这么用就行)。

  • 其间N是单片机的时钟周期,STC89C5X系列单片机供给6时钟周期和12时钟周期两种时钟周期,能够在烧写程序时修正;
  • Prescale是预分频数,经过设置【看门狗操控寄存器】能够设置为2、4、8、16、32、64、128、256;怎样设置演示程序中有介绍;
  • 晶振频率便是体系选用的晶振。

  所以假如相同挑选12MHz晶振,运用传统的12时钟周期,它最小的溢出时刻是(12*2*32768)/(12*106)=65.536ms,最大溢出时刻是(12*256*32768)/(12*106)≈8.38s。假如挑选256分频,也便是说只需在8.38秒之内喂一次狗就能够了。戏谑的说:这只狗比较抗饿,J~~

  关于咱们用户来说,看门狗的时刻是越长越好,这样能够节约更多的单片机资源,尤其是对时刻要求精准的体系,假如履行进程中咱们不断地“喂狗”,那么是比较浪费时刻的。所以STC89C5X系列单片机的看门狗更有优势一些。当然这个也是个人的挑选,假如对时刻要求的不严苛的话,勤喂几回狗也不要紧。

  下面我就以STC89C52RC单片机为例说说典型的51单片机的看门狗程序如何写,关于STC89C52RC单片机的“看门狗”界说请看STC89C51RC-RD单片机运用说明。以下程序在Keil 2和Keil 3下调时经过,下载在本校的实验板上到达预期作用。STC89C52RC/54RD+/58RD+/516RD+单片机上测验正常运转。

  假如没有咱们的实验板,请依照下面的硬件原理图自己在最小体系上建立一个实验环境也很简单。

图1. STC89C52最小单片机体系+两个指示灯

图2. 串行口接口(用于下载程序和测验本次实验)

view source

print?

001 /***************************************************************************
002 程序功用:本程序演示STC51单片机看门狗程序
003 程序规划:燕山大学 鲁信琼
004 晶振挑选:11.0592MHz, 假如晶振不匹配,请修正延时函数参数
005 接受51单片机、P%&&&&&%单片机程序、VB/VC++上位机程序、电子产品软硬件规划开发作业
006 EMail: xqlu(at)ysu.net.cn QQ: 9790335
007
008 因为现在AT89S52很盛行,所以我先说说ATMEL的看门狗;再说说本次实验用的STC89C52RC的看门狗;留意两个不相同!!!
009
010 ★下面是关于ATMEL-51单片机看门狗的描绘
011 【看门狗计数器】(watchdog timer)是一个14位的计数器,它以机器周期(晶振频率/12)添加,当计数值计满(16383/0x3FFF)了就使单片机软复位;
012 当发动了【看门狗计数器】之后,咱们需求在它计数没有满之前复位计数器强制它不行以溢出,这个进程称作喂狗。
013
014 “看门狗”原理:
015 1. 体系上电并不发动看门狗计数器,经过设置【看门狗重置寄存器(WDTRST SFR)】发动【看门狗计数器】,一般设置是给WDTRST写入0x1E和0xE1发动;
016 2. 【看门狗计数器】一旦发动不行中止,除非是硬件RST或许看门狗的软复位才干使其间止;
017 3. 规划程序在恰当的时刻喂狗一次,使其不能计满,程序就能不间断履行;
018 4. 假如程序中呈现死循环或许履行某一步超时,看门狗计数器就管帐满溢出,(这个时分咱们以为程序没有依照预订方案履行–程序跑飞),则复位体系。
019
020 ★下面是关于STC89C5XX-51单片机看门狗的描绘
021 WDT_CONTR方位0xE1; [-] [-] [EN_WDT] [CLR_WDT] [IDLE_WDT] [PS2] [PS1] [PS0]
022 EN_WDT: 看门狗答应位,置1发动看门狗,看门狗不能主动发动,需求设置该位后发动,一旦发动不能封闭(只能体系从头上电和看门狗复位能够封闭)
023 CLR_WDT: 看门狗计数器清零位,置1清零看门狗计数器,当计数器开端从头计数,硬件清零该位。
024 IDLE_WDT: 单片机IDLE形式看门狗答应位,当IDLE_WDT=1时,单片机在IDLE形式(闲暇形式)仍然启用看门狗
025 PS2~PS0: 看门狗定时器预分频器,下表中Prescale表明预分频数
026 PS2 PS1 PS0 Prescale
027 0 0 0 2
028 0 0 1 4
029 0 1 0 8
030 0 1 1 16
031 1 0 0 32
032 1 0 1 64
033 1 1 0 128
034 1 1 1 256
035
036 看门狗溢出时刻:(N*Prescale*32768)/晶振频率,其间N表明指令周期数N=12表明12时钟周期形式;N=6表明6时钟周期形式
037
038 关于实验的留意事项:
039 1. 本次实验运用的是11.0592MHz晶振,设置WDT_CONTR=(0011 0100)B,32预分频,单片机运用12指令周期形式。
040 核算看门狗溢出时刻:[12*32*32768/(11059200)]≈1s。
041 2. 本次实验的硬件电路很简略,便是最小体系上添加两个LED灯,原理图见正文,用户能够很简单完成。
042 ***************************************************************************/
043 #include
044 sfr WDT_CONTR=0xE1;//界说特别功用寄存器:STC单片机看门狗操控寄存器
045 #define uchar unsigned char
046 #define true 1
047 #define false 0
048 #define WEIGOU WDT_CONTR=0x34 //看门狗发动设置和“喂狗”操作
049 sbit LED=P1^6;//信号灯,体系正常作业就一闪一闪的
050 sbit LED_busy=P1^7;//作业灯,上电灭一瞬间(约800ms),然后正常作业的时分一向亮着;用于指示体系是否重启
051 uchar timer0_ctr,i;
052 constuchar str[]=”I love MCU!”;//界说一句话,让他从串口输出,只需体系重启的时分才输出一次,所以也是用于验证看门狗有没有重启体系
053
054 /*************************************************************************/
055 //延时函数,11.0592MHz晶振下延时约xms毫秒
056 voiddelay_ms(unsigned xms)
057 {
058 unsigned x,y;
059 for(x=xms; x>0; x–)
060 for(y=110; y>0; y–);
061 }
062 /*************************************************************************/
063
064 /*************************************************************************/
065 //主程序初始化函数
066 voidInitMain()
067 {
068 //初始化时两盏灯都平息
069 LED=1;
070 LED_busy=1;
071
072 TMOD=0x21;//定时器0作业在方法1,作为16位定时器;定时器1作业在方法2,作为串行口波特率发生器
073 TH0=0x4C;//定时器0装初值:每隔50ms溢出一次
074 TL0=0x00;
075 IE=0x82;//IE=(1000 0010)B, 使能定时器0中止
076 TR0=1;//发动定时器0
077 }
078 /*************************************************************************/
079
080 /*************************************************************************/
081 //串行口初始化程序
082 voidInitCOM()
083 {
084 SCON=0x50;//SCON=(0101 0000)B,波特率不加倍,答应接纳
085 TH1=0xFD;//设置波特率=9600bps
086 TL1=TH1;
087 TR1=1;//发动定时器1
088 }
089 /*************************************************************************/
090
091 /*************************************************************************/
092 //定时器0中止服务程序程序,操控信号灯闪耀。假如体系正常运转,信号灯1.5秒闪一次
093 voidTimer0_isr() interrupt 1
094 {
095 TH0=0x4C;
096 TL0=0x00;
097 timer0_ctr++;
098
099 if(timer0_ctr>=30)
100 {
101 TR0=0;//定时器0暂停,不然再次来中止会冲断程序
102 timer0_ctr=0;
103 LED=0;
104 delay_ms(100);
105 LED=1;
106 TR0=1;//定时器0从头发动
107 }
108 }
109 /*************************************************************************/
110
111 voidmain()
112 {
113 WEIGOU;//上来第一步设置看门狗定时器,而且发动
114 InitMain();
115 InitCOM();
116
117 //开机经过串口发送一次“I love MCU!”,运用串口调试帮手能够检查
118 //因为在while大循环外边,所以只需体系不从头发动,则上电后只会发送一次,用于判别体系是否重启
119 i=0;
120 while(str[i]!=)
121 {
122 SBUF=str[i];
123 while(TI==0);
124 TI=0;
125 i++;
126 }
127
128 //while大循环
129 while(true)
130 {
131 //约每隔800ms喂一次狗,能够经过调整这儿的喂狗时刻来验证看门狗是否有用
132 //咱们设置的看门狗约1秒。所以能够用800和2000别离做一次实验,看是否会被看门狗复位
133 delay_ms(2000);
134 LED_busy=0;//第一次上电约延时800ms作业灯点亮,假如体系不重启,他将一向亮着,用于指示体系是否重启
135 WEIGOU;
136 }
137 }

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/xinpin/yuanjian/259287.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部