数字时钟论文
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数字电子时钟设计
摘要:本系统以89C51单片机为核心,辅以晶振、键盘、LCD 显示、LED显示等电路组成,实现了一个由单片机控制的数字电子时钟系统。
它外带年、月、日、星期的显示,更具有整点报时功能。
主机使用LCD显示,用户界面友好。
该设计较好地实现了数字时钟的所有要求功能。
1 系统设计
1.1 设计任务与要求
1、设计一个有“时”、“分”、“秒”显示的电子钟
2、闹钟与整点报时系统
3、日历系统
1.2各模块方案选择和论证
1.2.1 计时模块
方案一:采用555数字电路来作为计时器。
用数字电路可以实现计时功能,功耗小,稳定性较高。
但是电路复杂。
方案二:采用单片机作为计时器。
51单片机功能比较广,虽然功耗大,但是它的定时器功能可以很好的实现本设计的计时模块,能够更好简化电路。
经比较在功耗无要求前提下,选择方案二。
1.2.2 闹钟和整点报时模块
方案一:采用数字电路实现闹钟和整点报时的功能。
使用74HC30芯片,稳定性高,但是电路设计规模较大,不便于操作。
方案二:采用单片机作为闹钟和整点报时的部分。
51单片机的定时器和中断功能可以实现闹钟和报时的功能。
操作方便,控制简单。
基于上一步选择单片机的基础上,方案二是最佳选择。
1.2.3 显示模块
方案一:采用LED显示。
LED数码管显示速度快,亮度高,显示清晰,控制也较为简单。
但是是功耗较大,显示的位数有限。
方案二:采用低功耗LED显示。
液晶有较低功耗,且能够较清晰的较多位数的数字和所有的字母。
其美观的用户界面是一个很大的优势。
为了较好地显示功能,选择方案二。
1.2.4电源模块
考虑到保持电路的简洁,系统采用了外接电源的方法,通过电源线和插针接入5V电压。
1.3设计分析
1.3.1系统框图
1.3.2电路说明
a. 计时模块:使用89C52单片机,其最小系统电路图见系统图。
b. 闹钟和报时模块:蜂鸣器和LED 引脚与单片机的I/O 口相连,另外LED 的引脚上各接一个10k 的上拉电阻,蜂鸣器和电源引脚接一个0.1uF 的去耦电容。
c. 液晶显示电路:把液晶的各个引脚接到单片机的P0口的对应位置,在液晶显示的的引脚上接上10k 的排阻作为上拉电阻。
d. 按键的设置:本系统总共需要四个按键,三个按键用于调时,一个按键用于控制闹钟的开与关。
2 系统的硬件实现
2.1 系统电路图(如上)
2.1.1 显示单元
1602液晶显示器
1.1602液晶显示器的优越性
①1602显示器有自带的存储器和指令系统,应用时只需把要显示的内容和显示的方式指令写入其内部的存储器即可,不需要复杂的外部电路系统,也不会用到太多的控制器时钟,从而保证了频率的宽度。
②液晶显示优于数码管的另外一点就是可以方便的显示字母和各种字符,因为1602自带了大量的字符内容。
这是数码管所办不到的。
③液晶显示器不需要复杂的外部电路,因为不用外部电路来实现其动态显示,这是应用1602液晶屏的重要原因之一。
2.1602基本信息
(1)读操作时序:
(2)写操作时序:
(3)外部电路:
2.2系统PCB图
3系统软件设计
3.1 软件实现功能:
用定时器实现计时功能,用中断实现闹钟,并输出到LCD显示。
3.2 软件流程图
3.3 系统程序
#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit en=P2^4;
sbit rs=P2^3;
sbit rw=P2^2;
sbit alarm=P2^6;
sbit key1=P3^4;
sbit key2=P3^5;
sbit key3=P3^6;
sbit key4=P3^7;
uchar code table0[]=" 0000-00-00 ";
uchar code table1[]=" 00:00:00";
uchar code
table5[7][10]={"MON","TUE","WED","THU","FRI","SAT","SUN"};
uchar code table4[]="alarm";
uchar
a,b,c,flag1,flag2,flag3,flag4,temp,numkey,numxq,num1=6,num2=5,numxq,n umalarm,num3;
int year1,year2,yue,ri,shi,fen,miao;
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void write_com(uchar com)
{
rw=0;
rs=0;
en=0;
P0=com;
delay(5);
en=1;
delay(5);
en=0;
}
void write_dat(uchar dat)
{
rw=0;
rs=1;
en=0;
P0=dat;
delay(5);
en=1;
delay(5);
en=0;
}
void YJinit()
{
uchar num,num1;
en=0;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);//清零
write_com(0x80);
for(num=0;num<12;num++)
{
write_dat(table0[num]);
delay(50);
}
write_com(0x80+12);
for(num=0;num<1;num++)
{
for(num1=0;num1<3;num1++) write_dat(table5[num][num1]);
}
write_com(0x80+40);
for(num=0;num<15;num++)
{
write_dat(table1[num]);
delay(50);
}
}
void display0(uchar add,int tim)//显示{
int sw,gw;
sw=tim/10;
gw=tim%10;
write_com(0x80+0x40+add);
write_dat(0x30+sw);
write_dat(0x30+gw);
}
void display1(uchar add,int tim) {
int sw,gw;
sw=tim/10;
gw=tim%10;
write_com(0x80+add);
write_dat(0x30+sw);
write_dat(0x30+gw);
}
void displayxq(uchar num,uchar numxq) {
uchar num1;
write_com(0x80+12);
for(num=numxq;num<numxq+1;num++) {
for(num1=0;num1<3;num1++) write_dat(table5[num][num1]);
}
}
void timer_init()
{
TMOD=0X11;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
EA=1;
ET1=1;
ET0=1;
TR1=0;
TR0=1;
}
void keyscan()
{
if(key1==0)
{
delay(5);
if(key1==0)
{
TR0=0;
numkey++;
while(!key1);
if(numkey==1)
{
write_com(0x80+0x40+14);
write_com(0x0f);
}
if(numkey==2)
write_com(0x80+0x40+11);
if(numkey==3)
write_com(0x80+0x40+8);
if(numkey==4)
write_com(0x80+1);
if(numkey==5)
write_com(0x80+3);
if(numkey==6)
write_com(0x80+6);
if(numkey==7)
write_com(0x80+9);
if(numkey==8)
write_com(0x80+12);
if(numkey==9)
write_com(0x80+13);
if(numkey==10)
write_com(0x80+14);
if(numkey==11)
{
numkey=0;
write_com(0x80+0x40+14);
write_com(0x0c);
TR0=1;
}
}
}
if(key4==0)//第四功能
{
delay(5);
if(key4==0)
{
uchar num;numalarm++;
flag3=1;
flag1=1;
b=0;
if(numalarm==2)
{
write_com(0x80+0x40);
for(num=0;num<5;num++) {
write_dat(table4[num]);
}
}
if(numalarm==2)
{
numalarm=0;
b=0;TR1=0;
flag1=0;
flag3=0;
write_com(0x80+0x40);
for(num=0;num<7;num++)
{
write_dat(table1[num]);
}
}
while(!key4);
}
}
if(numkey!=0) //第二功能键{
if(key2==0)
{
delay(5);
if(key2==0)
{
while(!key2);
if(numkey==1)
{
miao++;
if(miao==60)
miao=0;
display0(13,miao);
write_com(0x80+0x40+13);
}
if(numkey==2)
{
fen++;
if(fen==60)
fen=0;
display0(10,fen);
write_com(0x80+0x40+10);
}
if(numkey==3)
{
shi++;
if(shi==24)
shi=0;
display0(7,shi);
write_com(0x80+0x40+7);
}
if(numkey==4)
{
year1++;
if(year1==100)
year1=0;
display1(1,year1);
write_com(0x80+1);
}
if(numkey==5)
{
year2++;
if(year2==100)
year2=0;
display1(3,year2);
write_com(0x80+3);
}
if(numkey==6)
{
yue++;
if(yue==13)
yue=1;
display1(6,yue);
write_com(0x80+6);
while(!key2);
}
if(numkey==7)
{
ri++;
if(ri==32)
ri=1;
display1(9,ri);
write_com(0x80+9);
}
if(numkey==8)
{
write_dat(0x40+num1);
write_com(0x80+12);
num1++;
if(num1==24)
num1=6;
}
if(numkey==9)
{
uchar num;
write_dat(0x41+num);
write_com(0x80+13);
num++;
if(num==22)
num=0;
}
if(numkey==10)
{
write_dat(0x40+num2);
write_com(0x80+14);
num2++;
if(num2==24)
num2=4;
}
}
}
if(key3==0) //第三功能键
{
delay(5);
if(key3==0)
{
while(!key3);
if(numkey==1)
{
while(!key3);
miao--;
if(miao<0)
miao=59;
display0(13,miao);
write_com(0x80+0x40+13);
}
if(numkey==2)
{
fen--;
if(fen<0)
fen=59;
display0(10,fen);
write_com(0x80+0x40+10);
}
if(numkey==3)
{
shi--;
if(shi<0)
shi=23;
display0(7,shi);
write_com(0x80+0x40+7);
}
if(numkey==4)
{
year1--;
if(year1<0)
year1=99;
display1(1,year1);
write_com(0x80+1);
}
if(numkey==5)
{
year2--;
if(year2<0)
year2=99;
display1(3,year2);
write_com(0x80+3);
}
if(numkey==6)
{
yue--;
if(yue<1)
yue=12;
display1(6,yue);
write_com(0x80+6);
}
if(numkey==7)
{
ri--;
if(ri<1)
ri=31;
display1(9,ri);
write_com(0x80+9);
}
if(numkey==8)
{
write_dat(0x40+num1);
write_com(0x80+12);
num1--;
if(num1==5)
num1=24;
}
if(numkey==9)
{
int num;
write_dat(0x41+num);
write_com(0x80+13);
num--;
if(num<0)
num=22;
}
if(numkey==10)
{
write_dat(0x40+num2);
write_com(0x80+14);
num2--;
if(num2==4)
num2=24;
}
}
}
}
}
void main()
{
YJinit();
timer_init();
while(1)
{
P1=0xff;
if((shi==22)&&(fen==6)&&(flag1==1))//闹钟
{
alarm=~alarm;
delay(5);
TR1=1;
}
if((fen==0)&&(flag2==0)) //整点报时
{
flag4=1;
TR1=1;
}
keyscan();
if(a==18)
{
a=0;
miao++;
if(miao==60)
{
miao=0;
fen++;
if(fen==60)
{
fen=0;
flag1=0;
flag2=0;
shi++;
if(shi==24)
{
shi=0;
ri++;
numxq+=1;
if(numxq==8)
numxq=0;
if((year1*100+year2)%4==0&&(year1*100+year2)%100!=0||(year1*100+year2 )%400==0)//闰年月份
{
switch(yue)
{
case 1: if(ri==32)
{ ri=1;
yue++; }break;
case 2: if(ri==30)
{ ri=1;
yue++; }break;
case 3: if(ri==32)
{ ri=1;
yue++; }break;
case 4: if(ri==31)
{ ri=1;
yue++; }break;
case 5: if(ri==32)
{ ri=1;
yue++; }break;
case 6: if(ri==31)
{ ri=1;
yue++; }break;
case 7: if(ri==32)
{ ri=1;
yue++; }break;
case 8: if(ri==32)
{ ri=1;
yue++; }break;
case 9: if(ri==31)
{ ri=1;
yue++; }break;
case 10: if(ri==32)
{ ri=1;
yue++; }break;
case 11: if(ri==31)
{ ri=1;
yue++; }break;
case 12: if(ri==32)
{ ri=1;
yue++; }break;
}
if(yue==13)
{
yue=1;
year2++;
if(year2==100)
{
year2=0; year1++;
if(year1==100)
{
year1=0;
}
display1(1,year1);
}
display1(3,year2);
}
display1(6,yue);
}
else//平年月份
{
switch(yue)
{
case 1: if(ri==32)
{ ri=1;
yue++; }break;
case 2: if(ri==29)
{ ri=1;
yue++; }break;
case 3: if(ri==32)
{ ri=1;
yue++; }break;
case 4: if(ri==31)
{ ri=1;
yue++; }break;
case 5: if(ri==32)
{ ri=1;
yue++; }break;
case 6: if(ri==31)
{ ri=1;
yue++; }break;
case 7: if(ri==32)
{ ri=1;
yue++; }break;
case 8: if(ri==32)
{ ri=1;
yue++; }break;
case 9: if(ri==31)
{ ri=1;
yue++; }break;
case 10: if(ri==32)
{ ri=1;
yue++; }break;
case 11: if(ri==31)
{ ri=1;
yue++; }break;
case 12: if(ri==32)
{ ri=1;
yue++; }break;
}
if(yue==13)
{
yue=1;
year2++;
if(year2==100)
{
year2=0;
year1++;
if(year1==100)
year1=0;
display1(1,year1);
}
display1(3,year2);
}
display1(6,yue);
}
display1(9,ri);
displayxq(num3,numxq);
}
display0(7,shi);
}
display0(10,fen);
}
display0(13,miao);
}
}
}
void timer0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
a++;
}
void timer1() interrupt 3
{
TH1=(65536-25000)/256;
TL1=(65536-25000)%256;
b++;c++;
if((c%20==0)&&(flag4==1))//整点报时{
uchar num;temp=0xfe;
for(num=0;num<8;num++)
{
temp=_crol_(temp,1);
P1=temp;
delay(10);
}
}
if((c==240)&&(flag4==1))
{
c=0;
TR1=0;
flag2=1;
flag4=0;
}
if((b%15==0)&&(flag3==1))
{
uchar num;
write_com(0x80+0x40);
for(num=0;num<5;num++)
{
write_dat(table4[num]);
}
}
}
3 系统调试
3.1硬件调试
(1)液晶显示调试
接上电源,看液晶的显示,检查电路没有短路等,使其显示正常。
(2)键盘调试
调试液晶显示后,按下对应按键,检查不让电路短路,使按键可以调整显示的数字。
(3)闹钟调试
用按键调好闹钟,确保蜂鸣器正常鸣响。
(4)整点报时调试
按键调到整点,确保LED显示正常闪烁。
3.2 软件调试
本程序较大,采用C51语言编写。
采用自下而上的调试方法,先调试功能电路,再调试整个系统。
在调试过程中与硬件的调试相结合,提高了调试效率。
3.3 软硬件联合调试
当软件和硬件的基本功能分别调试后,进行软硬件联合调试及优化。
4 功能测试与结果分析
1、测试仪器
秒表、数字万用表、电源
2、功能
(1)液晶显示时间,用秒表测量数字钟走一秒需要的时间。
(2)当秒钟、分钟走到59后,下一步自动清零。
当时钟走到23后,下一步自动清零。
(3)当后一位走满一个周期后,前一位自动加一。
用秒表测数字钟走一分钟需要时间。
(4)在整点时,LED闪烁及时且不影响时钟正常行走。
(5)到达闹钟时间时,蜂鸣器及时鸣响,且鸣响可停,也不影响时钟的正常运作。
3、测试结果
时钟走一秒时间:1s; 时钟走一分时间:60s。
由实验结果看出基本技术指标达到题目设计要求。
5 结论与学习心得
从设计构想到完成成品,我遇到了很多的问题,这让我认识到,理论与实践的本质差异,理论要用于实践就要学会变通,而不是按部就班。
同时也加深了我对理论知识的记忆。
让我学到了很多课堂上学不到的东西,受益匪浅。
本系统以89C52芯片为核心部件,采用定时器和中断的方法实现计时和闹钟等功能。
系统的基本功能和发挥部分达到基本要求。
它是一个可以显示六位的数字时钟,并带有年、月、日以及星期的显示,外加闹钟和整点报时功能,是功能比较齐全的数字钟。
如果可以加入无线或者测温部分,相信本系统性能可以进一步提高。
附录一:元器件清单
1个11.0592Mhz晶振、
9个LED、
1个1602液晶、
1个蜂鸣管、
1个2k电位器、
2个电阻、
一片AT89C52芯片、
1个4.7uF/10V电解电容、
2个30pF和1个0.1uF瓷片电容、4个按键、
一排插针、一排插座、
1个40DIP插座、。