毕业设计单片机智能电子钟设计.docx
《毕业设计单片机智能电子钟设计.docx》由会员分享,可在线阅读,更多相关《毕业设计单片机智能电子钟设计.docx(29页珍藏版)》请在冰豆网上搜索。
毕业设计单片机智能电子钟设计
目录
目录1
一设计内容及要求1
1.1设计内容1
1.2设计要求2
1.3设计报告主要内容2
二总体设计方案2
2.1设计方案原理图2
2.1.1原理框图2
2.1.2电路原理图4
2.1.3方案讨论4
2.1.4设计任务明晰5
2.2程序框图5
2.3调试7
2.3.1软件调试7
2.3.2仿真调试8
三项目设计总结或结论8
参考文献9
附录9
一设计内容及要求
1.1设计内容
以AT89C52单片机为核心,外加LCD1602。
制作一LCD显示的智能电子钟。
1.2设计要求
(1)计时:
秒、分、时、天、周、月、年。
(2)闰年自动判别。
(3)自定任意时刻自动开/关屏。
(4)计时精度:
误差≤1秒/月(具有微调设置)。
(5)键盘采用动态扫描方式查询。
所有的查询、设置功能均由功能键K1、K2完成。
1.3设计报告主要内容
单片机课程设计是以课题或项目设计方式开设的一门课程,具有较强的综合性、实践性,是工科、工程类院校电类的一门必修课。
是将单片机原理的理论知识转化为应用技术的重要环节。
这个环节不但可以加深对单片机原理的深入了解,而且还能培养学生的实践动手能力,开发学生的分析、解决问题的能力。
二总体设计方案
2.1设计方案原理图
2.1.1原理框图
2.1.2电路原理图
图二电路原理图
2.1.3方案讨论
方案一:
采用实时时钟芯片
实时时钟芯片具有年、月、日、星期、时、分、秒计时功能和多点计时功能,计时数据的更新每秒自动进行一次,不需程序干预。
计算机可通过中断或查询方式读取计时数据进行显示,因此计时功能的实现无需占用CPU时间,程序简单。
此外,实时时钟芯片多数带有锂电池做后备电源,具有永不停止的计时功能,具有可编程方波输出功能,可用作实时测控系统的采样信号等。
有的实时时钟芯片内还带有非易失性RAM,可用来长期保存但有时也需变更数据,由于功能完善,精度高,软件程序设计简单,且计时不占用CPU时间,因此,在工业实时测控系统中多采用这一类专用芯片来实现实时时钟功能。
方案二:
软件控制
利用单片机内部的定时/计数器进行中断定时,配合软件延时实现时、分、秒的计时和秒表计时。
该方案节省硬件成本,且能使设计者对单片机的指令系统能有更深入的了解,从而掌握单片机应用技术的程序设计方法,因此,本系统设计采用此种软件控制方式来实现计时。
而有Atmel公司的AT89C52是一种自带8KBFlash存储器的低电压、高性能的COMS8位微处理器。
该器件采用Atmel高密度非易失性存储器制造技术制造,与工业标准的MCS-51指令集和输出引脚相兼容。
AT89C52将多功能8位CPU和闪存集成在一个芯片中,是一个高效的微控制器,使用也更方便,寿命更长,可以反复擦除1000次。
形成了强大的功能、使用灵活和具有较高性价比的微控制器。
它的功能强大,而且也比较容易购买,故本设计选用单片机芯片为AT89C52。
2.1.4设计任务明晰
采用AT89C52单片机作为系统的控制核心。
时钟数据通过市场上流行的时钟芯片DS1302来获取。
DS1302是DALLAS公司推出的涓流过串行接口与计算机进行通信,使的管脚数量减少。
实时时钟/日历电路可以计算2100年之前的秒、分、时、日、星期、月、年的具有闰年自动判别调整功能。
实时电路能够实现自定任意时刻自动开/关屏,采用LCDLM016L显示年、月、日、星期、时、分、秒。
通过开关实现微调,确保计时精确:
误差小于1秒/月。
DS1302时钟芯片的主要功能特性:
(1)能计算2100年之前的年、月、日、星期、时、分、秒的信息;每月的天数和闰年的天数可以自动调整;时钟可设置为24或12小时格式。
(2)31B的8位暂存数据存储RAM.
(3)串行I/O口方式使得引脚数量最少。
(4)DS1302与单片机之间能简单地采用串行的方式进行通信,仅需3根线。
(5)宽范围工作电压2.0-5.5V。
(6)工作电流为2.0A时,小于300nA。
功耗很低,保持数据和时钟信息时功率小于1mA。
2.2程序框图
图三
2.3调试
2.3.1软件调试
目前设计过程中容易造成原件和仪器仪表的损坏,而借助Keil和Proteus进行单片机系统的开发,可以节省设计成本,提高设计速度。
Keil软件包是一个功能强大的开发平台,它包括项目管理器、CX51编译器、AX51宏汇编器、BL51/LX51连接定位器、RTX51实时操作系统、Simulator软件模拟器及Monitor51硬件目标调试器。
它是一种集成化程度高的文件编译环境,主要功能为编译C语言源程序,汇编程序和混合语言源程序,连接和定位目标文件和库,创建HEX文件,调试目标程序等。
Keil是目前最好的51系列单片机开发工具之一。
Keil支持软件模拟仿真(Simulator)和用户目标测试(Monitor51)两种工作模式。
前者不需要任何单片机硬件即可完成用户程序仿真、调试,后者利用软件目标板中的监控程序可以直接调试目标硬件系统。
Proteus是一个完整的嵌入式系统软件、硬件设计仿真平台,它包括原理图输入系统ISIS、带扩展的Prospice混合模拟仿真器、动态元件库、高级图形分析模块和处理器虚拟系统仿真模型VSM。
ISIS是Proteus系统的中心,具有超强的控制原理设计环境。
ProteusVSM最重要的特点是把微处理器软件作用在处理器上,并和该处理器的任何模拟和数字原件协同仿真,仿真执行目标码就像在真正的单片机系统上运行一样,VSMCPU模型能完整仿真I/O接口、中断、定时器、通用外部设备口及其他与CPU有关的外部设备,甚至能仿真多个处理器。
2.3.2仿真调试
图四仿真图
三项目设计总结或结论
一分耕耘,一分收获。
只有亲自用实践来验证这句话,在能得其要领。
经过这次单片机课程设计,我从一个单片机实践的门外汉,已经越升为略知一二的新手。
虽然还有很多有关单片机的应用有待学习,但万变不离其宗,只要深入了解单片的原理,全部知识点,各个细节,一切设计皆有可能。
在实验的开始几天,基本上没有收获,不知何从下手,不知所措。
为了看得更远,不妨站在前人的肩膀上,我在整体思路模糊的情况下,在网上大量招资粮,各种与电子时钟相关的文章,我阅读了不少。
随着涉猎的点滴积累,我对电子时钟的设计方案已经慢慢酝酿而成。
有了方向和不少知识储备后,在接下来的几天,几乎每天都有突破,虽然有时只是一句程序的修改或诞生,但那种收获的感觉很暖人心。
参考文献
《单片机原理与应用》倪云峰主编
《51单片机c语言教程》郭天祥主编
《51单片机原理与应用》陈海宴主编
《单片机c语言应用100历》王东锋主编
附录
项目设计
评语
项目设计
成绩
指导教师
(签字)
年月日
程序
#include
#defineucharunsignedchar
#defineuintunsignedint
#defineulongunsignedlong
ucharcodetable[]="2011:
01:
01000";
ucharcodetable1[]="00:
00:
0000:
00";
ucharcodetable2[]="0123456789";
sbitlcd_rs=P3^3;//定义LCD端口
sbitlcd_rw=P3^4;
sbitlcd_en=P3^5;
sbitSclk=P2^6;
sbitIo=P2^7;
sbitRst=P2^5;
sbitS1=P1^0;//菜单键
sbitS2=P1^1;//加键
sbitS3=P1^2;//减键
sbitS4=P1^3;//退出菜单键
sbitss=P1^4;//秒表键,第一次启动,第二次暂停,第三次清零
sbitFMQ=P2^3;
voidyue31();//31天的月份函数
voidyue30();//30天的月份函数
voidyue29();//29天的月份函数
voidyue28();//28天的月份函数
voidTiming();//闹钟设置
voidmiaobiao();//秒表函数
ucharcount,k1num;//声明秒的变量
charshi,fen,miao;//声明时分秒
uintnian,yue,ri,ji=0,mm=0;//声明年月日,秒表计数,和秒表按键次数
ucharf,s;//定时器/
voiddelay(ucharz)//延时函数
{
ucharx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
voidwrite_com(ucharcom)//lcd写指令
{
lcd_rs=0;
lcd_rw=0;
lcd_en=0;
P0=com;
delay(5);
lcd_en=1;
delay(5);
lcd_en=0;
}
voidwrite_data(uchardate)//lcd写数据
{
lcd_rs=1;
lcd_rw=0;
lcd_en=0;
P0=date;
delay(5);
lcd_en=1;
delay(5);
lcd_en=0;
}
voidmiaobiao(charkk)//秒表函数
{
ucharbiao_bai,biao_shi,biao_ge;
biao_bai=kk/100;
biao_shi=kk%100/10;
biao_ge=kk%100%10;
write_com(0x80+13);
write_data(table2[biao_bai]);
write_com(0x80+14);
write_data(table2[biao_shi]);
write_com(0x80+15);
write_data(table2[biao_ge]);
write_com(0x0c);
}
voidwrite_fsm(ucharadd,uchardate)//计算时分秒位
{
ucharshi,ge;
shi=date/10;
ge=date%10;
write_com(0x80+0x40+add);
write_data(0x30+shi);
write_data(0x30+ge);
}
voidwrite_nyr(ucharadd,uchardate)//计算月日位
{
uintshi,ge;
shi=date/10;
ge=date%10;
write_com(0x80+0x00+add);
write_data(0x30+shi);
write_data(0x30+ge);
}
voidwrite_nian(ucharadd,uchardate)//计算年位,年是百位
{
uintbai,shi,ge;
bai=date/100%10;
shi=date/10;
ge=date%10;
write_com(0x80+0x00+add);
write_data(0x30+bai);
write_data(0x30+shi);
write_data(0x30+ge);
}
voidjiaxian()//设置键盘加显
{
if(k1num!
=0)
{
if(S2==0)
{
delay(10);
if(S2==0)
{
while(!
S2);//松手检测
if(k1num==1)
{
miao++;
if(miao==60)
miao=0;
write_fsm(8,miao);
//write_com(0x0e);
write_com(0x80+0x40+8);
}
if(k1num==2)
{
fen++;
if(fen==60)
fen=0;
write_fsm(5,fen);
write_com(0x80+0x40+5);
}
if(k1num==3)
{
shi++;
if(shi==24)
shi=0;
write_fsm(2,shi);
write_com(0x80+0x40+2);
}
if(k1num==4)
{
ri++;
if(ri==31)
ri=1;
write_nyr(8,ri);
write_com(0x80+0x00+8);
}
if(k1num==5)
{
yue++;
if(yue>12)
yue=1;
write_nyr(5,yue);
write_com(0x80+0x00+5);
}
if(k1num==6)
{
nian++;
if(nian==90)
nian=0;
write_nian(1,nian);
write_com(0x80+0x00+1);
}
if(k1num==7)
{
s++;
if(s==24)s=0;
write_fsm(11,s);
write_com(0x80+0x40+11);
}
if(k1num==8)
{
f++;
if(f==59)
f=0;
write_fsm(14,f);
write_com(0x80+0x40+14);
}
}
}
}
}
voidjianxian()//设置键盘减显
{
if(k1num!
=0)
{
if(S3==0)//K3设置
delay(10);
if(S3==0)
{
while(!
S3);
if(k1num==1)
{
miao--;
if(miao==-1)
miao=59;
write_fsm(8,miao);
write_com(0x80+0x40+8);
}
if(k1num==2)
{
delay(5);
fen--;
if(fen==-1)
fen=59;
write_fsm(5,fen);
write_com(0x80+0x40+5);
}
if(k1num==3)
{
shi--;
if(shi==-1)
shi=23;
write_fsm(2,shi);
write_com(0x80+0x40+2);
}
if(k1num==4)
{
ri--;
if(ri<1)
ri=31;
write_nyr(8,ri);
write_com(0x80+0x00+8);
}
if(k1num==5)
{
yue--;
if(yue<1)
yue=12;
write_nyr(5,yue);
write_com(0x80+0x00+5);
}
if(k1num==6)
{
nian--;
if(nian==0)
nian=90;
write_nian(1,nian);
write_com(0x80+0x00+1);
}
if(k1num==7)
{
s--;
if(s==0)
s=23;
write_fsm(11,s);
write_com(0x80+0x40+11);
}
if(k1num==8)
{
f--;
if(f==-1)
f=59;
write_fsm(14,f);
write_com(0x80+0x40+14);
}
}
}
}
voidkeyk4()//S4是退出菜单键
{
if(S4==0)
{
delay(5);
if(S4==0)
TR0=1;
{
while(!
S4);
k1num=0;
write_com(0x0c);//开显示,不显示光标,光标不闪烁
}
}
}
voidkeyk1()//菜单光标设置
{
if(S1==0)
{
delay(10);
while
(1){
if(S1==0)
{
while(!
S1);
k1num++;
TR0=0;//关定时中断
if(k1num==1)
{
write_com(0x80+0x40+8);
write_com(0x0f);//开显示,显示光标,光标闪烁
}
if(k1num==2)
{
write_com(0x80+0x40+5);
write_com(0x0f);
}
if(k1num==3)
{
write_com(0x80+0x40+2);
write_com(0x0f);
}
if(k1num==4)
{
write_com(0x80+0x00+8);
write_com(0x0f);
}
if(k1num==5)
{
write_com(0x80+0x00+5);
write_com(0x0f);
}
if(k1num==6)
{
write_com(0x80+0x00+1);
write_com(0x0f);
}
if(k1num==7)
{
write_com(0x80+0x40+11);
write_com(0x0f);
}
if(k1num==8)
{
write_com(0x80+0x40+14);
write_com(0x0f);
}
if(k1num==9)
{k1num=1;}
}
}
jiaxian();
jianxian();
keyk4();
}
}
voidinit()//启动LCD初始化数据
{
ucharnum;
lcd_rs=0;
lcd_en=0;
shi=0;
fen=0;
miao=0;
nian=0000;
yue=7;
ri=1;
s=21;
f=48;
write_com(0x38);//不监察忙信号
write_com(0x0f);//显示开光标设置
write_com(0x06);//显示光标移动设置
write_com(0x01);//显示清屏
write_com(0x80);//数据指针
write_com(0x80+0x00);
for(num=0;num<16;num++)//延时15ms
{
write_data(table[num]);//年月日的数据延时
delay(5);
}
write_com(0x80+0x40);
for(num=0;num<16;num++)
{
write_data(table1[num]);//时的延时
delay(5);
}
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
}
voiddisplay()
{
if(count==20)//是秒是的时间
{
count=0;
miao++;
if(miao==60)
{
miao=0;
fen++;
if(fen==60)
{
fen=0;
shi++;
if(shi==24)
{
shi=0;
ri++;
}
if(yue==2)
{
if((nian%4==0&&nian%100!
=0)|(nian%400==0))//计算闰年
{
yue29();
}
else
{
yue28();
}
}
elseif((yue==4)|(yue==6)|(yue==9)|(yue==11))//计算大小月
{
yue30();
}
else
{
yue31();
}
if(yue>12)
{
yue=1;
nian++;
}
{
if(nian>999)
nian=0;
write_nian(1,nian);
}
{
write_nyr(5,yue);
}
{
write_nyr(8,ri);
}
write_fsm(2,shi);
}
write_fsm(5,fen);
}
write_fsm(8,miao);
{
write_fsm(11,s);
}
{
write_fsm(14,f);
}
}
}
voidyue31()//31天的月份
{
if(ri>31)
{
ri=1;
yue++;
}
}
voidyue30()//30