基于单片机的电子时钟课程设计.docx
《基于单片机的电子时钟课程设计.docx》由会员分享,可在线阅读,更多相关《基于单片机的电子时钟课程设计.docx(14页珍藏版)》请在冰豆网上搜索。
![基于单片机的电子时钟课程设计.docx](https://file1.bdocx.com/fileroot1/2022-11/25/bc33a5f0-97ac-41ba-894b-5771d155d6cf/bc33a5f0-97ac-41ba-894b-5771d155d6cf1.gif)
基于单片机的电子时钟课程设计
第一章前言..............................................................1
第三章系统原理分析..............................................3
第四章硬件介绍......................................................4
5.1主程序...................................................................5
5.2数据的显示程序...................................................7
5.3键盘响应程序.......................................................8
附录一程序代码.....................................................11
附录二程序仿真图.................................................15
第一章前言
时钟,自从它发明的那天起,就成为人类的朋友,但随着时间的推移,科学技术的不断发展,人们对时间计量的精度要求越来越高,应用越来越广。
怎样让时钟更好的为人民服务,怎样让我们的老朋友焕发青春呢?
这就要求人们不断设计出新型时钟。
现今,高精度的计时工具大多数都使用了石英晶体振荡器,由于电子钟,石英表,石英钟都采用了石英技术,因此走时精度高,稳定性好,使用方便,不需要经常调校,数字式电子钟用集成电路计时时,译码代替机械式传动,用LED显示器代替显示器代替指针显示进而显示时间,减小了计时误差,这种表具有时,分,秒显示时间的功能,还可以进行时和分的校对,片选的灵活性好。
时钟电路在计算机系统中起着非常重要的作用,是保证系统正常工作的基础。
在一个单片机应用系统中,时钟有两方面的含义:
一是指为保障系统正常工作的基准振荡定时信号,主要由晶振和外围电路组成,晶振频率的大小决定了单片机系统工作的快慢;二是指系统的标准定时时钟,即定时时间,它通常有两种实现方法:
一是用软件实现,即用单片机内部的可编程定时/计数器来实现,但误差很大,主要用在对时间精度要求不高的场合;二是用专门的时钟芯片实现,在对时间精度要求很高的情况下,通常采用这种方法,典型的时钟芯片有:
DS1302,DS12887,X1203等都可以满足高精度的要求。
本文主要介绍用单片机内部的定时/计数器来实现电子时钟的方法,本设计由单片机AT89S51芯片和LED数码管为核心,辅以必要的电路,构成了一个单片机电子时钟。
第二章设计目的与要求
进行电路硬件设计和系统软件编程,以及仿真调试或制作。
一般3~5人一组,每组完成的内容不能雷同。
选择设计基于单片机的时钟显示器,数字钟是一个将“时”、“分”、“秒”显示计时装置。
它的计时周期为24小时,显示满刻度为23时59分59秒99毫秒,另外应有校时功能。
实现的功能:
在数字钟正常进行显示时,其显示周期为00:
00:
00至23:
59:
59,其中有五个按键,按下“暂停”键时钟停止走动,按下“开始”键时钟开始走动,按下“秒设置”时钟秒位自加1,加至60时向分位进1,按下“分设置”时钟分位自加1,加至60时向时位进1,按下“时设置”时钟秒位自加1,加至24时显示00。
第三章系统原理分析
系统设计中用到89C51单片机的部分功能:
包括内部定时器,键盘扩展,程序中断,串口通信等。
用一个六位的共阴极七段显示器,可通过一个输入/输出口作为显示器数据发送端;另一个输入/输出口的六位作为显示器各位的片选信号,另一个输入/输出口作为键盘扩展口使用。
系统原理图如图1所示。
P2.0-7
图1系统原理图
图2数字钟仿真图
第四章硬件介绍
AT89C51:
芯片共有40个引脚,引脚的排列顺序为从靠芯片的缺口左边那列逆时针数起,依次为1,2,3,4、、、40,其中芯片的1脚顶上有一个凹点。
在单片机的40个引脚中,电源引脚2根,外接晶体振荡器引脚2根,控制引脚4根以及4组8为可编程I/O引脚32根。
主要特性:
与MCS-51兼容;4K字节可编程闪烁存储器;寿命:
1000写/擦循环;数据保留时间:
10年;全静态工作:
0Hz-24Hz;三级程序存储器锁定:
128*8位内部RAM;32可编程I/O线;两个16位定时器/计数器;5个中断源;可编程串行通道;低功耗的闲置和掉电模式;片内振荡器和时钟电路。
主要管脚说明:
P0口:
P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门电流。
当P1口的管脚第一次写1时,被定义为高阻输入。
P0能够用于外部程序数据存储器,它可以被定义为数据/地址的第八位。
在FIASH编程时,P0口作为原码输入口,当FIASH进行校验时,P0输出原码,此时P0外部必须被拉高。
P1口:
P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流。
P1口管脚写入1后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。
在FLASH编程和校验时,P1口作为第八位地址接收。
P2口:
P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高,且作为输入。
并因此作为输入时,P2口的管脚被外部拉低,将输出电流。
这是由于内部上拉的缘故。
P2口当用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高八位。
在给出地址“1”时,它利用内部上拉优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容。
P2口在FLASH编程和校验时接收高八位地址信号和控制信号。
P3口:
P3口管脚是8个带内部上拉电阻的双向I/O口,可接收输出4个TTL门电流。
当P3口写入“1”后,它们被内部上拉为高电平,并用作输入。
作为输入,由于外部下拉为低电平,P3口将输出电流(ILL)这是由于上拉的缘故。
六位共阴级数码管:
cc表示共阴极的ac是共阳极的设计中所用的是7段六位共阴级数码管,如果要实现动态显示必须位码(1-6)轮流通低电位,也就是片选,段码控制数码管的显示.0-b,1-g,2-a,3-f,4-c,5-e,6-h,7-d。
图3数码管显示原理图
如图3数码管显示原理图所示,使用LED显示器时,要注意是共阴还是共阳,要注意区分这两种不同的接法。
为了显示数字或字符,必须对数字或字符进行编码。
七段数码管加上一个小数点,共计8段。
因此为LED显示器提供的编码正好是一个字节。
我们用的是共阴LED显示器,根据电路连接图显示16进制数的编码已列在下表。
0x3f,0x06,0x5b,0x4f,0x66,0x6d,
012345
0x7d,0x07,0x7f,0x6f,0x77,0x7c,
6789AB
0x39,0x5e,0x79,0x71,0x00
CDEF无显示
动态显示的特点是将所有位数码管的段选线并联在一起,由位选线控制是哪一位数码管有效,由另一位控制显示码值。
选亮数码管采用动态扫描显示。
所谓动态扫描显示即轮流向各位数码管送出字形码和相应的位选,利用发光管的余辉和人眼视觉暂留作用,使人的感觉好像各位数码管同时都在显示。
动态显示的亮度比静态显示要差一些,所以在选择限流电阻时应略小于静态显示电路中的。
我们这里正是利用的数码管动态显示来完成显示功能。
第五章软件实现与流程
5.1主程序
由于系统的主要功能都是由子程序来完成的,主程序基本上没什么事可做,只是利用调用子程序的方式实现的,主程序流程图如图3所示。
图3主程序流程图
5.2数据的显示程序
时钟数字显示涉及到两个操作:
发数据和改片选信号。
先发片选,再发数据。
用延时程序进行一个消影操作,这样就很好地解决了重影问题。
这样做的关键在于,在极短的一段时间内让显示器都不亮,等一切准备工作都做好了以后再发数据,只要显示频率足够快,是看不出显示器有闪烁的。
代码如下:
shi=hour/10;
ge=hour%10;
P3=0xfe;
P2=table1[shi];
delay(5);
P3=0xfd;
P2=table1[ge];
dp=1;
delay(5);
这段显示程序流程图如图4:
图4数据显示流程图
5.3键盘响应程序
键盘分编码键盘和非编码键盘,键盘上闭合键的识别由专用的硬件编码器实现,并产生按键编码号或键值的称为编码键盘,如计算机键盘。
而靠软件编程来识别的称为非编码键盘,在单片机组成的各种系统中,用的最多的是非编码键盘,也有用到编码键盘的,我们这里用的就是非编码键盘。
如图4键盘图所示,当按钮按下时;端口会变成低电平,我们设计一段扫描程序来判断那个端口是低电平来判断是否有按键按下。
键盘处理程序流程相对简单,只是简单的判键与处理。
当设置按键按下为低电平时,对应位数加1至满进制。
图5按键响应程序流程
第六章结束语
通过这次单片机设计,我加深了对课本专业知识的理解,平常都是理论知识的学习,在此次课程设计中,真正做到了自己查阅资料、完成一个基本电路的设计。
在此次的数字钟设计过程中,我更进一步地熟悉了芯片的结构及掌握了各芯片的工作原理和其具体的使用方法。
当然,在这个过程中我也遇到了困难,通过查阅资料,相互讨论,我准确地找出错误所在并及时纠正了,这也是我最大的收获,使自己的实验动手能力有了进一步的提高,让我对以后的工作学习有了更大的信心。
回顾起此次设计,感慨颇多,从理论到实践,我学到很多很多的东西,不仅巩固了以前所学过的知识,而且学到了很多在书本上没有学到过的内容。
通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才是真正的知识,才能提高自己的实际动手能力和独立思考的能力。
在设计的过程遇到了各种各样的问题,同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固,通过这次课程设计,把以前所学过的知识重新温故,巩固了所学的知识。
此次的课程设计,还让我知道了最重要的是心态,在你拿到题目时会觉得困难,但是只要充满信心,脚踏实地,就肯定会完成的。
参考文献
[1]张齐、朱宁西编著.《单片机系统设计与开发--基于Proteus单片机仿真和C语言编程》北京:
机械工业出版社.2008年
[2]马忠梅编著.《单片机的C语言应用程序设计(第4版)》.北京:
北京航天航空大学出版社.2007年
[3]李学礼编著.《基于Proteus的8051单片机实例教程》电子工业出版社,2008年
[4]戴佳戴、卫恒、刘博文编著.《51单片机C语言应用程序设计实例精讲》电子工业出版社.2008年
[5]侯玉宝编著.《基于Proteus的51系列单片机设计与仿真》电子工业出版社.2008年
附录一程序代码
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitset1=P1^0;//暂停
sbitset2=P1^1;//开始
sbitsets=P1^2;//秒设置
sbitsetm=P1^3;//分设置
sbitseth=P1^4;//时设置
sbitdp=P2^7;//小数点
ucharcodetable1[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
uchart0,hour,fen,miao,ge,shi,flag;
voiddelay(uintz)//延时子程序z的取值为这个函数的延时ms数,如delay(200);大约延时200ms
{
uintx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
voidinit()
{
TMOD=0x01;//TMOD的值表示定时器工作方式选择
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;//开总中断
ET0=1;//允许定时器0中断
TR0=1;//启动定时器
}
voidtimer0()interrupt1//定时器0的中断号是1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
t0++;
if(t0==20)
{
t0=0;
miao++;
if(miao==60)
{
miao=0;
fen++;
if(fen==60)
{
fen=0;
hour++;
if(hour==24)
hour=0;
}
}
}
}
voiddisplay(ucharhour,ucharfen,ucharmiao)
{
shi=hour/10;
ge=hour%10;
P3=0xfe;
P2=table1[shi];
delay(5);
P3=0xfd;
P2=table1[ge];
dp=1;
delay(5);
shi=fen/10;
ge=fen%10;
P3=0xfb;
P2=table1[shi];
delay(5);
P3=0xf7;
P2=table1[ge];
dp=1;
delay(5);
shi=miao/10;
ge=miao%10;
P3=0xef;
P2=table1[shi];
delay(5);
P3=0xdf;
P2=table1[ge];
delay(5);
}
voidkeyscan()
{
if(set1==0)
{delay(5);
if(set1==0)
{
TR0=0;
flag=1;
}
while(!
set1);
}
if(flag==1)
{if(sets==0)
{
delay(5);
if(sets==0)
{
miao++;
if(miao==60)
{
miao=0;
fen++;
if(fen==60)
{
fen=0;
hour++;
if(hour==24)
hour=0;
}
}
}
while(!
sets);
}
}
if(setm==0)
{
delay(5);
if(setm==0)
{
fen++;
if(fen==60)
{
fen=0;
hour++;
if(hour==24)
hour=0;
}
}
while(!
setm);
}
if(seth==0)
{
delay(5);
if(seth==0)
{hour++;
if(hour==24)
hour=0;
}
while(!
seth);
}
if(set2==0)
{
delay(5);
if(set2==0)
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
t0=0;
flag=0;
TR0=1;
}
while(!
set2);
}
}
voidmain()
{
init();
while
(1)
{display(hour,fen,miao);//调用显示子程序
keyscan();//调用键盘扫描子程序
}
附录二程序仿真图