单片机智能电子钟报告文件_第1页
单片机智能电子钟报告文件_第2页
单片机智能电子钟报告文件_第3页
单片机智能电子钟报告文件_第4页
单片机智能电子钟报告文件_第5页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

PAGE2-1.系统设计要求1。1基本功能(1)在LCD1602液晶显示器上显示年份、月、日、时、分、秒、星期.(2)闰年平年自动判断,时间日期年份自动变更。(3)用按键任意更改显示的时间:1)S1按键功能是停止时钟,进行设置显示的时间,光标移动。2)在s1按下的时候,s2进行时间的增加。按一次就增加1。3)在s2按下的时候,s3进行时间的减少。按一次就减少1.4)s4是完成设置的按键,时钟开始.同时也是闹钟响应的时候停止闹钟的声音。(4)扩展功能:1)在显示时间的基础上,加入了闹钟的功能.可以随意调闹钟响应的时间。2)到了闹钟判断响应的时候,蜂鸣器启动,发出频率为一秒一次的声音。1。2设计目的掌握单片机系统的开发应用,巩固和加深已学过的知识,提高动手能力及解决实际问题的能力,同时培养团队合作精神。将自己学到的知识更好地运用于实际当中。设计流程本次设计时钟电路,使用了AT89C52单片机芯片控制电路,单片机控制电路简单且省去了很多复杂的线路,使得电路简明易懂,使用键盘键上的按键来调整时钟的年、月、日、时、分、秒,用一扬声器来进行定时闹钟的提醒,同时使用C语言程序来控制整个时钟显示,使得编程变得更容易.2.1课程设计的开发流程1)方案规划。2)用proteus设计硬件电路。3)用汇编语言设计程序。4)用keilC51软件设计调试。5)利用proteus软件进行软件和硬件的联调。6)根据电路图焊接硬件电路。7)下载程序代码,在电路板上调试、检验设计。8)完成设计,撰写课程设计报告。2.2系统的功能及设计思路此设计原理框图如图2—3所示,此电路包括以下四个部分:单片机,键盘,闹铃电路及LCD1602液晶显示屏。经过编译程序仿真后,89C51的4K空间不够用,就选用更大空间的89C52单片机了。本设计用的元器件如列表2-3所示图2-3元器件列表:AT89c521片LCD1602液晶1片PNP三极管1个10up电解电容1个30p电容2个10K电阻1个1K电阻3个按键5个12MHz晶振1个无源蜂鸣器1个表2-32.3工作原理设计的电路主要由四模块构成:单片机控制电路,显示电路、闹铃电路以及按键控制电路。本设计采用C语言程序设计,使单片机控制LCD显示时间,当秒计数计满60时就向分进位,分计数器计满60后向时计数器进位,小时计数器按“23翻0”规律计数。时、分、秒的计数结果经过数据处理可直接送显示器显示。如果小时到达24小时候,就是“23翻0”,日、星期都要加一个单位。其余的闰年平年自动判断。闹钟的部分就是当闹钟的时、分与时钟的时、分相等的情况下,发出信号驱动蜂鸣器,当按下S4的时候,可以令蜂鸣器停止工作.电路功能使用说明:各个控制键的功能:S1可进行光标选择,同时令时钟停止走动。S2可对时间进行校准调节,按键一次增加一个单位。S3可对时间进行校准调节,按键一次减少一个单位。S4进行设置完成的时候推出,也可以在闹钟响应时停止蜂鸣器工作。AT89C52单片机,通过编写程序对LCD显示进行控制。LCD1602液晶显示器显示编译的数据。定时闹钟判断,达到符合情况时候驱动蜂鸣器工作。2。4软件研制方面1)采用模块化程序结构设计软件,首先将整个软件分成若干功能模块;2)根据设计的原理,编写源程序;3)调试各模块程序;4)与硬件一起联调,最后完成全部调试工作。2。5硬件研制方面1)将整个硬件系统划分为若干功能单元电路,会出整个系统逻辑电路,注明注明各交单元电路间接口信号;2)完成各单元电路设计,包括选择合适的各类元器件和电路板设计(元件布局和走线)。3。仿真实现(电路连接图)3。1选取的元器件及作用(1)单片机STC89C52STC89C52是比较常用的52系列单片机.它的工作电压是+5v。外围电路加上12M的晶振,使其正常工作。P0口控制LCD1602。空间有8k。(2)LCD1602液晶1602显示容量为16乘2个字符。工作电压为+5v。编号符号引脚说明编号符号引脚说明1VSS电源地9D2DateI/O2VDD电源正极10D3DateI/O3VL液晶显示偏压信号11D4DateI/O4RS数据/命令选择端12D5DateI/O5R/W读写选择端13D6DateI/O6E使能端14D7DateI/O7D0DateI/O15BLA背光源正极8D1DateI/O16BLK背光源负极4.软件编程按照电路图的设计焊接好硬件电路。就开始软件编程。程序主要分为两个部分,即液晶显示部分和控制按键的部分。由于本设计采用的是用按键分别控制。可以在主函数中调用一个键盘扫描的函数,当相应的不同按键按下后控制液晶显示和单片机P0的输出,从而控制液晶的显示。源程序见附录.本电子时钟共使用了四个按键.第一个按键用于选择所要调节的内容(如年、月、日、时、分、秒),按下不同次数光标分别在要调节的对应位置闪烁;第二个按键用于所调节的量的增加,按下一次增加一个单位;第三个按键用于所调节量的减少,按一下增加一个单位。第四个按键是设置完成退出,并且可以控制闹钟的声音,即是当闹钟响应的时候按下,蜂鸣器立刻停止工作。该电子时钟实现的功能是液晶正常显示时分秒,年月日和星期.不仅可以用按键调节时分秒,还可以调节年月日,并且要保证星期和年月日相对应。在这里需要指出的是由于条件限制(除非有时钟芯片实现万年历),不可能保证星期与年月日正确对应),故采程序中用天数对7取余数,余1时为星期一(MON),余2时为星期二(TUE),依此类推,余0时为星期天(SUN),当天数到每月最后一天时继续上加不回归到1,这样可以保证星期是正确的。具体见程序中注释.编程思路是,在确定了时钟要实现的功能后按照上述各按键所实现的效果编写程序。本程序包含液晶写指令函数(write_com())、写数据函数(write_data())、初始化函数(init())、写入时分秒函数(write_sfm())、写入月和日函数(write_nyr())【别指出,由于年包含四位数字其写法与月和日不同,故单独设置一个写入年函数】、写入星期函数(write_xq())和键盘扫描函数,这些程序围绕主函数互相嵌套调用.5、调试部分本次实验的调试部分花了大量的时间。当程序写好编译通过后,下载到单片机中,调试硬件看有无显示和输出。调试主要分为2个部分。分别是液晶显示部分,按键控制部分。首先是液晶部分,一开始就是无法显示,查看电路后,后来检测才知道是排线的接触不良造成的.经过几次程序的修改,和对液晶部分电路的检测终于将液晶部分调出有显示。然后检查按键部分.首先检查按键的焊接确定无误后,进行按键控制,结果显示良好.6.课程设计结果分析此时钟设计是利用protues仿真软件进行仿真,以及单片机开发箱验证,基本上实现了课程设计要求实现的功能.硬件部分设置了的4个按键.当按键S1按下时,进入光标显示状态,计数器停止工作,时钟也停止,进入设置时间的状态.在S1按下的情况,按键S2按下时,对应光标的数据随着S2按键的按下的次数而变化,具体是按键一次就是增加一个单位。在S1按下的情况,按键S3按下时,对应光标的数据随着S3按键的按下的次数而变化,具体是按键一次就是少一个单位。在增加和减少设置的选项中也加入了闰年平年的判断,更利于设置。S4按下的时候,推出设置状态,计数器工作,开始计时。同时,在闹钟响应的时候按下S4按键就是令蜂鸣器停止工作。调试阶段,出现一些问题。比如,实际小时显示到29才归零,分钟显示到60才进一……经过软件调试,以上问题均一一排除,结果达到预期目标。但时间有限,部分扩展功能不能及时实现,比如音乐闹铃,开启闹钟及关闭闹钟功能等等7。个人心得以及总结之前做设计的不是这个设计,那个设计失败,我感到很受打击,因为自己的理论知识用不了实际当中,学不会用。所以自己决定是简单的开始做起来,就是选择了电子时钟。从最开始的计数开始,利用单片机内部的计数功能,更能准确计数时间。但是我还是不会自己很顺利的编程,所以自己去图书馆借了课程设计的资料回来自己研究。不懂的地方就问同学,一步一步慢慢来,结合书本的资料我成功了编好程序。我之前选择的是数码管显示的,但是在焊接的电路板的时候我遇到了极大的困难,因为我用到的是6位的数码管,而市场只有4位一下的,我买回来2位和4位的扩展成6位,按照网上和书本的资料我焊接好,用单片机开发箱来验证,悲哀的是居然每一个数码管变化都是一样的,后来询问了刘老师,结果还是一样不能显示,最终选择了用LCD1602液晶显示器来显示时间数据了.那个数码管的以后再研究了。可是,那个液晶显示器的编程就完全变了,不同于数码管的引脚一样,然后查了很多的资料,经过无数次在单片机开发显示原理,才掌握了他工作的原理,然后一步一步来自己修改书本的程序,达到自己显示的结果。修改的过程还是很困难的,多的同学的指导,让我少走了很多的弯路。到了最后一步了,焊接电路板,这个倒是不难,因为是之前的几个课程设计都是焊接电路板的,经过几次的焊接经验,自己对焊接有一定的掌握了,所以焊机的很顺利.最后还是显示不了,经过大家的研究,终于指导那是排线的接触不良导致的。这次的设计真的是感悟很多,所有的事情都不是很容易就完成的,必须经过一定的磨练才可以.就是比如焊接的工艺吧,有经验了就焊接的快和好。拥有了知识,也不一定用于实际当中,自己如果不去实践的话,可能真的一辈都不会了解,别把所有的事情都看的那么简单,从小事做起事=是最踏实的。这次是C语言编程的,尽管自己对C语言有很深的接触,但真正让自己顺利的编写的程序的话,那可不是小事一桩,有一定的累积才是霸道!在焊接电路板的时候,应该很好的了解元器件的功能和特性,不然的话自己就很折腾,显示不出来的时候就是很麻烦的,搞不好就要重新焊接一次了。这次设计最大的收获当然就是了解到了单片机的应用,如何应用,可以应用到哪些方面。8.参考文献1)单片机原理及其接口技术(第三版)北京航空航天大学出版社2)单片机应用系统开发实例导航人民邮电出版社3)单片机课程设计辅导书4)模拟电子技术基础童诗白著5)数字电子技术基础阎石著6)以及网上的一些相关的资料附录1源程序#include<reg52.h〉#defineucharunsignedchar#defineuintunsignedintsbitRS=P2^6;sbitRW=P2^5;sbitE=P2^7;sbits1=P1^0;sbits2=P1^1;sbits3=P1^2;sbits4=P1^3;sbitspeaker=P2^0;ucharcodetable[]="2099—12—31MON";ucharcodetable1[]="23:58:5023:59";ucharnum,count,shi=23,fen=58,miao=50;ucharyue=12,ri=31;uintnian=2099;uchars1num,xq;charNshi=23,Nfen=59,clock;/////////////////延时函数/////////////////////////////////voiddelay(ucharz){ uintx,y; for(x=z;x〉0;x——) for(y=110;y〉0;y-—);}////////////////LCD写入指令与数据/////////////////////////voidwrite_com(ucharcom){ RS=0; RW=0; P0=com; delay(5); E=0; delay(5); E=1; }voidwrite_data(uchardate){ RS=1; RW=0; P0=date; delay(5); E=0; delay(5); E=1;}///////////////////数据初始化/////////////////////////////////////voidinit()//初始化{ delay(15); write_com(0x38);//displaymode不监察忙信号 write_com(0x08);//displaymode write_com(0x01);//displaymode显示清屏 write_com(0x06);//显示光标移动位置 write_com(0x0c);//显示开及光标设置 write_com(0x01);//显示清屏 write_com(0x80); write_com(0x02); for(num=0;num<15;num++) { write_data(table[num]); delay(20); } write_com(0x80+0x41); for(num=0;num〈15;num++) { write_data(table1[num]); delay(20); } TMOD=0x01;//t016位计数器 EA=1; ET0=1; TR0=1; TH0=(65536-50000)/256;//赋值初值12MHz晶振 TL0=(65536—50000)%256;}///////////////写入时、分、秒、日、月等数据////////////////////////////voidwrite_sfm(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)//只写入月和日(月和日均只有十位和个位,写法相同){ ucharshi,ge; shi=date/10; ge=date%10; write_com(0x80+add); write_data(0x30+shi); write_data(0x30+ge);}voidwrite_nian(ucharadd,uintyear)//写入年{ uintqian,bai,shi,ge; qian=year/1000;//2413/1000=2(得到千位) bai=(year%1000)/100;//(2413%1000)=413413/100=4(得到百位) shi=((year%1000)%100)/10;//413%100=1313/10=1(得到十位) ge=(((year%1000)%100))%10;//13%10=3(得到个位) write_com(0x80+add);//地址指向第一行 write_data(0x30+qian);//写数据 write_data(0x30+bai); write_data(0x30+shi); write_data(0x30+ge);}//////////////////////写入星期数据////////////////////////////voidwrite_xq1(ucharadd)//星期一{ write_com(0x80+add);//第一行 write_data(0x40+0x0d);//查询液晶的字符手册可知MON(星期一) write_data(0x40+0x0f);//这三个英文字符对应的二进制码 write_data(0x40+0x0e);//}voidwrite_xq2(ucharadd)//星期二{ write_com(0x80+add); write_data(0x54); write_data(0x55); write_data(0x45);}voidwrite_xq3(ucharadd)//星期三{ write_com(0x80+add); write_data(0x50+4); write_data(0x40+8); write_data(0x50+5);}voidwrite_xq4(ucharadd)//星期四{ write_com(0x80+add); write_data(0x57); write_data(0x45); write_data(0x4e);}voidwrite_xq5(ucharadd)//星期五{ write_com(0x80+add); write_data(0x46); write_data(0x52); write_data(0x49);}voidwrite_xq6(ucharadd)//星期六{ write_com(0x80+add); write_data(0x53); write_data(0x41); write_data(0x54);}voidwrite_xq7(ucharadd)//星期日{ write_com(0x80+add); write_data(0x53); write_data(0x55); write_data(0x4e);}voidwrite_naozhong(ucharadd,uchardate){ ucharshi,ge; shi=date/10; ge=date%10; write_com(0x80+0x40+add);//地址指向第二行,在第二行写 write_data(0x30+shi);// write_data(0x30+ge);}//////////////////按键设置////////////////////////////////////////按键1设置,光标设置//////voidkeyscan()//按键控制函数{ if(s1==0)//按键1 { delay(5);//按下消抖 if(s1==0) { s1num++;//s1num1是按键1的标志变量,表示按键1按下的次数 while(!s1);//按键弹起时消抖 if(s1num==1) { TR0=0;//时间停止走 write_com(0x80+0x40+8);//按键1按下时,光标显示位置第二行12位 write_com(0x0f);//光标在秒个位闪烁,调秒 } if(s1num==2) { write_com(0x80+0x40+5);//按键1按下第二次,光标在分个位闪烁,调分 } if(s1num==3) { write_com(0x80+0x40+2);//按键1按下第三次,光标在时位闪烁,调时 } if(s1num==4) { write_com(0x80+4);//按键1按下第四次,光标在年位闪烁,调年 } if(s1num==5) { write_com(0x80+7);//按键1按下第五次,光标在月个位闪烁,调月 } if(s1num==6) { write_com(0x80+10);//按键1按下第六次,光标在日个位闪烁,调日 } if(s1num==7) { write_com(0x80+12);//按键1按下第七次,光标在星期个位闪烁,调星期 }if(s1num==8){ write_com(0x80+0x40+12); } if(s1num==9){ write_com(0x80+0x40+15); } if(s1num==10) { s1num=0;//重新回到开始的位置 write_com(0x0c);//光标按下第七次,光标回到秒个位, TR0=1;////////////////时间开始走。 } } } //////////////////////按键2设置,增加///////////////// if(s1num!=0)//按键按下执行以下操作,按键2的设置 { if(s2==0)//按键2的作用为按下时使想要调整的时分秒,年月日等数值增加 { delay(5); if(s2==0) { while(!s2); if(s1num==1) { miao++; if(miao==60) miao=0; write_sfm(7,miao);//刷新屏幕,将新的秒的值显示出来,其中秒的位置为0X80+0X40+8,从此位置开始写新的秒值 write_com(0x80+0x40+8); } if(s1num==2) { fen++; if(fen==60) fen=0; write_sfm(4,fen);//刷新屏幕,将新的分的值显示出来,其中分的位置为0X80+0X40+5,从此位置开始写新的分值 write_com(0x80+0x40+5); } if(s1num==3) { shi++; if(shi==24) { shi=0; write_sfm(1,shi); write_com(0x80+0x40+2);//刷新屏幕,将新的时的值显示出来,其中时的位置为0X80+0X40+2,从此位置开始写新的时值? } } if(s1num==4) { nian++; write_nian(1,nian);//刷新屏幕,将新的年的值显示出来,其中年的位置为0X80+4,从此位置开始写新的年值 write_com(0x80+4); } if(s1num==5) { yue++; if(yue==13) yue=1; write_nyr(6,yue);//刷新屏幕,将新的月的值显示出来,其中月的位置为0X80+7,从此位置开始写新的月值 write_com(0x80+7); } if(s1num==6) { ri++; if(yue==2&&(nian%4==0)&&ri==29)ri=1;//闰年2月天数计算if(yue==2&&(nian%4!=0)&&ri==30)ri=1;//平年2月if((yue==4||yue==6||yue==9||yue==11)&&ri==31)ri=1;//4,6,9,11月计算elseif(ri==32)ri=1;//1,3,5,7,8,10,12月天数计算 write_nyr(9,ri);//刷新屏幕,将新的日的值显示出来,其中日的位置为0X80+10,从此位置开始写新的日值 write_com(0x80+10); } if(s1num==7) { xq++; if(xq%7==0) write_xq1(12); if(xq%7==1) write_xq2(12); if(xq%7==2) write_xq4(12); if(xq%7==3) write_xq3(12); if(xq%7==4) write_xq5(12); if(xq%7==5) write_xq6(12); if(xq%7==6) write_xq7(12); write_com(0x80+12); } if(s1num==8) { Nshi++; if(Nshi==24) Nshi=0; write_naozhong(11,Nshi); write_com(0x80+0x40+11); } if(s1num==9) { Nfen++; if(Nfen==60) Nfen=0; write_naozhong(14,Nfen); write_com(0x80+0x40+14); } } } } ////////////////////按键3的设置,减少////////////////////if(s1num!=0)//按键按下执行以下操作,按键3的设置 { if(s3==0)//按键3的作用是按下时使想要调整的时分秒,年月日等数值减少 { delay(5); if(s3==0) { while(!s3); if(s1num==1) { miao-—; if(miao==—1) { miao=59; } write_sfm(7,miao); write_com(0x80+0x40+8); } if(s1num==2) { fen-—; if(fen==-1) fen=59; write_sfm(4,fen); write_com(0x80+0x40+5); } if(s1num==3) { shi-—; if(shi==-1) shi=23; write_sfm(1,shi); write_com(0x80+0x40+2); } if(s1num==4) { nian——; write_nian(1,nian); write_com(0x80+4); } if(s1num==5) { yue—-; if(yue==0) yue=12; write_nyr(6,yue); write_com(0x80+7); } if(s1num==6) { ri—-; if(yue==2&&(nian%4==0)&&ri==0)ri=28;if(yue==2&&(nian%4!=0)&&ri==0)ri=29;if((yue==4||yue==6||yue==9||yue==11)&&ri==0)ri=30;elseif(ri==0)ri=31; write_nyr(9,ri); write_com(0x80+10); }if(s1num==8) { Nshi——; if(Nshi<0) Nshi=23; write_naozhong(11,Nshi); write_com(0x80+0x40+11); } if(s1num==9) { Nfen——; if(Nfen<0) { Nfen=59; write_naozhong(14,Nfen); write_com(0x80+0x40+14); } } } } }//////////////////按键4的设置,退出////////////////// if(s4==0){ delay(5); if(s4==0) { while(!s4); if(s1num<=9&&s1num!=0) { s1num=0; TR0=1; write_com(0x0c); } if(Nshi==shi&&Nfen==fen)/////停止闹钟 { clock=0; speaker=1; } } }}voidalarm(){if(Nfen!=fen)clock=1;if(clock==1){ if(Nshi==shi&&Nfen==fen){ if(count==0)//设置蜂鸣器响的拼率为一秒一次,0为响 speaker=0; if(count==10) speaker=1; }}}////////////////////主函数/////////////////////////voidmain(){ init(); while(1) { alarm(); keyscan(); if(count==20)//定时器计满值进入中断20次,时长20*50000=1秒 { count=0; miao++; if(miao==60) { miao=0; fen+

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论