基于单片机的数字时钟设计兰州交通大学.docx
《基于单片机的数字时钟设计兰州交通大学.docx》由会员分享,可在线阅读,更多相关《基于单片机的数字时钟设计兰州交通大学.docx(22页珍藏版)》请在冰豆网上搜索。
![基于单片机的数字时钟设计兰州交通大学.docx](https://file1.bdocx.com/fileroot1/2023-3/1/ee361e7a-fa15-4259-bacb-a6c5d51777b4/ee361e7a-fa15-4259-bacb-a6c5d51777b41.gif)
基于单片机的数字时钟设计兰州交通大学
单片机原理及系统课程设计
评语:
考勤(10)
守纪(10)
过程(30)
设计报告(30)
答辩(20)
总成绩(100)
专业:
电气工程及其自动化
班级:
电气1103
姓名:
郭振
学号:
201109318
指导教师:
侯涛
兰州交通大学自动化与电气工程学院
2014年1月15日
基于单片机的数字时钟设计
1、课程设计目的
(1)进一步熟悉和掌握单片机的结构及工作原理。
(2)掌握单片机的接口技术及相关外围芯片的特性及控制方法。
(3)通过课程设计,掌握以单片机为核心的电路设计的基本方法和技术,了解有关电路参数的计算方法。
2、设计方案
在整个设计中,主要用的是单片机的自动控制原理,包括硬件和软件。
在硬件部分,包括按键控制模块、数码管显示模块和闹钟模块;软件部分,主要是主程序设计。
本设计是作息时间控制器,设计其实现的功能主要有:
使用4位七段显示器来显示当前的时间,由LED闪动作为秒计数表示,显示格式为“时分”,并可显示日期,显示格式为“月日”,年份单独显示。
由4个按键来作功能设置,可以设置现在的日期、时间及定时设置时间,一旦设置的时间到则作出相应动作:
发光二极管闪亮,同时播放音乐。
系统方框图如图1所示:
图1系统方框图
3、硬件设计
3、1按键控制模块
按键设定部分比较简单,因为本系统按键少,所以在设计上采用了独立按键方式,程序的编制上也采用了简单的扫描方式。
按键控制模块主要有由四个按键组成:
K1、K2、K3、K4、。
其中K1的功能是模式切换键;K2的作用是加一;K3的作用是闹钟使能;K4的作用是减一。
(1)时间校正:
当我们需要正确的显示时间即可进行时间校正,按一下K1即进入小时校正状态,通过K2加一或K4减一来进行小时校正,再按一次K1键即可进行分钟校正,校正原理同小时校正相同。
(2)闹钟设定:
当我们需要闹钟提醒时即可使用此功能,连续按三下K1键即可进入闹钟小时设定状态,通过K2键加一或K4键减一,进行小时设定,再按一次K1键即可进行分钟设定,其设定原理与小时设定原理相同,按一下K3键,则时间设定完毕,到时会自动响铃。
(3)日期校正:
当我们需要与当前日期保持一致时,则可以使用日期校正功能,连续按动五次K1键,则进入月份校正状态,通过K2加一键或K4减一键进行校正月份,再按一次K1键,则可进行日期校正,校正原理同月份校正原理相同。
(4)年份校正:
当我们需要保持年份与当前年份一一致时,则可以进行年份校正。
连续按动七次K1键,即进入年份校正状态,通过K2加一键或K4减一键进行校正。
(5)闹钟响铃:
当我们设定的时间与当前时间一致时,则闹钟就会自动响铃提示,与此同时发光二极管闪亮,一分钟后响铃停止,发光二极管熄灭,若在此期间按下闹钟使能键K3同样能使响铃停止,发光二极管熄灭。
3、2数码管显示模块
时间显示模块主要由四位七段数码管来显示,配合按键控制模块的校正与设定时间,相应的显示。
时间正常显示时,LED每闪动60次,分钟自动加一;每六十分钟小时自动加一;每24小时天自动加一。
数码管显示模块如图2所示:
图2数码管显示模块仿真图
3、3闹钟模块
闹钟模块快的主要功能即闹铃。
当设定时间与当前时间一致时,则闹钟自动闹铃进行提示,同时二极管闪亮一分钟后,自动退出响铃状态,若按K3键,闹钟退出响铃状态。
闹钟模块如图3所示:
图3闹钟模块仿真图
4、硬件设计
4、1主程序设计
在主控程序循环中主要工作为扫描是否有按键,若有按键则应做相应的功能处理,同时也扫描显示器显示时间数据,并检查所设置的时间是否到了,时间计时处理程序是等过了1S后,则更新时间数据,将最新的时,分,秒的数据转换为数字数据并显示在七段显示器上。
程序中是这样判断是否过了1S的:
设一旧秒数变量,当新旧秒数变量不一样时,则表示已过了1S,要做相关程序时间处理了。
4、2中断子程序
中断子程序的主要功能:
提供时间基准。
当连续中断20次时,即为一秒,此时秒加一;当秒值为60时,分钟加一,同时秒清零;当分钟值为60时,小时加一,同时分钟值清零;当小时为24时,天值加一,同时小时清零;由于每月天数不定,1、3、5、7、8、10、12月为31天,当计数到此类月份时,天值为32时,月值加一,同时天值为1;4、6、9、11月为30天,当计数到此类月份时,天值为31时,月值加一,同时天值为1;如果是闰年,则2月为29天,当计数到此类月份时,天值为30时,月值加一,同时天值为一;如果不是闰年,则2月为28天,当计数此类月份时,天值为29时,月值加一,同时天值为一;当月值为13时,则年值加一,同时月值为一。
中断子程序流程图如图4所示:
图4中断子程序流程图
4、3按键扫描子程序
按键扫描子程序是程序计中相当重要的一部分。
按键扫描子程序的功能是:
扫描是否有按键按下,若有键按下,则执行相应功能。
5、系统仿真
Proteus仿真如图5所示:
图5系统仿真图
6、总结
通过这两周的课程设计,让我了解了设计电路的程序,也让我了解了数字钟的工作原理和设计理念,加强了我们动手、思考和解决问题的能力。
在此次的数字钟设计过程中,我进一步熟悉了单片机芯片的硬件结构和各引脚的功能,以及数码管的工作原理和使用方法,巩固和加强了理论知识。
参考文献
1王思明,张金敏,苟军年等.单片机原理及应用系统设计[M].科学出版社,2012年
2吴金.8051单片机实践与应用[M].清华大学出版社,2002年
附1:
源程序代码
#include
#defineuintunsignedint
#defineucharunsignedchar
ucharcodea[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//*************************************************************************************
sbitK1=P1^4;
sbitK2=P1^5;
sbitK3=P1^6;
sbitK4=P1^7;
sbitsd=P3^6;
sbitBEEP=P3^7;
ucharm=0,h=0,sec=0,cnt=0,x,y,qian,bai,shi,ge;
ucharset_h=00;
ucharset_m=00;
ucharmonth=1;
ucharday=1;
ucharth0_f;
uchartl0_f;
uintyear=2014;
voiddelay(uchart);//延时函数
voidscankey(void);//按键扫描函数
voidinit(void);//初始化函数
voiddisplay(void);//显示函数
voidset_time(void);//设定时间显示辅助函数
voidset_day(void);//设定日期显示辅助函数
voidm_choose(void);//月份选择函数
voidbianhuan(void);//年份显示辅助函数
voidbianhuan1(void);//时间显示辅助函数
changedata(uchar*song,uchar*diao,uchar*jie);//音乐符号串解释函数
voidplay(uchar*songdata);//奏乐函数
//世上只有妈妈好
ucharcodemamahao[]={
"6.5_35|`16_5_6-|35_6_53_2_|1_,6_5_3_2-|"
"2.3_55_6_|321-|5.3_2_1_,6_1_|,5--"
};
ucharcodefreq[36*2]={
0xA9,0xEF,//00220HZ,1//0
0x93,0xF0,//00233HZ,1#
0x73,0xF1,//00247HZ,2
0x49,0xF2,//00262HZ,2#
0x07,0xF3,//00277HZ,3
0xC8,0xF3,//00294HZ,4
0x73,0xF4,//00311HZ,4#
0x1E,0xF5,//00330HZ,5
0xB6,0xF5,//00349HZ,5#
0x4C,0xF6,//00370HZ,6
0xD7,0xF6,//00392HZ,6#
0x5A,0xF7,//00415HZ,7
0xD8,0xF7,//00440HZ1//12
0x4D,0xF8,//00466HZ1#//13
0xBD,0xF8,//00494HZ2//14
0x24,0xF9,//00523HZ2#//15
0x87,0xF9,//00554HZ3//16
0xE4,0xF9,//00587HZ4//17
0x3D,0xFA,//00622HZ4#//18
0x90,0xFA,//00659HZ5//19
0xDE,0xFA,//00698HZ5#//20
0x29,0xFB,//00740HZ6//21
0x6F,0xFB,//00784HZ6#//22
0xB1,0xFB,//00831HZ7//23
0xEF,0xFB,//00880HZ`1
0x2A,0xFC,//00932HZ`1#
0x62,0xFC,//00988HZ`2
0x95,0xFC,//01046HZ`2#
0xC7,0xFC,//01109HZ`3
0xF6,0xFC,//01175HZ`4
0x22,0xFD,//01244HZ`4#
0x4B,0xFD,//01318HZ`5
0x73,0xFD,//01397HZ`5#
0x98,0xFD,//01480HZ`6
0xBB,0xFD,//01568HZ`6#
0xDC,0xFD,//01661HZ`7//35
};
//******************************
//音乐符号串解释函数
changedata(uchar*song,uchar*diao,uchar*jie)
{
uchari,i1,j;
chargaodi;
ucharbanyin;
ucharyinchang;//Òô³¤
ucharcodejie7[8]={0,12,14,16,17,19,21,23};
*diao=*song;
for(i=0,i1=0;;)
{
gaodi=0;
banyin=0;
yinchang=4;
if((*(song+i)=='|')||(*(song+i)==''))i++;
switch(*(song+i))
{
case',':
gaodi=-12;i++;
break;
case'`':
gaodi=12;i++;
break;
}
if(*(song+i)==0)
{
*(diao+i1)=0;
*(jie+i1)=0;
return;
}
j=*(song+i)-0x30;i++;
j=jie7[j]+gaodi;
yinc:
switch(*(song+i))
{
case'#':
i++;j++;
gotoyinc;
case'-':
yinchang+=4;
i++;
gotoyinc;
case'_':
yinchang/=2;
i++;
gotoyinc;
case'.':
yinchang=yinchang+yinchang/2;
i++;
gotoyinc;
}
*(diao+i1)=j;
*(jie+i1)=yinchang;
i1++;
}
}
//******************************************
//奏乐函数
voidplay(uchar*songdata)
{
uchari,c,j=0;
uintn;
uchardiaodata[40];
ucharjiedata[40];
changedata(songdata,diaodata,jiedata);
TR1=1;
for(i=0;diaodata[i]!
=0;i++){
tl0_f=freq[diaodata[i]*2];
th0_f=freq[diaodata[i]*2+1];
for(c=0;c{
for(n=0;n<24;n++)
{scankey();
if(y==0){
TR1=0;
return;
}
display();
}
}
TR1=0;
for(n=0;n<500;n++);
TR1=1;
}
TR1=0;
}
voidtime0(void)interrupt1
{
TH0=0x3c;
TL0=0xb0;
cnt++;
if(y==1&&(set_h==h&&set_m==m))sd=~sd;
elsesd=1;
if(cnt==20)
{
sec++;
cnt=0;
if(sec==60)
{
sec=0;
m++;
if(m==60)
{
m=0;
h++;
if(h==24)
{
h=0;
day++;
switch(month)
{
case1:
if(day==32){month++;day=1;}break;
case2:
if(year%4==0){if(day==30){month++;day=1;}}
else{if(day==29){month++;day=1;}}break;
case3:
if(day==32){month++;day=1;}break;
case4:
if(day==31){month++;day=1;}break;
case5:
if(day==32){month++;day=1;}break;
case6:
if(day==31){month++;day=1;}break;
case7:
if(day==32){month++;day=1;}break;
case8:
if(day==32){month++;day=1;}break;
case9:
if(day==31){month++;day=1;}break;
case10:
if(day==32){month++;day=1;}break;
case11:
if(day==31){month++;day=1;}break;
case12:
if(day==32){month++;day=1;}break;
}
if(month==13)
{
month=1;
year++;
}
}
}
}
if(x==0)bianhuan1();
}
}
timer1()interrupt3
{
TL1=tl0_f;TH1=th0_f;//调入预定值
BEEP=~BEEP;//取反音乐输出IO
}
voidmain(void)
{
init();
while
(1)
{
display();
scankey();
if(y==1&&(set_h==h&&set_m==m))play(mamahao);
elseBEEP=0;
}
}
voidinit(void)
{
BEEP=0;
TMOD=0x11;
TH0=0x3c;
TL0=0xb0;
ET0=1;
TR0=1;
ET1=1;
TR1=0;
EA=1;
}
voiddisplay(void)
{
P2=0xfe;
P0=a[qian];
if(x%2==1&&cnt>=10)P0&=0x00;
delay(20);
P2=0xfd;
P0=a[bai];
if(x%2==1&&cnt>=10)P0&=0x00;
elseif(x==0&&cnt>=10)P0|=0x80;
delay(20);
P2=0xfb;
P0=a[shi];
if(((x%2==0&&x!
=0)||x==7)&&cnt>=10)P0&=0x00;
delay(20);
P2=0xf7;
P0=a[ge];
if(((x%2==0&&x!
=0)||x==7)&&cnt>=10)P0&=0x00;
delay(20);
}
voidm_choose(void)
{
switch(month)
{
case1:
if(day==32)day=1;elseif(day==0)day=31;break;
case2:
if(year%4==0){if(day==30)day=1;elseif(day==0)day=29;}
else{if(day==29)day=1;elseif(day==0)day=28;}break;
case3:
if(day==32)day=1;elseif(day==0)day=31;break;
case4:
if(day==31)day=1;elseif(day==0)day=30;break;
case5:
if(day==32)day=1;elseif(day==0)day=31;break;
case6:
if(day==31)day=1;elseif(day==0)day=30;break;
case7:
if(day==32)day=1;elseif(day==0)day=31;break;
case8:
if(day==32)day=1;elseif(day==0)day=31;break;
case9:
if(day==31)day=1;elseif(day==0)day=30;break;
case10:
if(day==32)day=1;elseif(day==0)day=31;break;
case11:
if(day==31)day=1;elseif(day==0)day=30;break;
case12:
if(day==32)day=1;elseif(day==0)day=31;break;
}
}
voidset_time(void)
{
qian=set_h/10;
bai=set_h%10;
shi=set_m/10;
ge=set_m%10;
}
voidset_day(void)
{
qian=month/10;
bai=month%10;
shi=day/10;
ge=day%10;
}
voidbianhuan(void)
{
qian=year/1000;
bai=year%1000/100;
shi=year%100/10;
ge=year%10;
}
voidbianhuan1(void)
{
qian=h/10;
bai=h%10;
shi=m/10;
ge=m%10;
}
voidscankey(void)
{
if(K1==0)
{
delay(20);
if(K1==0)
{
while(K1==0);
x++;
if(x==3)set_time();
elseif(x==5)set_day();
elseif(x==7)bianhuan();
elseif(x==8){x=0;bianhuan1();}
}
}
if(K2==0)
{
delay(20);
if(K2==0)
{
while(K2==0);
switch(x)
{
case0:
break;
case1:
h++;if(h==24)h=0;bianhuan1();break;
case2:
m++;if(m==60)m=0;bianhuan1();break;
case3:
set_h++;if(set_h==24)set_h=0;set_time();break;
case4:
set_m++;if(set_m==60)set_m=0;set_time();break;
case5:
month++;if(month==13)month=1;set_day();break;
case6:
day++;m_choose();set_day();break;
case7:
year++;bianhuan();break;
}
}
}
if(K3==0)
{
delay(20);
if(K3==0)
{
while(K3==0);
y++;
if(y==2)y=0;
}
}
if(K4==0)
{
delay(20);
if(K4==0)
{
while(K4==0);
switch(x)
{
case0:
break;
case1:
h--;if(h==255)h=23;bianhuan1();break;
case2:
m--;if(m==255)m=59;bianhuan1();break;
case3:
set_h--;if(set_h==255)set_h=23;set_time();break;
case4:
s