51单片机课设电子钟.docx
- 文档编号:23377564
- 上传时间:2023-05-16
- 格式:DOCX
- 页数:40
- 大小:46.89KB
51单片机课设电子钟.docx
《51单片机课设电子钟.docx》由会员分享,可在线阅读,更多相关《51单片机课设电子钟.docx(40页珍藏版)》请在冰豆网上搜索。
51单片机课设电子钟
福州大学
《MCS-51单片机》
课程设计
题目:
数字时钟
姓名:
学号:
学院:
电气工程与自动化学院
专业:
电机电器
年级:
2009
起讫日期:
2012.04.10~2012.5.8
指导教师:
蔡逢煌
目录
1、课程设计目的2
2、课程设计题目和实现目标2
3、设计方案3
4、Proteus仿真原理图5
5、程序流程图5
6、程序代码5
7、调试总结35
8、设计心得体会35
9、参考文献35
1、课程设计目的
《MCS-51单片机》课程设计是与《MCS-51单片机》课程相配套的实践教学环节。
《MCS-51单片机》是一门实践性很强的专业基础课,通过课程设计,达到进一步理解单片机的硬件、软件和综合应用方面的知识,培养实践能力和综合应用能力,开拓学习积极性、主动性,学会灵活运用已经学过的知识,并能不断接受新的知识。
培养大胆发明创造的设计理念,为今后就业打下良好的基础。
通过课程设计,掌握以下知识和技能:
1.单片机应用系统的总体方案的设计;
2.单片机应用系统的硬件设计;
3.单片机应用系统的软件程序设计;
4.单片机开发系统的应用和调试能力
2、课程设计题目和实现目标
2.1课程设计题目
.智能电子钟设计
要求:
1.能正确显示日期、时间,并且可修该;
2.具有闹铃的功能;
3、秒表功能;
4、数码显示当前温度;
2.2实现目标
使用时钟芯片ds1302实现对时间、日期的计时功能。
使用lcd1602液晶显示屏来显示时钟芯片内部的计时情况。
同时闹钟、温度显示、秒表功能也使用液晶屏显示。
最终实现的效果是显示屏第一行显示年月日和星期,第二行显示小时、分钟、秒,以及温度值。
在经行闹钟设置时,闹钟显示在显示屏第二行,同样秒表功能也显示在第二行。
正常时间、闹钟和秒表三个功能通过按键切换,分别显示于显示屏第二行。
闹钟通过闹钟程序实现,当所设闹钟与计时时间相同时,蜂鸣器发出滴滴声。
秒表的设计是通过使用芯片内部定时器0作为计时时基,结合中断程序和按键实现秒表启动、停止和清零的效果。
温度测量使用芯片ds18b20,读出的温度在lcd上显示,且具有实时显示测量的功能。
能实现显示两位的正温度,并可以在程序内部设置一个温度最大值,当所测温度超过最大值时,LED小灯闪亮以作为报警提示。
3、设计方案
设计的总体思路是时钟芯片1302的数据采集出来以后送入单片机,经过转码以后再送入lcd液晶屏显示。
同理18b20所测量的温度通过但数据线送入单片机,经过转码以后送入显示屏,与时间日期同时显示在显示屏上。
具体的设计方案如下:
1602由两行每行十六个显示点阵组成,有八根数据传输线,三根控制线分别为选通位RS,使能位E,读状态位WR。
另外还需外接电源线和地线。
在操作过程中首先要注意的一点是由于只有一根指令传输的接线,因此指令数据是一位一位经行传输的。
在对显示屏经行操作时,首先要对显示屏经行初始化,设置基本参数。
之后再程序中经行操作就可以只写控制字和数据。
每显示一个数据都需要先给出数据要显示的地址,之后再传输数据。
对显示屏经行写指令操作时要保持RS低电平RW低电平、E高脉冲。
而在写入数据时要保持RS高电平、RW低电平、E高脉冲。
将时钟芯片里的每一位数据送入单片机内部寄存器ACC中的地位,然后每取一位数据ACC左移一位,这样去除一个八位数据为一次读取时间。
同样向时钟芯片送数据时也是通过将要写入的内容先存入ACC然后每次写入地位数据,写完一位就右移一位。
初始化完成后,每次与时钟芯片通信都先写入要通信的地址,再读写数据。
从时钟芯片中读出或者写入的数据是BCD码,因此需要有一个转码过程。
这里我在写入数据时设计了一个十六进制数转为BCD码的程序“bcd()”,转码完成后可以使用一个传输写入的程序writeto1302来写入数据,而读出时,在读出程序readfrom1302中直接加入了BCD转十六进制的语句。
转码结束后数据存入数组time[]以便经行进一步的处理。
因为lcd显示的是ASC码,且每一位显示一个数字,因此这里要对十六进制数分离并变成ASC码的相应值。
与上述过程相对的是,在每次修改时间的时候,因为此时始终芯片还在工作,因此这个时候需要先停止读入时钟值,我在程序中通过设置一个标志位flag来实现控制,判断标志位的值来控制时间数据的读入。
同时在更改数据结束后需要先将更改的结果送入到时钟芯片中,此过程相当于对时钟芯片再次赋值,然后时钟芯片就会在所赋值的基础上继续工作,这样就达到了我们想要的修改时间的效果。
对于温度的处理类似于时间的处理。
温度芯片18b20也只有一条数据线,因此使用时间传输时同样的方式,每次读写八位数据组成一字节的数据。
通过阅读温度测量芯片的数据手册,可以发现温度转化完成后从芯片中读出两个字节的数据,两字节数据组成了十六位的温度数字值。
该值中高五位表示温度的正负,第四位表示温度的小数值。
因为在我设计的程序中我只要求显示两位的正温度值,因此这里我将高四位和第四位舍去然后重新组合为一个八位数据,用上边叙述过的同样的方法处理此八位数据然后送入lcd经行显示。
闹钟功能,在这里我定义了三个变量,通过对此三个变量的设置,然后将变量与存储着从时钟芯片中读出的时分秒数据经行对比,当两者相同时,将接有蜂鸣器的引脚置高,再通过一个循环程序时的蜂鸣器发出滴滴的声音。
秒表功能我是用到了单片机内部计时器T0和中断功能。
用以前曾经写过的方法,让程序每50MS中断一次并在中断程序中经行循环,当到达一秒时秒位加一。
并结合键盘设置有秒表开秒表关和秒表清零功能。
键盘作为整个程序的主要操作点,设有留个独立键盘。
K1为位选功能,选中要修改的位;K2是增值功能,是算选中的值加一;K3是减值功能;K4是正常时钟、闹钟、秒表切换的功能位;K5在普通模式下表示闹钟开关,在秒表模式下作为秒表的开关;K6为秒表模式下的清零位,只有在秒表停止时才能动作。
4、Proteus仿真原理图
5、程序流程
首先程序开始运行后,可以按下K1键选择要操作的位。
每次按下会换一个操作位,位顺序为:
秒、分、时、日、月、年、星期。
选中星期后,再次按下K1键后程序回到正常运行模式。
在选中每一位的时候可以通过K2、K3键来增减数值,内部已经设置好,因此分秒只能在0到59增减变化,时的范围是0到23,而日期则与月份值有关,有大小月份之分。
按下K4键后第二行显示全零,此时为闹钟设置模式,依然用K1选中位,K2K3增减数值,K5控制闹钟开启和关闭。
再次按下K4键进入秒表模式,此时按下K5秒表开始运转,再次按下K5秒表停止。
在秒表停止的情况下按下K6,秒表清零。
程序内设置温度报警值为35度,当温度高过该值后小灯会闪烁报警。
闹钟时间到以后蜂鸣器发出滴滴的声音。
6、程序代码
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitSCLK=P3^6;//时钟芯片端口设置
sbitIO=P3^4;
sbitCE=P3^5;
sbitACC0=ACC^0;//定义ACC寄存器中的第1位
sbitACC7=ACC^7;//定义ACC寄存器中的第八位
sbitLCDE=P2^6;//液晶显示控制端口设置
sbitLCDRS=P2^5;
sbitLCDWR=P2^4;
sbitDQ=P3^7;
sbitBF=P0^7;
sbitK1=P2^0;//独立按键端口设置,mode
sbitK2=P2^1;//add
sbitK3=P2^2;//subtraction
sbitK4=P2^3;
sbitK5=P3^0;
sbitK6=P3^1;
sbitLED=P2^7;
sbitring=P3^2;//alarmpin
uchartable[]="2012-05-01MON";
uchartable1[]="00:
00:
00";
ucharcodetable2[]={32,29,32,31,32,31,32,32,31,32,31,32};
chartable3[]={"MONTUEWENTHUFRISATSUN"};
chartime[]={0x00,0x00,0x00,0x01,0x05,0x06,0x0c};
ucharLED_DIS[]={0,0,0,0,0,0,0,0};
ucharLED_DIS1[]={0,0,0,0,0,0,0,0};
ucharK1_num,flag,temph,templ,timee,K4_num,K5_num;
uchartemp,T,c_miao,c_fen,c_shi,count;
charshi,fen,miao;
voiddelay(uint);
voidds1302display();
//*****************NOTUSEDIRECTLY
voidwritebyte(ucharucDa)
{
uchari=0;
ACC=ucDa;
for(i=8;i>0;i--)
{
IO=ACC0;
SCLK=1;
_nop_();
SCLK=0;
_nop_();
ACC=ACC>>1;
}
}
ucharreadbyte(void)
{
uchari=0;
for(i=8;i>0;i--)
{
ACC=ACC>>1;
ACC7=IO;
SCLK=1;
_nop_();
SCLK=0;
_nop_();
}
return(ACC);
}
//************
voidwriteto1302(ucharaddr,uchardat)
{
CE=0;
SCLK=0;
CE=1;
writebyte(addr);
_nop_();
_nop_();
writebyte(dat);//tipsthecodetypeofdatisbcd
SCLK=1;
CE=0;
}
ucharreadfrom1302(ucharaddr)
{
uchardat1,temp;
CE=0;
SCLK=0;
CE=1;
writebyte(addr);
_nop_();
_nop_();
dat1=readbyte();
CE=0;
temp=_cror_(dat1&0xf0,4);
dat1=temp*10+(dat1&0x0f)*10/10;
return(dat1);//将读出的BCD码转为十六进制码
}
//*********lcdread&write
bitBusyTest()
{
bitresult;
LCDRS=0;//根据规定,RS为低电平,RW为高电平时,可以读状态
LCDWR=1;
LCDE=1;//E=1,才允许读写
_nop_();//空操作
_nop_();
_nop_();
_nop_();//空操作四个机器周期,给硬件反应时间
result=BF;//将忙碌标志电平赋给result
LCDE=0;//将E恢复低电平
returnresult;
}
voidwrite_com(ucharcom)
{
while(BusyTest()==1);
LCDRS=0;
LCDWR=0;
LCDE=0;
P0=com;
delay(5);
LCDE=1;
delay(5);
LCDE=0;
}
voidwrite_data(uchardat)
{
while(BusyTest()==1);
LCDRS=1;
LCDWR=0;
LCDE=0;
P0=dat;
delay(5);
LCDE=1;
delay(5);
LCDE=0;
}
//*********************
//**********************
voidbcd()//bcd转码
{
uinti,tmp;
for(i=0;i<7;i++)
{tmp=time[i]/10;
time[i]=time[i]%10;
time[i]=time[i]+tmp*16;
}
}
voidwritetime()
{
writeto1302(0x8e,0x00);//清清除写保护
writeto1302(0x80,time[0]);//秒
writeto1302(0x82,time[1]);//分
writeto1302(0x84,time[2]);//时
writeto1302(0x86,time[3]);//日
writeto1302(0x88,time[4]);//月
writeto1302(0x8a,time[5]);//星期
writeto1302(0x8c,time[6]);//年
writeto1302(0x8e,0x80);//写保护不允许写入
}
voidreadtime()
{
time[6]=readfrom1302(0x8d);
time[5]=readfrom1302(0x8b);
time[4]=readfrom1302(0x89);
time[3]=readfrom1302(0x87);
time[2]=readfrom1302(0x85);
time[1]=readfrom1302(0x83);
time[0]=readfrom1302(0x81);
}
voidinto()
{
LED_DIS[0]=time[2]/10+0x30;
LED_DIS[1]=time[2]%10+0x30;
LED_DIS[2]=':
';
LED_DIS[3]=time[1]/10+0x30;
LED_DIS[4]=time[1]%10+0x30;
LED_DIS[5]=':
';
LED_DIS[6]=time[0]/10+0x30;
LED_DIS[7]=time[0]%10+0x30;
LED_DIS1[0]=time[6]/10+0x30;
LED_DIS1[1]=time[6]%10+0x30;
LED_DIS1[2]='-';
LED_DIS1[3]=time[4]/10+0x30;
LED_DIS1[4]=time[4]%10+0x30;
LED_DIS1[5]='-';
LED_DIS1[6]=time[3]/10+0x30;
LED_DIS1[7]=time[3]%10+0x30;
}
//****************************
//****************************keyscan
voidwrite_lcdline_1(ucharaddr,uchardat)//sfm
{
ucharshiwei,gewei;
shiwei=dat/10;
gewei=dat%10;
write_com(0x80+addr);
write_data(0x30+shiwei);
write_data(0x30+gewei);
}
voidwrite_lcdline_2(ucharaddr,uchardat)//sfm
{
ucharshiwei,gewei;
shiwei=dat/10;
gewei=dat%10;
write_com(0x80+0x40+addr);
write_data(0x30+shiwei);
write_data(0x30+gewei);
}
voidkeyscan()
{
if(K6==0)
{
delay(5);
if(K6==0)
{
while(!
K6);
if((K4_num==2)&(K5_num==0))
{
write_lcdline_2(7,0);
write_lcdline_2(4,0);
write_lcdline_2(1,0);
c_miao=0;
c_fen=0;
c_shi=0;
}
}
}
if(K5==0)
{
delay(5);
if(K5==0)
{
K5_num++;
while(!
K5);
if(K5_num==2)
K5_num=0;
}
}
if(K4==0)
{
uinttmp;
uchars,f,m;
delay(5);
if(K4==0)
{
K4_num++;
while(!
K4);
flag=1;
s=time[2];
f=time[1];
m=time[0];
if(K4_num==1)
{
uchari;
write_com(0x80+0x40);
for(i=0;i<9;i++)
{
write_data(table1[i]);
}
}
if(K4_num==2)
{
uchari;
write_com(0x80+0x40);
for(i=0;i<9;i++)
{
write_data(table1[i]);
}
}
if(K4_num==3)
{
K4_num=0;
tmp=m/10;
m=m%10;
m=m+tmp*16;
tmp=f/10;
f=f%10;
f=f+tmp*16;
tmp=s/10;
s=s%10;
s=s+tmp*16;
writeto1302(0x8e,0x00);//清清除写保护
writeto1302(0x80,m);//秒
writeto1302(0x82,f);//分
writeto1302(0x84,s);//时
flag=0;
}
}
}
if(K1==0)
{
delay(5);
if(K1==0)
{
K1_num++;
flag=1;
while(!
K1);
if(K1_num==1)
{
write_com(0x80+0x40+7);
write_com(0x0f);//开显示,显示光标,光标闪烁
}
if(K1_num==2)
{
write_com(0x80+0x40+4);
}
if(K1_num==3)
{
write_com(0x80+0x40+1);
}
if(K1_num==4)
{
write_com(0x80+9);
}
if(K1_num==5)
{
write_com(0x80+6);
}
if(K1_num==6)
{
write_com(0x80+3);
}
if(K1_num==7)
{
write_com(0x80+12);
}
if(K1_num==8)
{
K1_num=0;
bcd();
writetime();
write_com(0x0c);//关光标,关光标闪烁
flag=0;
}
}
}
if(K1_num!
=0)
{
if(K2==0)
{
delay(5);
if(K2==0)
{
while(!
K2);
if(K1_num==1)
{
if(K4_num==0)
{
time[0]++;
if(time[0]==60)
time[0]=0;
write_lcdline_2(7,time[0]);
write_com(0x80+0x40+7);
}
if(K4_num==1)
{
miao++;
if(miao==60)
miao=0;
write_lcdline_2(7,miao);
write_com(0x80+0x40+7);
}
}
if(K1_num==2)
{
if(K4_num==0)
{
time[1]++;
if(time[1]==60)
time[1]=0;
write_lcdline_2(4,time[1]);
write_com(0x80+0x40+4);
}
if(K4_num==1)
{
fen++;
if(fen==60)
fen=0;
write_lcdline_2(4,fen);
write_com(0x80+0x40+4);
}
}
if(K1_num==3)
{
if(K4_num==0)
{
time[2]++;
if(time[2]==24)
time[2]=0;
write_lcdline_2(1,time[2]);
write_com(0x80+0x40+1);
}
if(K4_num==1)
{
shi++;
if(shi==24)
shi=0;
write_lcdline_2(1,shi);
write_com(0x80+0x40+1);
}
}
if(K1_num==4)
{
time[3]++;
if(time[3]==table2[time[4]-1])
time[3]=1;
write_lcdline_1(9,time[3]);
write_com(0x80+9);
}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 51 单片机 电子钟