《基于单片机数字式时钟的设计单片机设计报告论文毕设论文.doc》由会员分享,可在线阅读,更多相关《基于单片机数字式时钟的设计单片机设计报告论文毕设论文.doc(60页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、目录目录1系统的总体设计11.1仿真电路设计11.1.1仿真电路中各模块的分析11.1.1.1DS1302实时时钟芯片11.1.1.2LCD1602工业字符型液晶21.1.1.3AT89C52CMOS 8位单片机21.1.1.474HC573八进制3态非反转透明锁存器31.1.1.574HC00四与非门41.1.1.6蜂鸣器41.1.1.7Led灯51.1.1.8按键51.2系统流程图分析62系统的软件设计82.1软件各模块分析82.1.1时钟设置模块82.1.2闹铃模块82.1.3显示模块92.2调试结果分析102.3体会与心得112.4附录112.4.1附录1 参考文献112.4.2附录2
2、 源代码11QXYINYONGXIAN1110411231单片机课程设计1 系统的总体设计1.1 仿真电路设计以AT89C52单片机为核心,DS1302实时时钟芯片,设计数字式电子钟。人机接口包括按键、显示器、闹钟指示灯和蜂鸣器等,显示器显示时间,按键可以调节时间,并可控制电子钟的启停、闹钟设置。蜂鸣器作半点和整点报时闹铃,半点和整点报时闹铃,时间延时10秒,自定义闹铃,时间延时30秒。显示器用LCD。图 1.1-1仿真电路1.1.1 仿真电路中各模块的分析1.1.1.1 DS1302实时时钟芯片DS1302是由美国DALLAS公司推出的具有涓细电流充电能力的低功耗实时时钟芯片。DS1302的
3、在实时显示时间中的应用。它可以对年、月、日、周、时、分、秒进行计时,且具有闰年补偿等多种功能。图 1.1.1.1-1 DS1302仿真电路1.1.1.2 LCD1602工业字符型液晶工业字符型液晶,能够同时显示16x02即32个字符。(16列2行。它是一种专门用来显示字母、数字、符号等的点阵型液晶模块。它由若干个5X7或者5X11等点阵字符位组成,每个点阵字符位都可以显示一个字符,每位之间有一个点距的间隔,每行之间也有间隔,起到了字符间距和行间距的作用,正因为如此所以它不能很好地显示图形(用自定义CGRAM,显示效果也不好)。图 1.1.1.2-1Lcd1602仿真电路1.1.1.3 AT89
4、C52CMOS 8位单片机AT89C52是一个低电压,高性能CMOS 8位单片机,片内含8k bytes的可反复擦写的Flash只读程序存储器和256 bytes的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片内置通用8位中央处理器和Flash存储单元,AT89C52单片机在电子行业中有着广泛的应用。图 1.1.1.3-1 AT89C52引脚图1.1.1.4 74HC573八进制3态非反转透明锁存器74HC573包含八进制3态非反转透明锁存器。图 1.1.1.4-1 74HC573引脚图1.1.1.5 74HC00四与非门7
5、4HC00是一款高速CMOS器件,74HC00引脚兼容低功耗肖特基TTL(LSTTL)系列。74HC00遵循JEDEC标准no.7A。74HC00实现了2输入与非门功能。图 1.1.1.5-1 74HC00引脚图图 1.1.1.5-2 74HC00实验电路图1.1.1.6 蜂鸣器输出脉冲到蜂鸣器,蜂鸣器就会响。实验中P3.0口接蜂鸣器,给予特定脉冲可演奏两只老虎的音乐。图 1.1.1.6-2 蜂鸣器1.1.1.7 Led灯输出1到Led灯,Led灯就会亮。实验中P3.1口接Led灯,交替输出1/0到Led灯,实现Led灯的闪烁。图 1.1.1.7-2 Led灯1.1.1.8 按键共有8个按键,
6、功能如下: :选定下一个数值+:光标所在值增加- : 光标所在值减少延时:5分钟后蜂鸣器响定时:按下后开始设定定时时间设置:按下后开始设定时间暂停:时钟停止确定:定时/设置的确定图 1.1.1.8-1 键盘1.2 系统流程图分析 系统流程图分析整点/半点报时定时报时暂停时钟设置时间设置定时时间延时报时开始初始化显示器读取当前时间/或自定义时间显示2秒提示语后清屏显示时间整点/半点定时到按暂停键按设置键按定时键结束关闭程序YNNNNNYYYYY按延时键N图 1.2-1 系统流程图2 系统的软件设计2.1 软件各模块分析2.1.1 时钟设置模块时钟设置分析按设置键获取当前时间选择设置位设置具体时间
7、写入DS1302函数返回按确定键NY2.1.2 闹铃模块时钟设置分析按定时键获取当前时间选择设置位设置具体定时时间保存定时时间函数返回按确定键NY2.1.3 显示模块显示分析转化时间程序被调用读取当前时间显示时间程序返回2.2 调试结果分析在电子时钟设计中程序比较长,遇到了各种各样的问题。因此修改程序的时间很长,有语法错误,也有仿真时功能无法实现的问题,在此不能一一说明,只能对个别问题加以阐述。比如开始时无法对DS1302,写入的值是错误的。将写入的字符值改为数字后,问题解决了。虽然现在回过头来发现这个问题很简单,但当时是百思不得其解。我从中学到:任何事情都会有出错的可能,有些时候人的思路中的
8、一些错误是自己难以发现的,在工作和生活中要多对自己的想法提出质疑。不光是这种明显的问题很多,有些细微的问题也一样出现了,但解决起来并不容易。在最后的硬件实现阶段发现蜂鸣器不响。虽然蜂鸣器接地,但是给蜂鸣器高电平也无法驱动蜂鸣器。最后老师说要给蜂鸣器脉冲才能驱动蜂鸣器。问题得以解决。程序已基本实现要求的如下功能:基本任务:以AT89C52单片机为核心,设计数字式电子钟。人机接口包括按键、显示器、闹钟指示灯和蜂鸣器等,显示器显示时间,按键可以调节时间,并可控制电子钟的启停、闹钟设置。蜂鸣器作半点和整点报时闹铃,闹铃时间延时30秒。显示器可以用数码管或LCD。扩展任务增加:对日期的预设功能,通过按键
9、,切换日期显示或时间显示。其他任务:增加闹钟种类:每日指定时刻闹铃、延时闹铃,可以按任意键,停止闹铃。2.3 体会与心得通过本次课程设计,我对基于单片机数字式时钟的设计有了深入的研究。首先,我对课题进行了分析,分析了任务要求并理出了简单的设计思路。电子钟最关键的就是对89C52芯片、DS1302。接着,我就接着我的设计思路,开始编写程序,调试程序。想法永远是很美好的,到自己开始写程序时,我又开始迷茫了,因为单片机课程是上学期学习的,很多知识点已经忘记了,我又进行了重新的学习。后来我找到了一段相似的程序,然后进行了改编。最后我的程序顺利的调试出来了。通过这次的单片机大实验,使我加深了对单片机的认
10、识,并且熟悉了单片机系统的设计流程,收获丰硕。功能上基本达标:时钟的显示,调时功能。时钟显示功能,精确度完全可以满足日常生活显示时间的需要;调时功能,方便快捷,定时,整点报时,任意键停止闹铃,暂停时钟等。随着现在互联网的越来越发达。网络在本次设计中起到了很大作用,很多芯片资料,传统的纸质图书里是没有的。如何在浩如烟海的网络中提取我们需要的知识也是我必须要提高的,网络作为一个平台,由于大家的无私奉献,才使得它丰富多彩,包罗万象。但从这么多的资料中找到我想要的却不是那么容易,以后得着重加强这方面的能力。从这次的设计中,我真正的体会到,什么叫书到用时方恨少,还有就是理论联系实践的重要性,如何把我们所
11、学的理论知识运用到实际生活当中,这是最难的,也是我最缺的。实践出真知,光有书本上的知识是远远不够的,我明白了,作为一个理工科学生,我必须多动手多实践。2.4 附录2.4.1附录1 参考文献1 单片机原理与应用系统设计-基于C51的Proteus仿真实验指导书2 教科书3 LCD工作原理及其应用方面的资料4 5 潘永雄.新编单片机原理与应用. 第2版6 何宏森.多功能智能电子钟的设计.兵工自动化,20052.4.2附录2 源代码/ main.c/*基于单片机数字式时钟的设计*尹永贤*2014年11月17日-2014年11月28日*yinyongxian*/*引用库函数*/#include /*
12、special function register declarations */#include /* prototype declarations for I/O functions */#include #include #include #include /*/*定义数据类型的简写形式*/#define byte unsigned char#define uchar unsigned char#define word unsigned int#define uint unsigned int#define ulong unsigned long#define BYTE unsigned
13、 char#define WORD unsigned int#define TRUE 1#define FALSE 0/*/void time(unsigned int ucMs);/延时单位:ms/*ds1302.c文件中函数与变量的声明*/extern void ds1302_initial();extern void Ds1302ReadAll();extern void Ds1302DataConver();extern void Ds1302WriteAll();extern char Ds1302Reg; /ds1302内部日期寄存器 (00-06)extern char Date
14、; /时钟数据转换为字符存储extern char DateTime;/*/uchar xdata Lcd1602CmdPort _at_ 0x8000;/E=1 RS=0 RW=0uchar xdata Lcd1602StatusPort _at_ 0x8001;/E=1-0 RS=0 RW=1uchar xdata Lcd1602WdataPort _at_ 0x8002;/E=1 RS=1 RW=0uchar xdata Lcd1602RdataPort _at_ 0x8003;/E=1-0 RS=1 RW=1/*设定闹钟保存所设定的时间*/char year2=0,month2=0,d
15、ay2=0,hour2=0,minute2=0,second2=0,week=1;/*设定时间保存所设定的时间*/char yearT2=0,monthT2=0,dayT2=0,hourT2=0,minuteT2=0,secondT2=0,weekT=1;/*根据SetTime的值设定相应参数*/*0:设置年 1:设置月 2:设置日 3:设置时 4:设置分 5:设置秒 6:设置星期*/char SetTime=0;char delayUp=-1; /为5时变为延时到char startDelay=0; /延时开始#define BUSY0x80/ 忙判别位code uchar exampl=-
16、DS1302/LCD1602 -calendar clock;/首先显示sbit Buzzer = P30; /蜂鸣器的接口sbit Led = P31; /Led灯的接口/Lcd1602驱动函数void LcdWriteData( char dataW );void LcdWriteCommand(uchar CMD,uchar AttribC );void LcdReset( void );void Display( uchar dd );void DispOneChar(uchar x,uchar y,uchar Wdata);void Putstr(uchar x,uchar y, u
17、char code *ptr);void LocateXY(char posx,char posy);/显示光标定位 void displayTTV(void);/显示时间 void Clock(void);/闹钟void yanzou(uchar i,uint pai);/演奏定时音乐void pause(void); /暂停void setled(void); /设置Ledchar anyKeyDown(void); /任意键按下返回真void setNowTime(void); /设置时间void setClock(void); /设置闹钟void integralPoint(void)
18、; /整点或半点报时void delay5Min(void);/延时5分钟 /*主程序*/void main(void)LcdReset(); /初始化Ds1302DataConver();Putstr(0,0,exampl);/显示一个预定字符串exampltime(2000);/保持2秒显示内容Putstr(0,0, );/清屏Led=0; /灭灯/初始化后灯处于灭的状态ds1302_initial(); /设定2014年1月1日0时0分0秒 星期三while(1)/程序初始化后开始循环运行time(300); /防止出现光标移动displayTTV();/显示时间integralPoin
19、t(); /整点或半点报时delay5Min(); /延时5分钟Clock(); /定时时间到程序pause(); /按下暂停键,停止时钟setNowTime();/按下设置键,设置时钟setClock(); /按下定时键,设置闹钟/*设置时间*/void setNowTime(void) /-设置时间开始.-if(P1=0xDF)/按下设置键while(P1=0xDF); Putstr(0,0, );/清屏/获得当前时间值yearT1=Date12;yearT0=Date11;monthT1=Date6;monthT0=Date7;dayT1=Date8;dayT0=Date9;hourT1
20、=Date0;hourT0=Date1;minuteT1=Date2;minuteT0=Date3;secondT1=Date4;secondT0=Date5;weekT=Ds1302Reg5;while(P1!=0x7F)/按确定键设定完成time(200); /显示格式为:*:*:* (表示时分秒)if(P1=0xFE) /按右移while(P1=0xFE); if(SetTime=6) SetTime=0; else SetTime=SetTime+1; DispOneChar(0,0,2); /显示设定的年份DispOneChar(1,0,0);DispOneChar(2,0,year
21、T1);DispOneChar(3,0,yearT0);DispOneChar(4,0,-);DispOneChar(5,0,monthT1); /显示设定的月份DispOneChar(6,0,monthT0);DispOneChar(7,0,-);DispOneChar(8,0,dayT1); /显示设定的日期DispOneChar(9,0,dayT0);Putstr(11,0,Time.); /显示一个预定字符串examplDispOneChar(0,1,hourT1); /显示设定的时DispOneChar(1,1,hourT0);DispOneChar(2,1,:);DispOneCh
22、ar(3,1,minuteT1); /显示设定的分DispOneChar(4,1,minuteT0);DispOneChar(5,1,:);DispOneChar(6,1,secondT1); /显示设定的秒DispOneChar(7,1,secondT0);/switch(Ds1302Reg5)switch(weekT)case 1:Putstr(9,1,Sun);/周日break;case 2:Putstr(9,1,Mon);/周一break;case 3:Putstr(9,1,Tue);/周二break;case 4:Putstr(9,1,Wed);/周三break;case 5:Put
23、str(9,1,Thu);/周四break;case 6:Putstr(9,1,Fri);/周五break;case 7:Putstr(9,1,Sat);/周六break;default:Putstr(9,1,Err);/错误break;/根据SetTime的值修改相应的值:SetTime=0 0:设置年 1:设置月 2:设置日 3:设置时 4:设置分 5:设置秒 6:设置星期 switch(SetTime) case 0:LocateXY(0,0);/ 定位显示地址if(P1=0xFD) /年+while(P1=0xFD); if(yearT0=9)yearT0=0;if(yearT1=9)
24、 yearT1=0;else yearT1=yearT1+1;else yearT0=yearT0+1;else if(P1=0xFB) /年- while(P1=0xFB); if(yearT0=0)if(yearT1=0)yearT1=0;yearT0=0;elseyearT1=yearT1-1; yearT0=9;else yearT0=yearT0-1;break;case 1:LocateXY(5,0);/ 定位显示地址if(P1=0xFD) /月+while(P1=0xFD); if(monthT0=2)if(monthT1=1) monthT1=0; monthT0=1;else
25、 monthT0=monthT0+1;else if(monthT0=9) monthT1=1;monthT0=0;elsemonthT0=monthT0+1; else if(P1=0xFB) /月- while(P1=0xFB); if(monthT0=1)if(monthT1=1) monthT0=0;else monthT1=1;monthT0=2;else if(monthT0=0) monthT1=0;monthT0=9;elsemonthT0=monthT0-1; break;case 2:LocateXY(8,0);/ 定位显示地址if(P1=0xFD) /日+while(P1
26、=0xFD); if(dayT0=1)if(dayT1=3) dayT1=0; dayT0=1;else dayT0=dayT0+1;else if(dayT0=9) dayT1=dayT1+1;dayT0=0;elsedayT0=dayT0+1; else if(P1=0xFB) /日- while(P1=0xFB); if(dayT0=0) dayT1=dayT1-1; dayT0=9;else if(dayT0=1) if(dayT1=0) dayT1=3;dayT0=1;else dayT0=dayT0-1;elsedayT0=dayT0-1; break;case 3:LocateX
27、Y(0,1);/ 定位显示地址if(P1=0xFD) /时+while(P1=0xFD); if(hourT0=3)if(hourT1=2) hourT1=0; hourT0=0;else hourT0=hourT0+1;else if(hourT0=9)hourT0=0; hourT1=hourT1+1;elsehourT0=hourT0+1; else if(P1=0xFB) /时- while(P1=0xFB); if(hourT0=0)if(hourT1=2 | hourT1=1) hourT1=hourT1-1; hourT0=9;else hourT1=2; hourT0=3;el
28、sehourT0=hourT0-1; break;case 4:LocateXY(3,1);/ 定位显示地址if(P1=0xFD) /分+while(P1=0xFD); if(minuteT0=9)if(minuteT1=5) minuteT1=0; minuteT0=0;else minuteT1=minuteT1+1; minuteT0=0;elseminuteT0=minuteT0+1; else if(P1=0xFB) /分- while(P1=0xFB); if(minuteT0=0)if(minuteT1=5 | minuteT1=4 | minuteT1=3 |minuteT1=
29、2 | minuteT1=1) minuteT1=minuteT1-1; minuteT0=9;else minuteT1=5; minuteT0=9;elseminuteT0=minuteT0-1; break;case 5:LocateXY(6,1);/ 定位显示地址if(P1=0xFD) /秒+while(P1=0xFD); if(secondT0=9)if(secondT1=5) secondT1=0; secondT0=0;else secondT1= secondT 1+1; secondT0=0;elsesecondT0=secondT0+1; else if(P1=0xFB) /秒- while(P1=0xFB); if(secondT0=0)if(secondT1=5 | secondT1=4 | secondT1=3 | secondT1=2 | secondT1=1) secondT1=secondT1-1; secondT0=9;else secondT1=5; secondT0=9;elsesecondT0=secondT0-1; break;case 6:LocateXY(9,1);/ 定位显示地址if(P1=0xFD) /星期+while(P1=0
限制150内