电子钟设计论文宋永义.docx
《电子钟设计论文宋永义.docx》由会员分享,可在线阅读,更多相关《电子钟设计论文宋永义.docx(29页珍藏版)》请在冰豆网上搜索。
电子钟设计论文宋永义
摘要
该电子时钟由AT89C51,BUTTON,74LS244,74LS164,共阳极数码管等构成,采用晶振电路作为驱动电路,由延时程序和循环程序产生的一秒定时,达到时分秒的计时,六十秒为一分钟,六十分钟为一小时。
而电路中五个控制按键拥有多种不同的功能,按下又松开,达到省电的,则可以通过按键实现分钟的累加,每按一次对应的小时和分钟加一。
应用Proteus的ISIS软件和Keil软件实现了单片机电子时钟系统的设计与仿真。
该方法仿真效果真实、准确,节省了硬件资源。
该电子钟具有显示时间和温度测量的功能。
关键词:
AT89C51控制按键温度测量74LS24474LS164
第1章设计说明
1.1引言
1957年,Ventura发明了世界上第一个电子表,从而奠定了电子时钟的基础,电子时钟开始迅速发展起来。
现代的电子时钟是基于单片机的一种计时工具,采用延时程序产生一定的时间中断,用于一秒的定义,通过计数方式进行满六十秒分钟进一,满六十分小时进一,满二十四小时小时清零。
从而达到计时的功能,是人民日常生活补课缺少的工具。
现在高精度的计时工具大多数都使用了石英晶体振荡器,由于电子钟、石英钟、石英表都采用了石英技术,因此走时精度高,稳定性好,使用方便,不需要经常调试,数字式电子钟用集成电路计时时,译码代替机械式传动,用LED显示器代替指针显示进而显示时间,减小了计时误差,这种表具有时、分、秒显示时间的功能,还可以进行时和分的校对,片选的灵活性好。
1.2设计任务
单片机是一门技术性、应用性很强的学科,实践教学是它的一个极为重要的环节。
不论是硬件扩展、接口应用还是编程方法、程序调试,都离不开实验教学。
如果不在切实认真地抓好学生的实践技能的锻炼上下功夫,单凭课堂理论课学习,势必出现理论与实践脱节,学习与应用脱节的局面。
本设计充分利用单片机的内部资源,结合基本的电路模块实现数字电子钟的设计和实时温度的采集。
基本要求如下:
(1)24小时计时功能:
用6位LED显示器显示时、分、秒。
(2)时间调整功能:
用功能移位键、功能加键和功能减键实现时间的调整。
(3)闹铃功能:
用定闹键配合功能移位键、功能加键和功能减键三个按键设定闹铃,并用蜂鸣器实现响铃功能。
(4)环境温度采集与显示功能:
选用温度传感器DS18B20采集环境温度,并用2位LED显示器显示环境温度。
在这里我们只考虑采集室内温度,即零度以上的温度。
1.3原理描述
1.3.1原理框图
本设计的总图原理框图如图1-1所示:
图1-1系统总体框图
1.3.2系统原理
AT89C51单片机作为微处理器MCU,是系统设计的核心部分。
显示模块为八位的数码管,前六位用于时间的显示,后两位显示当前的温度值。
按键部分位5个独立的按键,用于时间的调整和定时。
温度采集模块的核心部件是数字温度传感器DS1820。
闹铃部分用蜂鸣器来实现。
系统的工作原理是单片机的内部定时器模拟时钟信号,作为时间信息传给数码管的前六位,同时单片机一定的时间间隔分别采集温度传感器的温度信息并送至数码管的后两位和扫描键盘,若发现某个键盘被按下,则作出相应的处理。
定时时间到时,灯亮,蜂鸣器发出响声,响1分钟后自动停止。
时钟电路原理,在AT89C51芯片内部有一个高增益反相放大器,其输入端为芯片引脚XTAL1,输出端为引脚XTAL2。
而在芯片内部,XTAL1和XTAL2之间跨接晶体振荡器和微调电容,从而构成一个稳定的自激振荡器。
时钟电路产生的振荡脉冲经过触发器进行二分频之后,才成为单片机的时钟脉冲信号。
第2章硬件设计
硬件电路主要包括数码管驱动电路、温度采集电路、键盘接口电路、稳压电路和蜂鸣器驱动电路。
2.1硬件介绍
2.1.1AT89C51的简介
单片机是一种集成在电路芯片,是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU随机存储器RAM、只读存储器ROM、多种I/O口和中断系统、定时器/计时器等功能(可能还包括显示驱动电路、脉宽调制电路、模拟多路转换器、A/D转换器等电路)集成到一块硅片上构成的一个小而完善的计算机系统。
兼容标准MCS-51指令系统的AT89S51单片机是一个低功耗、高性能CHMOS的单片机,片内含4KB在线可编程Flash存储器的单片机。
它与通用AT80C51系列单片机的指令系统和引脚兼容。
AT89S51单片机片内的Flash可允许在线重新编程,也可用通用非易失性存储编程器编程;片内数据存储器内含128字节的RAM;有40个引脚,32个外部双向输入/输出(I/O)端口;具有两个16位可编程定时器;中断系统是具有6个中断源、5个中断矢量、2级中断优先级的中断结构;震荡器频率0到33MHZ,因此我们在此选用12MHZ的晶振是比较合理的;具有片内看门狗定时器;具有断电标志POF等等。
AT89S51具有PDIP,TQFP和PLCC三种封装形式。
上图就是PDIP封装的引脚排列,下面介绍各引脚的功能。
AT89C51引脚如图2-1所示:
图2-1AT89C51引脚
1.单片机的特点
单片机结构上的设计主要是满足控制的需要,因此,它在硬件结构、指令系统及I/O能力等方面均有其独特之处,其显著的特点之一就是具有非常有效的控制功能,故也可以把单片机成为微控制器。
与普通的微型计算机相比,单片机主要具有以下特点:
(1)体积小、结构简单、可靠性高:
单片机把各功能部件集成在一块芯片上,内部采用总线结构,减少了各芯片之间的连线,大大提高了单片机的可靠性与抗干扰能力。
另外,其体积小,对于强磁场环境易于采取屏蔽措施,适合于恶劣环境下工作。
(2)控制功能强:
单片机虽然结构简单,但是它“五脏俱全”,已经具备了足够的控制功能。
单片机具有较多的I/O口,CPU可以直接对I/O口进行I/O操作、算术操作、逻辑操作和位操作,指令简单而丰富。
所以单片机也是“面向控制”的计算机。
(3)低电压、低功耗:
单片机已可在2.2V的电压下运行,有的已能在1.2V或0.9V电压下工作;工耗降至μA级,一颗纽扣电池就可以长期使用。
(4)优异的性能价格比:
由于单片机构成的控制系统硬件结构简单、开发周期短、控制功能强、可靠性高,因此,在达到同样功能的条件下,用单片机开发的控制系统比用其他类型的微型计算机开发的控制系统价格更便宜。
2.1.2系统原理
常用的LED显示器有7段,这种显示器有共阳极和共阴级两种。
本设计采用共阳极LED显示器。
LED数码管如图2-2所示
图2-2LED数码管
系统电路原理图如图2-3所示:
图2-3系统原理图
2.2数码管驱动电路
本设计用的数码管为7SEG-MPX4-CA-BULL,是四位一体的共阳极红色数码管。
数码管采用动态扫描的方式显示。
由两片74LS244控制LED数码管的位选信号。
具体的电路连接如图2-4所示:
图2-4数码管驱动电路
图2-574LS164的管脚
寄存器74LS244用与数码管的位选信号的控制,移位寄存器74LS164用于段选信号的产生,即若要某一位数码管点亮,需要74LS244产生该位的选通信号同时需要74LS164产生一定的段点亮信号。
这些信号都是有单片机控制产生的。
本设计使用的数码管是共阳极的,要点亮某一位数码管,需要74LS244产生一个高电平的位选通信号,同时74LS164的八个输出引脚输出对应的数码管编码信号。
2.3键盘接口电路
该设计用了五个键盘,实现的功能却是比较完善,减少了硬件资源的损耗,该键盘可以实现小时和分钟的调节以及控制。
直接按下,则可以通过按键实现分钟的累加,每按一次分钟加一,也可实现小时的调节,同样每按一次小时加一。
达到时间调节的目的。
具体接口如图2-6所示
图2-6按键接口
第一个按键用于时间的调整,接在了单片机的外部中断0端,按键信号的产生由外部中断源产生,把时间调整键设为外部中断是因为,调整时间的时候时间不应该仍在走动,而中断正好符合这一特点。
其余四个键盘分别接单片机的P2.4~P2.7口,用扫描的方式检测按键是否被按下。
具体的操作如下:
调整时间:
K1用于调整时间,K2用于“时”的设定,K3用于“分”的设定,最后K4用于确认设定有效。
定时:
K5用于定时,K2用于“时”的设定,K3用于“分”的设定,最后K4用于确认设定有效。
具体操作如图2-7至图2-15所示:
图2-7正常工作状态
图2-8设定时间
图2-9时间设定小时加一
图2-10时间设定分钟加一
图2-11确认设定
图2-12设定闹钟
图2-13设定闹钟小时加一
图2-14设定闹钟分钟加一
图2-15确认设定
2.4主控模块AT89C51
AT89C51是一个8位单片机,片内ROM全部采用FLASHROM技术,晶振时钟为12MHz。
AT89C51是标准的40引脚双列直插式集成电路芯片,有4个八位的并行双向I/O端口,分别记作P0、P1、P2、P3。
第31引脚需要接高电位使单片机选用内部程序存储器;第40脚为电源端VCC,接+5V电源,第20引脚为接地端VSS,通常在VCC和VSS引脚之间接0.1μF高频滤波电容。
第3章软件仿真
3.1软件仿真
仿真软件使用的是Poteus栏中逐个选择你要使用的元器件,选择后单击OK将其拖拽到工程中,接下来将选好的所有元器件排列好并进行连线,确保电路图连接无误后,使用该软件仿真系统可以将已经编好的程序代码加载进AT89C51中仿真出结果。
加的文件要以.hex为后缀的文件。
加载的方法是在单片机上双击,打开EditComponent对话框,在ProgramFile项选择要加载的文件,加载完单击对话框右侧的OK键即可。
加载完文件以后,就可以进行系统仿真了。
仿真的方法是分别单击软件界面左下方的
可以开启仿真、单步执行、暂停仿真和停止仿真。
系统仿真图如图3-1所示
图3-1系统仿真图
该电子钟的闹铃功能如图3-2和3-3所示
图3-2实现闹铃功能仿真图
图3-3闹铃系统仿真图
3.2软件设计
3.2.1程序流程图
程序流程图图3-4所示:
图3-4程序流程图
3.2.2程序调试
编译软件使用Keil软件,调试的基本步骤为:
新建一个工程命名并保存、新建一个源程序文件命名并保存、将源文件添加进工程、向源文件中输入源程序、编译调试。
若出现什么错误,修改后重新编译,直至最后没有错误为止。
程序详见附录。
用Keil软件调试程序的界面如图3-5所示:
图3-5软件调试界面
3.2.3显示温度程序
voiddisplay_temp(charA)//显示温度
{
charshi,ge;
shi=A/10;
ge=A%10;
R=0;
R=1;
SBUF=table[shi];//向发送缓冲器SBUF中写数据
while(!
TI);//直到发送完8位数据
P1=0x40;
delay(30);
P1=0;
TI=0;
R=0;
R=1;
SBUF=table[ge];
while(!
TI);
P1=0x80;
delay(30);
P1=0;
TI=0;
}
第4章硬件制作
使用的元件:
AT89C51(1个),共阳极四段LED数码管(2个),74LS244(2个),74LS164(1个),发光二极管(红色1个,绿色1个),蜂鸣器(1个),按键开关(5个),12M晶体振荡器(1个),DS18B20(1个),10K电阻(2个),27pf电容(2个),100uf电解电容(1个),万用板(1块)。
元器件经过排列分布后,进行连线,将程序烧到AT89C51中,经过检测无误后做出实物如图4-1所示:
图4-1电子时钟实物
结论
本设计可以满足电子钟的常规应用要求,即可实现时间的调整和定时,外加温度的实时采集。
本设计直接采用寄存器和锁存器驱动数码管,没有用三极管驱动。
一方面,设计电路得到了简化。
另一方面,由于寄存器和锁存器的电流不够大,所以数码管的亮度不是特别的亮,但足以满足要求。
由于数码管的位数限制,本设计只用了两只数码管显示温度信息,所以温度的精度是1度,并且无法显示温度的正负。
在仿真的过程中遇到了很多困难,有很多元件不能在仿真软件上很快的找到,有许多细节的地方需要耐心的研究,这充分体现了耐心的重要性
通过这次电子钟的设计,对AT89C51单片机的内部资源得到了进一步的理解,使理论和实践得到了结合。
我知道,今后我的路还是很长,我要学的东西也有很多。
通过这次实习,我深刻的认识到计算机专业的路的不平坦,但我会以一种良好的态度去迎接每一个挫折和挑战。
参考文献
[1]张毅刚.单片机原理及应用[M].北京:
高等教育出版社,2003.
[2]吕凤翥.C++语言基础教程[M].北京:
清华大学出版社,1999.3.
[3]张齐,杜群贵.单片机应用系统设计技术[M].北京:
电子工业出版社,2004.8.
[4]孙传友,孙晓斌.测控系统原理与设计[M].北京:
北京航空航天大学出版社,2007.12.
[5]孙育才,孙华芳,王荣兴.单片机原理及应用[M].北京:
电子工业出版社,2003.
[6]李鸿.单片机原理及应用[M].湖南:
湖南大学出版社,2004.
附录
源程序如下
/************************************************************
电子钟设计源程序
*************************************************************/
#include
/*******************位定义***********************************/
sbitbee=P2^2;
sbitDQ=P2^1;
sbitR=P2^0;
sbitK2=P2^4;//按键
sbitK3=P2^5;
sbitOK=P2^6;
sbitRing=P2^7;
bitmark1,mark2;
/****************数码管编码***********************************/
charhour,minute,second,A,clockH,clockMin,aa;
charcodetable[]={0xc0,0xf9,0xa4,0xb0,
0x99,0x92,0x82,0xf8,0x80,0x90};
/****************函数原型声明*********************************/
voiddisplay_hour(char);
voiddisplay_minute(char);
voiddisplay_second(char);
voiddisplay_temp(char);
voiddisplay(char,char,char,char);
voidchu_shi_hua();
voidClocking();
voiddelay(int);
unsignedchartemplow_byte,temphi_byte;
unsignedcharow_reset(void);
unsignedcharread_bit(void);
voidwrite_bit(charbitval);
unsignedcharread_byte(void);
voidwrite_byte(charval);
voidwendu();
//////////////////////////////////main函数/////////////////////////
voidmain()
{
charchoice;
chu_shi_hua();
while
(1)
{
wendu();
if(Ring==0)
{
delay(100);
if(Ring==0)
choice=1;//定时键按下,则定时
}
else
choice=0;
switch(choice)
{
case0:
display(hour,minute,second,A);
break;
case1:
Clocking();
}
}
}
/********************************************************************
*函数名:
display(charhour,charminute,charsecond,charA)
*调用:
display_hour(hour)、display_minute(minute)、display_second(second)display_temp(A)
*作用:
显示时间信息和温度信息
********************************************************************/
voiddisplay(charhour,charminute,charsecond,charA)
{
display_hour(hour);
display_minute(minute);
display_second(second);
display_temp(A);
if(hour==clockH&&minute==clockMin)//闹钟
{
bee=0;
delay(100);
bee=1;
}
}
/********************************************************************
*函数名:
display_hour(charhour)
*调用:
delay()
*作用:
显示时
********************************************************************/
voiddisplay_hour(charhour)//显示时
{
charh1,h2;
h1=hour/10;
h2=hour%10;
R=0;
R=1;
SBUF=table[h1];
while(!
TI);
P1=0x01;
delay(20);
P1=0;
TI=0;
R=0;
R=1;
SBUF=table[h2];
while(!
TI);
P1=0x02;
delay(20);
P1=0;
TI=0;
}
/********************************************************************
*函数名:
display_minute(charminute)
*调用:
delay()
*作用:
显示分
********************************************************************/
voiddisplay_minute(charminute)//显示分
{
charmin1,min2;
min1=minute/10;
min2=minute%10;
R=0;
R=1;
SBUF=table[min1];
while(!
TI);
P1=0x04;
delay(20);
P1=0;
TI=0;
R=0;
R=1;
SBUF=table[min2];
while(!
TI);
P1=0x08;
delay(20);
P1=0;
TI=0;
}
/*******************************************************************
*函数名:
display_second(charsecond)
*调用:
delay()
*作用:
显示秒
********************************************************************/
voiddisplay_second(charsecond)//显示秒
{
charsec1,sec2;
sec1=second/10;
sec2=second%10;
R=0;
R=1;
SBUF=table[sec1];
while(!
TI);
P1=0x10;
delay(20);
P1=0;
TI=0;
R=0;
R=1;
SBUF=table[sec2];
while(!
TI);
P1=0x20;
delay(20);
P1=0;
TI=0;
}
/********************************************************************
*函数名:
display_temp(charA)
*调用:
delay()
*作用:
显示温度
********************************************************************/
voiddisplay_temp(charA)//显示温度
{
charshi,ge;
shi=A/10;
ge=A%10;
R=0;
R=1;
SBUF=table[shi];//向发送缓冲器SBUF中写数据
while(!
TI);//直到发送完8位数据
P1=0x40;
delay(30);
P1=0;
TI=0;
R=0;
R=1;
SBUF=table[ge];
while(!
TI);
P1=0x80;
delay(30);
P1=0;
TI=0;
}
/********************************************************************
*函数名:
chu_shi_hua()
*调用:
*作用:
初始化一些参数
********************************************************************/
voidchu_shi_hua()//初始化函数
{
SM0=0;//串行口设置为工作方式0
SM1=0;
aa=0;
mark1=1;
mark2=1;
hour=12;
minute=0;
second=30;
clockH=0;
clockMin=0;
K2=1;//键盘读之前先置1
K3=1;
OK=1;
TMOD=0X01;
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
EA=1;
ET0=1;
TR0=1;
EX0=1;
I