《课程设计(论文)基于单片机的电子钟设计报告.doc》由会员分享,可在线阅读,更多相关《课程设计(论文)基于单片机的电子钟设计报告.doc(26页珍藏版)》请在三一办公上搜索。
1、物理机电学院课程设计报告课程名称: 基于单片机的电子钟 系 部: 物理与机电工程学院 专业班级: 09电子信息工程(2)班 学生姓名: / 指导教师: 王清辉 完成时间: 2012年3月18日 报告成绩: 评阅意见: 评阅教师 日期 基于单片机的电子钟设计报告一、设计任务与要求基于单片机的电子钟,设计要求是(1)具有小时分秒时间显示。(2)能够设置闹钟至少5次闹钟时间。(3)可利用按键修改时间,具有上午下午的提示信息。二、方案设计与论证本次方案的设计以单片机中的定时为主,分别实现时、分、秒、时、年、月、日上的显示和正常进位,在此基础上,总体方案可分为以下四个功能模块:模块一:计时功能模块,以微
2、机开发系统中51单片机的定时功能为主,本次设计采用的计时方式为方式2,并且采用中断方式进行一秒计时,由于51单片机的功能特性的限制,计时的方案由采用100ms计时并且在这个基础上连续循环10次进行秒钟计时,在秒的基础上再分别进行其他时间单位的转化,如此逐渐递进实现总体时间计时的实现。时进制采用24小时进制,年份显示只能实现099之间的显示。模块二:显示功能模块,主要以微机开发系统中的七段液晶显示实现,显示的主要格式为“时/年分/月秒/日”,其中,年、月、日的显示由微机开发系统中的按键实现切换。模块三:闹钟功能模块:以蜂鸣器的蜂鸣为标志,蜂鸣器工作则表示预定时间到达。闹钟的设定由按键开关实现,闹
3、钟的开关有拨键开关控制。模块四:控制功能模块:主要以微机开发系统 中的按键和拨键开关实现,按键开关主要用作时间设置,日期设置和闹钟设置以及对时间和日期的显示的转换。拨键开关主要用来实现闹钟的开关设置。在按键开关的防抖动处理上,以在程序中进行10ms的延时来进行处理。电子钟的总体功能原理是以AT89S51单片机为主要的控制核心,通过外接8个独立式键盘作为控制信号源,两个四位一体数码管作为显示器件,单片机实时的去执行相应的功能。在数码管上显示出来,此时通过不同的按键来观察和调节各种数据三、硬件电路设计3.1 硬件功能模块介绍3.1.1 时钟功能模块时钟电路用于产生MCS-51单片机工作时所需要的时
4、钟控制信号,MCS-51单片机的内部电路在时钟信号控制下,严格地按照时序执行指令进行工作,而时序所研究的是指令执行中各个信号在时间上的关系。单片机各个功能部件的运行都是以时钟控制信号为基准,有条不紊的一拍一拍地工作。因为,时序频率直接影响单片机的速度。时钟电路通过在芯片的外部XTAL1和XTAL2两个引脚跨接晶体振荡器和微调电容,形成反馈电路,就构成了一个稳定的自激振荡电路。时钟电路为单片机产生时钟脉冲序列,晶振频率为12MHz。3.1.2 键盘功能模块为了方便时钟调整与秒表的控制,在单片P1口口线上接了独立键盘,采用低电平有效地方法。在本次电子钟设计中,调整是与键盘脱不了关系的,因为键盘是机
5、械按钮,所以在触点闭合及释放的瞬间将出现电压抖动,所以在键扫描时应该要消除抖动,而且对于一键多功能的按钮必须要判释放,以免某个程序段多次执行。3.1.3 数码管显示模块数码管显示器是单片机重要的输出设备,它不仅具有发光响应快,高频特性好,而且机械性能好,工作电压低,随着工艺发展,可以发出不同颜色的光。在本次设计中,采用共阳极数码管,利用三极管驱动器段控口以便LED发出较亮的光。在本次设计中采用了两个四位一体数码管,数码管的段控接在AT89S52单片机的P0口线上,从a到dp与P0.0到P0.7对应连接,位控制线接在AT89S52单片机的P2口线上,从LED0到LED7与P2.0到P2.7对应连
6、接3.1.4 复位电路模块复位是单片机的初始操作,其主要功能是把PC初始化为0000H,使单片机从0000H单元开始执行程序。除了进入系统的正常初始化之外,当由于程序运行出错或操作错误使系统处于死锁状态时,为摆脱困境,也需安装复位键以重新启动。复位操作有上电自动复位和按键手动复位两种方式。复位电路通过极性电容和1个电阻串联,电容接VCC,电阻接地完成了上电复位,在电容两端并联一个电阻就可以实现按键电平复位。3.2 原理图、PCB图、元器件布局图3.2.1 电路原理图3.2.2 PCB图3.2.3 原件清单元件序号型号主要参数数量1电阻1K1个2电阻200欧1个3瓷片电容1041个4瓷片电容30
7、PF2个5三极管Pnp90121个6蜂鸣器5V1个7晶振12M1个8轻触按键6个9单片机STC89S511个10排阻10K1排11排针4个12IC座40脚1个13蓝白可调1个14LCD16021个151602液晶插针1个四、软件设计4.1 单片机资源使用说明(1) 单片机片内定时/计数器0:用于定时50ms。(2) 单片机片内定时/计数器1:用于定时10ms。(3) 单片机P1口接按键:用于对电子钟、秒表调整与控制(4) 单片机P0口接数码管段控口:P0.0P0.7对应于LED的adp(5) 单片机P2口接数码管位控:P2.7P2.0对应于LED的70(6) 单片机P3.1接蜂鸣器:作为电子钟
8、调整时提醒信号4.2 软件系统各模块功能介绍(1)主程序模块:程序的初始化及复位后显示P.,此时进入功能选择状态,按下K0选择电子钟并同时启动电子钟,按下K1选择秒表并进入秒表等待状态。两功能中一种功能被选择与令外一种功能无半点关系,两者是互不影响。 (2)电子钟程序模块:当电子钟选择键按下时,先给缓冲区内清零,在通过查表给缓冲区一次送00-00-00并实现让00-00-00从左向右显示,一旦显示完则开启定时器开始计时,如果没有键按下则不断计时一直从00-00-00到23-59-59,然后重新从00-00-00开始。这里采用定时器中断完成计时功能。如果有键按下则启动2s定时,累计2s内K0按下
9、的次数,按下1次则进入调秒状态,按下2次则进入调分状态,按下3次则进入调时,按下多次则无效,进入调整状态时,调整的改两位闪动显示并且蜂鸣器鸣叫以示提醒,次数按下K0键作为确认,按下K1就加1,按下K2就减1。(3)秒表程序模块:当秒表选择键按下时,先给缓冲区送灭代码序号。再依次送00H代码序号以实现00000000依次从右向左显示,显示到最左端则进入秒表等待状态。按下K1开始计时,秒表最小计时单元是0.01s,采用定时器中断的方法。秒表运行时再次按下K1键则暂停计时,此时可以选择继续和重新计时,分别按K1和K0。(4)主要子程序模块:为了方便软件程序编写,编写了许多子程序,有键扫描程序,用来判
10、是否有键按下;有显示子程序,用于数码管的显示;有加1、减1子程序,用于对电子钟时分秒的调整;还有延时程序,用于数码管动态显示、键扫描消抖动、延时。4.3 软件系统程序流程框图主程序流程框图如图3.1所示电子钟功能程序流程框图如下图3.2所示,左半部分为定时器0中断服务程序,右部分为电子钟主体程序。图3.2 整个电子钟程序框图4.4 软件系统的程序#include #define uchar unsigned char#define uint unsigned intsbit lcden=P34;sbit rs=P35;sbit FM=P23;sbit s4=P13;sbit s1=P10;sb
11、it s2=P11;sbit s3=P12;uchar count,date,s1num,temp,csnum;uint nian=2012;char yue=03,ri=22,xq=2,shi,fen,miao,shi_c,fen_c,s_c5,f_c5,num_c=1,ri_c;bit flag,setpage,shuaxin;uchar code table= 2012.03.22 Thu;uchar code table1= 00:00:00;/初始化要在这里改数值uchar code table3= HELLO! _ !;/uchar code table4= welcome!;uc
12、har code table5= Successfully;uchar code table6= Saved!_;uchar code table7=am;uchar code table8=pm;uchar code table9= ;void keyscan();void delay(uint z);void write_com(uchar com);void write_date(uchar date);void write_sfm(uchar add,uchar date);void word(uchar add,unsigned char *str) ;/写字符串void write
13、_nyr(uchar add,uchar date);void write_nian();void init();void clock();void welcome();void beep(uchar t);void delay1(uint z);void save();void myupdate();void colon();void mychar();void main() welcome();delay(500);init();while(1)keyscan();clock();/执行闹钟程序/以下为时钟程序 if(miao%2)&csnum=0) colon(); mychar();i
14、f(count=20)count=0;miao+;if(miao=60)/如果秒不到60,则只刷新秒miao=0;fen+;if(fen=60)fen=0; shi+;if(shi=24)shi=0; xq+;write_com(0x80+12);if(xq=8)xq=1;if(xq=1)word(12,Mon);if(xq=2)word(12,Tue);if(xq=3)word(12,Wed);if(xq=4)word(12,Thu);if(xq=5)word(12,Fri);if(xq=6)word(12,Sat);if(xq=7)word(12,Sun);ri+;/接下来要大小月,在二月
15、时要判断是否闰年/如果是闰年,则为29天if(yue=7)temp=yue%2;switch(temp) case 0:/0为小月if(yue=2)/如果为二月,则判断是不是闰年,是为29天,不是为28天 if(nian%4=0)&nian%100!=0|(nian%400=0)if(ri=30)ri=1;yue+;write_nyr(6,yue);elseif(ri=29)ri=1;yue+;write_nyr(6,yue);/if(yue=2)if(ri=31)ri=1;/yue+yue+;if(yue=13)yue=1;nian+;write_nian();write_nyr(6,yue
16、);break;case 1:/1为大月 if(ri=32)ri=1;yue+;if(yue=13)yue=1;nian+;write_nian();write_nyr(6,yue);break; /if(yue7)temp=yue%2;switch(temp)case 0:/0为大月if(ri=32)ri=1;/yue+yue+;if(yue=13)yue=1;nian+;write_nian();write_nyr(6,yue);break;case 1:/1为小月if(ri=31)ri=1;/yue+yue+;if(yue=13)yue=1;nian+;write_nian();writ
17、e_nyr(6,yue);break;/if(yue7) write_nyr(9,ri); /if(shi=24)if(shuaxin=0)write_sfm(4,shi);/if(fen=60)if(shuaxin=0)write_sfm(7,fen);/if(miao=60)if(shuaxin=0)write_sfm(10,miao); /if(count=20) /while(1)void delay(uint z)int x,y;for(x=110;x0;x-)for(y=z;y0;y-);void write_com(uchar com)/写指令函数 rs=0;lcden=0; P
18、0=com; delay(2); lcden=1; delay(2);lcden=0;void write_date(uchar date)/写数据函数rs=1;lcden=0;P0=date;delay(2);lcden=1;delay(2);lcden=0;void init()uchar num;write_com(0x38);/显示模式设置write_com(0x0c);/光标设置write_com(0x06);/光标指针设置write_com(0x01);/显示清屏write_com(0x80);/从第一行开始写for(num=0;num15;num+)write_date(tabl
19、enum);delay(2);write_com(0x80+0x40);/从第二行开始写for(num=0;num12;num+)write_date(table1num);delay(2);for(num=0;num5;num+)/初始化闹钟存放数组s_cnum=0;f_cnum=0;RCAP2H=(65536-50000)/256;RCAP2L=(65536-50000)%256;/设置自动重装初值T2CON=0x04;/启动定时器EA=1;/总中断 ET2=1;/开定时器中断TH0=(65536-50000)/256;TL0=(65536-50000)%256;TR0=0;ET0=1;v
20、oid write_sfm(uchar add,uchar date)/写时分秒uchar shi,ge;shi=date/10;ge=date%10;write_com(0x80+0x40+add);write_date(0x30+shi);write_date(0x30+ge);void write_nyr(uchar add,uchar date)/写月日uchar shi,ge;shi=date/10;ge=date%10;write_com(0x80+add);write_date(0x30+shi);write_date(0x30+ge);void write_nian()ucha
21、r shi,ge;shi=nian%100/10;ge=nian%10;write_com(0x80+1);write_date(0x30+2);write_date(0x30);write_date(0x30+shi);write_date(0x30+ge); void word(uchar add,unsigned char *str)/写字符串,如MONwhile(*str != 0)write_date(*str+);*str = 0;write_com(0x80+add);void keyscan()if(s1=0)/okdelay(5);if(s1=0)shuaxin=1;s1nu
22、m+;while(!s1);/为假就退出,松手后即为假beep(1);if(csnum=1) csnum=2;if(csnum=0)/刚开始一定要执行的 write_com(0x01);write_com(0x0f);write_com(0x80+4);word(4,a.Time);write_com(0xc0+4);word(0x44,b.Clock);write_com(0x84);/光标停在时间那里csnum=1;flag=1;if(csnum=2)/调时间/*/调时间画面初始化while(setpage=0)flag=0;write_com(0x01);/显示清屏 myupdate()
23、;write_com(0x0f);/光标闪烁 setpage=1;/setpage为1,则不用再次初始化调时画面/while(setpage=0)/*if(s1num=1)/调秒TR2=0;shuaxin=1;write_com(0x80+0x40+10);write_com(0x0f);/光标闪烁if(s1num=2)/调时write_com(0x80+0x40+7);if(s1num=3)/调分write_com(0x80+0x40+4);if(s1num=4)/调星期 write_com(0x80+12);if(s1num=5)/调日 write_com(0x80+9);if(s1num
24、=6)/调月份write_com(0x80+6);if(s1num=7)/调年write_com(0x80+3);if(s1num=8)save();myupdate();TR2=1;s1num=0;csnum=0;/调完会到初始状态setpage=0;flag=0;shuaxin=0;/调完退出时要回到刷新状态 /if(csnum=2)/调时间if(csnum=3)/调闹钟if(setpage=0)uchar i=0;flag=0;write_com(0x80);write_com(0x0c);write_com(0x01);word(0,You Can Set 32);write_com(
25、0xc0);word(0, In One Day);delay(700); /把闹钟存放数组设置一个数,以免write_com(0x01);word(6,Clock 01 00:00);write_com(0x0f);setpage=1;/if(setpage=0)if(s1num=1)/调闹钟数write_com(0x80+6);write_com(0x0f);/光标闪烁if(s1num=2)/调时write_com(0x80+10);if(s1num=3)/调分write_com(0x80+13);if(s1num=4)/全部回到初始状态uchar num;save();myupdate(
26、);s1num=0;csnum=0;/调完会到初始状态setpage=0;flag=0;shuaxin=0;write_com(0x0c);/关闪烁; write_com(0x80);/从第一行开始写for(num=0;num15;num+)write_date(tablenum);delay(2);write_com(0x80+0x40);/从第二行开始写for(num=0;num12;num+)write_date(table1num);delay(2);write_nyr(6,yue);write_nyr(9,ri);write_sfm(4,shi);write_sfm(7,fen);/
27、写回值/if(csnum=3)/调闹钟/if(s1=0)/if(s1=0)OK键处理完毕if(flag=1)/flag为进入设置时间或闹钟画面标志,为1则进入设置if(csnum!=0)if(s2=0)delay(5);if(s2=0)while(!s2);beep(1);csnum=2;/调时间标志s1num=0;write_com(0x84);if(s3=0)delay(5);if(s3=0)while(!s3);beep(1);csnum=3;/调闹钟标志s1num=0;write_com(0xc4);/if(flag=1)if(s1num!=0)/OKNUM=1if(s2=0)dela
28、y(5);/延时,消抖if(s2=0)/确实按下了,再做下面的处理while(!s2); beep(1);if(csnum=2)/shijianif(s1num=1)/miaomiao+;if(miao=60)miao=0;write_sfm(10,miao);write_com(0x80+0x40+10);if(s1num=2)/fenfen+;if(fen=60)fen=0;write_sfm(7,fen);write_com(0x80+0x40+7);if(s1num=3)/shishi+;if(shi=24)shi=0;write_sfm(4,shi);write_com(0x80+0
29、x40+4);if(s1num=4)/xingqixq+;if(xq=8)xq=1;if(xq=1)word(12,Mon);if(xq=2)word(12,Tue);if(xq=3)word(12,Wed);if(xq=4)word(12,Thu);if(xq=5)word(12,Fri);if(xq=6)word(12,Sat);if(xq=7)word(12,Sun);write_com(0x80+12);if(s1num=5)/riri+;if(ri=31)ri=0;write_nyr(9,ri);write_com(0x80+9);if(s1num=6)/yueyue+;if(yue
30、=13)yue=0;write_nyr(6,yue);write_com(0x80+6);if(s1num=7)/niannian+;if(nian=2100)nian=2009;write_nian();write_com(0x80+1); /if(csnum=2)/shijianif(csnum=3)/naozhongif(s1num=1)num_c+;if(num_c=33)num_c=1;write_nyr(6,num_c);write_com(0x80+6);if(s1num=2)shi_c+;if(shi_c=24)shi_c=0;s_cnum_c-1=shi_c;write_nyr(10,shi_c);write_com(0x80+10); if(s1num=3)fen_c+;if(fen_c=60)fen_c=0;f_cnum_c-1=fen_c;write_nyr(13,fen_c);write_com(0x80+13); /if(s2=0) /if(s2=0)if(s3=0)delay(5);if(s3=0)while(!s3);beep(1); if(csnum=2)/shijianif(s1num=1)/miaomiao-;if(miao=-1)miao=5