多功能电脑时钟.docx
《多功能电脑时钟.docx》由会员分享,可在线阅读,更多相关《多功能电脑时钟.docx(14页珍藏版)》请在冰豆网上搜索。
多功能电脑时钟
目录
一、功能描述1
二、方案设计1
2.1系统分析1
2.2器件选择1
三、软件设计2
3.1操作功能设计2
3.2程序编制思想2
3.3程序流程图3
四、程序调试3
五、心得体会4
六、参考文献5
附录1:
电路原理图6
附录2:
程序7
多功能电脑时钟设计报告
一、功能描述
1、实时显示当前时间即北京时间(时、分)。
2、可修改北京时间(时、分)。
3、可设定闹铃时间(时、分)。
4、按设定闹铃时间定时报时,报时时长为10秒钟。
5、具有显示星期和修改星期的功能。
6、具有秒表功能,能启动、暂停、停止秒表,启到后实时显示秒、百分秒。
7、能实现整点报时。
二、方案设计
2.1系统分析
根据系统功能要求,可将系统组成结构分成四大部分:
单片机控制中心、键盘接口、时钟显示和声音报时,如下图为系统的组成结构图。
其中,单片机控制中心是核心。
MCU根据按键输入,可切换不同的显示模式或设置不同的参数。
时钟显示完成北京时间或秒表时钟或星期的信息。
声音报时可完成闹铃和整点报时的提示。
2.2器件选择
选用STC89C51芯片,频率为11.0592MHz。
由于系统要求显示小时和分钟,采用四位LED数码管显示即可。
按键是用来设置北京时间或闹钟时间或启动秒表等功能的,设置三个按键:
模式键(K_Mode)、UP键(K_UP)、DOWN键(K_DN)。
选用蜂鸣器作为闹铃。
三、软件设计
3.1操作功能设计
根据系统功能描述,可以分为:
北京时间功能、闹铃功能、秒表功能星期显示功能。
我们通过对K_Mode键按下的次数计数,用Mode计数,Mode的次数就代表了不同的模式,每个模式都有与之相对应的指示灯,每个模式的功能如下:
Mode0:
按键每按下时显示北京时间模式,此时,四个指示灯全灭,显示格式为:
小时.分钟(如:
09.50,为9点50分),按K_UP或者K_DN键对系统没影响,每到整点时,要进行3秒钟的报时。
Mode1:
按键按下一次时,进入修改北京时间的小时模式,四个指示灯依次为亮灭灭灭,按K_UP或者K_DN键对小时进行修改。
Mode2:
按键按下两次时,进入修改北京时间的分钟模式,四个指示灯依次为灭亮灭灭,按K_UP或者K_DN键对分钟进行修改。
Mode3:
按键按下三次时,进入修改闹铃时间的小时模式,四个指示灯依次为灭灭亮灭,按K_UP或者K_DN键对闹铃小时进行修改。
Mode4:
按键按下四次时,进入修改闹铃时间的分钟模式,四个指示灯依次为灭灭灭亮,按K_UP或者K_DN键对闹铃分钟进行修改。
Mode5:
按键按下五次时,进入秒表模式,四个指示灯依次为亮亮亮亮,显示格式为:
秒百分秒(如12.90为当前秒表计时到12秒900毫秒),在此种模式下,K_UP键设为用来启动/暂停秒表、K_DN键设为用来对秒表进行清零。
Mode6:
按键按下六次时,进入星期的显示和修改模式,四个指示灯依次为亮亮灭灭,显示格式为(ΓΓΓX),X表示星期,可以通过按K_UP或者K_DN键对X修改。
3.2程序编制思想
使用定时器0来定时,定时5ms,运用定时器的中断来实现这些功能,显示是用的数码管的动态扫描,每5ms扫描一位数码管,20ms循环一次。
设置一些标志位,实时时间显示的标志位,星期显示的标志位,闹铃时间显示的标志位,秒表显示的标志位,在不同的模式下,我们要使该模式下的标志位有效,从而进行此模式的显示,通过按键进行不同的操作。
每个标志位有效时,数码管显示的内容就不一样。
闹钟的实现是用一个子函数,没5ms调用一次函数,把北京时间与设定的闹铃时间比较,如果相等就使蜂鸣器有效。
闹铃时间的长短可以用一个变量对秒计数,当计数值小于我们设定的值时,就是蜂鸣器有效,当大于等于设定的值时就关闭蜂鸣器。
整点报时很好实现,在中断函数里,当分钟等于60时,小时要自增1,我们可以在此时是蜂鸣器有效,有用一个变量对秒计数,当秒等于我们设定的值时,就关闭蜂鸣器。
3.3程序流程图
图2流程图
四、程序调试
按下编译后,生成“hex”文件,通过软件将其下载至单片机中,不是我们想要的结果,对程序要进行不断的调试。
我认为在此次程序编写和调试中解决了一个比较大的问题:
几个模式下,数码管的不同显示,我们是在秒表的基础上进行设计,我们在按Mode键时,数码管显示的内容没有切换,显示的还是北京那时间,按K_UPK_DN键没有任何反应,只有显示和设定北京时间;最开始我们的显示程序是写在主函数里的,参考了一些好的程序后,我们借鉴了他们的思想,通过设置不同的标志位,标志位有效时,在中端函数里进行不同的显示。
我们设置了7个模式,对每个模式的功能及操作进行调试,我们在秒表模式下,按下启动/暂停、清零都能实现,不过按启动/暂停时有时候显示的是北京时间,原来是在秒表模式下,我们要把其他模式的标志位要关掉,改正后,这个问题就解决了。
闹铃的调试时,本来我们是设置的响1分钟,并且可以通过一个按键关断闹铃,但是在第二次设置闹钟时,闹铃就不会响了。
最后我们只好让闹铃响20s,然后自动关闭,
五、心得体会
经过几个周的单片机设计,我们从中学到了很多的东西。
刚开始设计时,老师给我们的任务很简单,就叫我们设计灯的闪烁。
那时候我们对单片机都还不熟悉,一下午才把那个任务完成了。
然后就是数码管的动态显示,计数器,秒表,最后才是电脑时钟的设计。
我们从简单的单片机设计开始,一步一步的增加难度。
电脑时钟的设计,是在秒表的基础上慢慢的添加一个一个的功能,然后一个一个的调试。
在调试的过程中我们遇到了很多的问题,我们编出来的程序不是一下子就能实现我们想要的功能的,要经过不断的修改、调试,最后实现我们想要的功能。
总之,通过本次单片机综合程序设计训练,我对单片机的基本的应用技术有了深刻的了解,而且还会将其融会贯通,应用于我们我需要的程序之中。
本次训练中,定时器的应用相当广泛,它与中断函数构成了基本的计数环节,为后面的时间显示和星期显示等提供了基础。
中断为定时提供了条件,函数每5ms便进入中断函数一次,并执行相应的操作与计数。
条件语句为数码管的功能显示提供了条件。
同时,对于程序的调试、分析、修正也有了相应的掌握。
六、参考文献
[1]沈红卫.单片机的智能系统设计与实现[M].北京电子工业出版社
[2]李光飞,楼然苗,胡佳文,等著.单片机课程设计实例指导[M].北京航空航天大学出版社
[3]汪德彪.MCS-51单片机原理及接口技术[M].北京电子工业出版社
[4]胡文金,钟秉翔.单片机应用技术实训教程[M].重庆大学出版社
[5]张毅刚,彭喜元,董继成.单片机原理及应用[M].重庆大学出版社
[6]王静霞,单片机应用技术.电子工业出版社
附录1:
电路原理图
附录2:
程序
#include"reg52.h"
#defineTHCO0xee
#defineTLCO0x0
unsignedcharcodeDuan[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x31};
//共阴极数码管,段码
unsignedcharData_Buffer[4]={0,0,0,0};
//四个数码管显示数值,数组变量定义
unsignedcharMill_Sec=0,Sec1=0,Ring_flag=0;
unsignedcharHour=0,Min=0,Sec=0;
unsignedcharRing_Hour=16,Ring_Min=40,count0=0,Week=1;
unsignedcharMode=0;//MODE,0:
实时时钟;1:
修改小时;2:
修改分钟;3:
修改闹钟小时;4:
修改闹钟分钟;5:
启动秒表;6:
修改星期
bitstart_flag=0,brush_flag=0;//标志位定义
bitflag=0,Week_flag=0;//标志位定义
sbitP10=P1^0;//四个数码管的位码口定义
sbitP11=P1^1;
sbitP12=P1^2;
sbitP13=P1^3;
sbitP14=P1^4;//蜂鸣器
sbitK_Mode=P2^0;//按键定义
sbitK_UP=P2^1;
sbitK_DN=P2^2;
sbitLED1=P2^3;//四个指示灯
sbitLED2=P2^4;
sbitLED3=P2^5;
sbitLED4=P2^6;
voidnaozhong();
voidmain()
{
TMOD=0x11;//定时器0初始化
TH0=THCO;
TL0=TLCO;
TR0=1;
ET0=1;
EA=1;
P14=1;
while
(1){
naozhong();
if(flag==1){//更新数码管显示北京时间
flag=0;
Data_Buffer[0]=Hour/10;
Data_Buffer[1]=Hour%10;
Data_Buffer[2]=Min/10;
Data_Buffer[3]=Min%10;
}
if(Ring_flag==1){//更新数码管显示闹钟时间
Ring_flag=0;
Data_Buffer[0]=Ring_Hour/10;
Data_Buffer[1]=Ring_Hour%10;
Data_Buffer[2]=Ring_Min/10;
Data_Buffer[3]=Ring_Min%10;
}
if(brush_flag==1)//更新数码管显示
{brush_flag=0;
Data_Buffer[0]=Sec1/10;
Data_Buffer[1]=Sec1%10;
Data_Buffer[2]=Mill_Sec/10;
Data_Buffer[3]=Mill_Sec%10;
}
if(Week_flag==1)//更新数码管显示
{Week_flag=0;
Data_Buffer[0]=10;
Data_Buffer[1]=10;
Data_Buffer[2]=10;
Data_Buffer[3]=Week;
}}
}
voidtimer0()interrupt1
{
staticunsignedcharBit=0;//静态变量,退出程序后,值保留
staticunsignedcharK_count=0,time_count=0,count=0;
TH0=THCO;
TL0=TLCO;
Bit++;
if(Bit>=4)Bit=0;
P1|=0x0f;//先关位码
P0=Duan[Data_Buffer[Bit]];//开段码
if(count<100&&Bit==1&&Mode!
=6)P0|=0x80;//0.5S中间小数点亮,之后灭,不断循环
switch(Bit)//送位码
{
case0:
P10=0;break;
case1:
P11=0;break;
case2:
P12=0;break;
case3:
P13=0;break;
}
if(start_flag==1)//秒表启动
{
time_count++;
if(time_count==2)//10ms时间
{
time_count=0;
Mill_Sec++;
if(Mill_Sec>99)//1S时间到
{
Mill_Sec=0;
Sec1++;
if(Sec1>99){Sec1=0;}
}
brush_flag=1;//更新数码管显示标志
}
}
count++;
if(count>=200)//秒计时,定时器定时5ms,计200次为一秒
{
count=0;
Sec++;
if(Sec==3)P14=1;//整点报时闹铃关闭
count0++;//闹钟响的时间
if(Sec>=60)
{
count0=0;
Sec=0;
Min++;
if(Min>=60)//时间计时
{
P14=0;//整点报时
Min=0;Hour++;
if(Hour>=24)
{
Hour=0;Week++;
if(Week>=8)
{
Week=1;
}
}}}
}
if(K_Mode==0||K_UP==0||K_DN==0)//有键按下
{
K_count++;
if(K_count>=30)//消抖处理
{
K_count=0;
flag=1;
if(K_Mode==0)//修改Mode,
{
Mode++;
if(Mode>=7)Mode=0;
if(Mode==0){LED1=1;LED2=1;LED3=1;LED4=1;}//实时时间
elseif(Mode==1){LED1=0;LED2=1;LED3=1;LED4=1;}//修改小时
elseif(Mode==2){LED1=1;LED2=0;LED3=1;LED4=1;}//修改分钟
elseif(Mode==3){LED1=1;LED2=1;LED3=0;LED4=1;Ring_flag=1;flag=0;}//修改闹铃小时
elseif(Mode==4){LED1=1;LED2=1;LED3=1;LED4=0;Ring_flag=1;flag=0;}//修改闹铃分钟
elseif(Mode==5){LED1=0;LED2=0;LED3=0;LED4=0;brush_flag=1;flag=0;Ring_flag=0;}
elseif(Mode==6){LED1=0;LED2=0;LED3=1;LED4=1;Week_flag=1;flag=0;brush_flag=1;}
}
elseif(K_UP==0)
{
if(Mode==1)//小时加
{Hour++;if(Hour>=24)Hour=0;}
elseif(Mode==2)//分钟加
{Min++;if(Min>=60)Min=0;}
elseif(Mode==3)//闹铃小时加
{Ring_Hour++;if(Ring_Hour>=24)Ring_Hour=0;Ring_flag=1;}
elseif(Mode==4)//闹铃分钟加
{Ring_Min++;if(Ring_Min>=60)Ring_Min=0;Ring_flag=1;}
elseif(Mode==5)
{start_flag=!
start_flag;brush_flag=1;flag=0;}
elseif(Mode==6)//星期加
{Week++;if(Week>=8)Week=1;Week_flag=1;brush_flag=0;flag=0;Ring_flag=0;}
}
elseif(K_DN==0)
{
if(Mode==1)//小时减
{if(Hour==0)Hour=23;
elseHour--;}
elseif(Mode==2)//分钟减
{if(Min==0)Min=59;elseMin--;}
elseif(Mode==3)//闹铃小时减
{if(Ring_Hour==0)Ring_Hour=23;elseRing_Hour--;Ring_flag=1;}
elseif(Mode==4)//闹铃分钟减
{if(Ring_Min==0)Ring_Min=59;elseRing_Min--;Ring_flag=1;}
elseif(Mode==5)
{Mill_Sec=0;Sec1=0;Week_flag=0;brush_flag=1;flag=0;Ring_flag=0;}
elseif(Mode==6)//星期减
{if(Week==1)Week=7;elseWeek--;Week_flag=1;brush_flag=0;flag=0;Ring_flag=0;}
}}
}
elseK_count=0;
}
voidnaozhong()//闹钟程序
{
if(Mode==3||Mode==4)Ring_flag=1;
if(Hour==Ring_Hour&&Min==Ring_Min)
{
if(count0<20){P14=0;}
if(count0>=20){P14=1;}}
}