- 浏览: 590281 次
- 性别:
- 来自: 深圳
文章分类
- 全部博客 (300)
- Web前端 (27)
- Java疑难 (60)
- 面试 (59)
- 汇编语言 (1)
- 计算机组成原理 (2)
- 操作系统 (3)
- 计算机网络 (6)
- C/C++疑难 (9)
- SSH (2)
- Web开发 (15)
- 故障 (3)
- 软件开发 (16)
- Portal开发 (1)
- 后台开发 (6)
- 数据库 (35)
- 设计模式 (4)
- 数据结构与算法 (4)
- Linux (3)
- 项目管理 (10)
- 多线程 (12)
- 嵌入式 (9)
- 网络编程 (4)
- 架构设计 (20)
- 软件工具技巧 (7)
- 并行并发 (4)
- 窗口编程 (7)
- 串口编程 (0)
- Flex (2)
- 协议 (1)
- 通讯方式 (4)
- 性能分析优化 (5)
- 测试相关 (4)
- 海量数据处理 (2)
- JAVA核心技术 (10)
- SOA (3)
- 攻略规划 (1)
- 爬虫/搜索 (2)
- 正则表达式 (1)
- A Comparison Of NoSQL Database Management Systems And Models (1)
最新评论
-
charles751:
分析的很好!但有一点:只要同步组合操作就可以了,不一定非要sy ...
Vector 是线程安全的? -
S346618898:
core Java中有一段:Vector类对自己的所有可修改方 ...
Vector 是线程安全的? -
code_cj:
基本上明白了.但执行顺是否应该是/etc/profile -& ...
profile bashrc bash_profile之间的区别和联系 -
xd2008ck:
各自有各自的场景吧楼主不要太激进了
Vector 是线程安全的? -
zwt2001267:
写的不错,赞一个
Vector 是线程安全的?
“看门狗定时器”是这样一种东西,从功能上说它可以让微控制器在意外状况下(比如软件陷入死循环)重新回复到系统上电状态,以保证系统出问题的时候重启一次 。 就跟我们现在用电脑一样,死机了你就按一下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. 串行口接口(用于下载程序和测试本次试验)
001
|
/***************************************************************************
|
002
|
程序功能:本程序演示STC51单片机看门狗程序
|
003
|
程序设计:燕山大学 鲁信琼
|
004
|
晶振选择:11.0592MHz, 如果晶振不匹配,请修改延时函数参数
|
005
|
承接51单片机、PIC单片机程序、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 <REG52.H>
|
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
|
const
uchar str[]=
"I love MCU!"
;
//定义一句话,让他从串口输出,只有系统重启的时候才输出一次,所以也是用于验证看门狗有没有重启系统
|
053
|
|
054
|
/*************************************************************************/
|
055
|
//延时函数,11.0592MHz晶振下延时约xms毫秒
|
056
|
void
delay_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
|
void
InitMain()
|
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
|
void
InitCOM()
|
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
|
void
Timer0_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
|
void
main()
|
112
|
{
|
113
|
WEIGOU;
//上来第一步设置看门狗定时器,并且启动
|
114
|
InitMain();
|
115
|
InitCOM();
|
116
|
|
117
|
//开机通过串口发送一次“I love MCU!”,使用串口调试助手可以查看
|
118
|
//由于在while大循环外边,所以只要系统不重新启动,则上电后只会发送一次,用于判断系统是否重启
|
119
|
i=0;
|
120
|
while
(str[i]!=
'\0'
)
|
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
|
}
|
发表评论
-
计数器与定时器有何区别
2012-12-31 22:01 2218计数器是当你开始从0开始计数时一直不停的开始记数!除非你 ... -
正确区分LJMP、AJMP、SJMP、JMP指令
2012-12-16 13:53 1810无条件转移指令(共4条)LJMP addr16 ; PC〈 ... -
volatile
2012-12-06 21:24 664volatile的本意是“易变的” 由于访问寄存器的速度要快过 ... -
单片机里面输入与输出
2012-10-11 09:37 1008把单片机看成是一个箱子,引脚就是外面的管子。 通过引脚给 ... -
SPI接口
2012-10-10 14:41 3517文章出处http://hi.baidu.com/wooutst ... -
宏作用
2012-10-09 11:33 935宏定义作用: (1)方便程序的修改 上面的#d ... -
单片机内部中断和外部中断——摘自《删繁就简单片机入门到精通》
2012-10-09 10:13 952每个周末丁丁小朋 ... -
IAR产生HEX文件的设置
2012-09-24 16:18 2550方法一 1、首先选择项目 2、Proje ...
相关推荐
8051单片机看门狗原理和C语言演示程序(以STC89C52RC单片机为例)
STC89C52单片机开发板PDF原理图+软件程序例程源码(48例): 28 一分钟倒计时 29 温度计DS18B20 3 点亮四个LED灯2 30 通过矩阵按键与数码管 31 抢答器 32 秒表(可暂停) 33 门铃 34 交通灯 35 计数器计数 36 红外...
STC89C5151单片机
STC89C52RC单片机开发板PDF原理图,包括常用的接口及外围电路,可以做为你的学习设计参考。
[Altium_Designer]_STC89C52单片机最小系统原理图+PCB文件
stc89c52单片机开发板电路原理图。主要包括模拟量采集ADC,AD/DA转换。485传输,点阵模块接口,红外发送,温湿度传感器,蜂鸣器,超声波模块,按键,指示灯,最小系统,外扩接口,USB供电以及串口传输,4位七段...
stc89c51单片机引脚功能介绍.pdfstc89c51单片机引脚功能介绍.pdfstc89c51单片机引脚功能介绍.pdfstc89c51单片机引脚功能介绍.pdfstc89c51单片机引脚功能介绍.pdfstc89c51单片机引脚功能介绍.pdf
STC89C52单片机掉电数据保存程序,代码清晰易懂!
STC89C51单片机最小系统开发板AD设计资料 原理图+PCB+3D图
ad软件用的stc89c51单片机芯片的封装库元件
基于STC89C52单片机的交通灯设计讲解.docx基于STC89C52单片机的交通灯设计讲解.docx基于STC89C52单片机的交通灯设计讲解.docx基于STC89C52单片机的交通灯设计讲解.docx基于STC89C52单片机的交通灯设计讲解.docx基于...
STC89C52RC单片机学习板PDF原理图+配套试验例程KEIL源码程序(105例): 10 LED循环左移 100.12864液晶基础显示 101.1602动态显示 102.红外解码1602液晶显示 103.红外解码数码管显示 105 NRF24L01开发板一 11 LED循环...
基于STC89C52单片机的秒表程序,请多指教!
stc89系列 单片机是指一个集成在一块芯片上的完整计算机系统。尽管他的大部分功能集成在一块小芯片上,但是它具有一个完整计算机所需要的大部分部件:CPU、内存、内部和外部总线系统,目前大部分还会具有外存。同时...
STC89C52RC单片机开发板PDF原理图
51单片机最小系统原理图,STC89C52单片机,宏晶科技单片机。51单片机最小系统原理图,STC89C52单片机,宏晶科技单片机。51单片机最小系统原理图,STC89C52单片机,宏晶科技单片机。51单片机最小系统原理图,STC89C52...
基于STC89C52单片机的烟雾报警器软件设计.pdf
该程序源代码用于STC89C52RC单片机智能小车测速、按键调速、红外避障综合实验。 1、源代码开发软件:keil; 2、程序对应处理器是:STC89C52RC(51单片机); 3、智能小车电机驱动芯片是:L293D; 4、智能小车电机为:...
单片机设计电路之STC89C52RC实验板原理图及PCB图