单片机课程设计实验报告-基于STC89C52RC的电子万年历设计.doc_第1页
单片机课程设计实验报告-基于STC89C52RC的电子万年历设计.doc_第2页
单片机课程设计实验报告-基于STC89C52RC的电子万年历设计.doc_第3页
单片机课程设计实验报告-基于STC89C52RC的电子万年历设计.doc_第4页
单片机课程设计实验报告-基于STC89C52RC的电子万年历设计.doc_第5页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

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

文档简介

单片机实验报告题 目:基于stc89c52rc的电子万年历设计专 业: 通信工程 年 级: 2008级 班 级: 学生姓名: 学 号: 指导老师: 一、 设计任务与要求:利用stc89c52rc单片机设计一个具有如下功能的电子万年历:1、 能够显示年、月、日、时、分、秒、星期。2、 能正确显示闰年日期。3、 可更改年、月、日、时、分、秒、星期。4、 可设定指定日期、时间的闹钟。二、方案设计与论证按照系统设计的要求和功能,将系统分为主控模块、时钟电路模块、按键扫描模块、lcd显示模块、蜂鸣器电路、电源电路、复位电路、晶振电路几个模块,系统框图如图1所示。主控模块采用stc89c52rc单片机,按键模块用5个按键,用于调整时间和设定闹钟,显示模块采用lcd1602,时钟电路模块采用ds1302实时时钟实现对时间,日期的操作。图1基于at89c52rc单片机的电子万年历系统框图三、 硬件单元电路设计与参数计算1、 主控模块我们选用stc89c52rc单片机作为中央处理器,如图2所示。图2stc89c52rc主控模块2、时钟振荡电路时钟振荡电路图3所示,时钟振荡电路用于产生单片机正常工作时所需要的时钟信号,电路由两个30pf的瓷片电容和一个12mhz的晶振组成,并接入到单片机的xtal1和xtal2引脚处,使单片机工作于内部振荡模式。此电路在加电后延迟大约10ms振荡器起振,在xtal2引脚产生幅度为3v左右的正弦波时钟信号,其振荡频率主要由石英晶振的频率决定。图3stc89c52rc时钟振荡电路3、复位电路复位电路由电阻和极性电容组成,如图4所示,通过高电平使单片机复位,在时钟电路开始工作后,当高电平的时间超过大约2us时,即可实现复位。此复位电路同时具备了上电复位和手动复位的功能,上电复位发生在开机加电时,由系统自动完成,手动复位通过一个按键来实现,在程序运行时,若遇到死机,死循环或程序“跑飞”等情况,通过手动复位就可以实现重新启动的操作。手动按钮复位需要人为在复位输入端rst上加入高电平。一般采用的办法是在rst端和正电源vcc之间接一个按钮和一个电阻,如图所示,当人为按下按钮时,则vcc 的+5v电平就会直接加到rst端,由于人的动作再快也会使按钮保持接通达数十毫秒,所以,完全能够满足复位的时间要求。图4stc89c52rc复位电路4、ds1302时钟电路时钟电路主要由时钟芯片ds1302、晶振等几部分组成,ds1302采用3线串行接口,占用引脚少,如图5所示。图5ds1302时钟电路5、按键电路按键电路由5个轻触开关组成,如图6所示。按键用来调整时间和设定闹钟,其一端直接接到单片机的端口,另一端接地,当按下按键时,相应的端口变为低电平,通过检测这一低电平就可以判断是哪个键按下,从而作相应的操作。图6按键电路6、显示电路显示电路采用lcd1602液晶显示,图中只画出了其相应的接口,如图7所示。3脚用于调节lcd1602的背光,4、5、6为lcd1602的控制口,用于控制其写入或是读出指令,7至14脚为lcd1602的数据口,将数传送到lcd1602中。图7lcd1602接口电路7、蜂鸣器电路蜂鸣器电路如图8所示。通过控制三极管的导通和截止来实现蜂鸣器的响与不响。图8蜂鸣器电路四、软件设计与流程图1、程序主流程图主程序首先初始化定时器、lcd1602及ds1302,然后就开始查询按键,有键按下则开始调整时间和设置闹钟,若没有按下,则执行下面的时间、日期及闹钟时间的显示,最后依次循环这些相同的操作,相应流程图如图9所示:开始初始化按键是否按下显示时间、日期及闹钟时间时间、日期、闹钟设定结束是否图9程序主流程图按键的检测主要是通过查询的办法来实现,利用按键进行间调整及闹钟设置,闹钟开关键是开启和关闭闹钟功能;设置1键按下则开始设置时间及日期,同时被选择的时间和日期开始闪烁,第一次按下设置1键时,设置年,第二次按下设置月,后面依次设置日、星期、时、分、秒;闹钟设置键按下则开始设置闹钟时间及日期,同时被选择的时间和日期开始闪烁,第一次按下闹钟设置键时,设置年,第二次按下设置月,后面依次设置日、星期、时、分、秒;若按下下调键是减1操作,按下上调键是加1操作,无论是对时钟和闹钟的年份或月份进行加减,都会使日期归1。五、仿真电路图基于stc89c52rc单片机的电子万年历硬件仿真电路图如图10所示,系统由stc89c52rc单片机、按键扫描电路、显示电路、时钟电路、晶振电路、复位电路、蜂鸣器电路组成。图10 电子万年历仿真图六、结论与心得通过这次课程设计,我对单片机的理论知识有了进一步的掌握,对单片机的原理和实际应用有了更多地理解和掌握。我对单片机的c语言编程有了更深刻的认识和更扎实的掌握,通过不断修改,不断尝试,对源代码各个模块的函数都有了一个非常深入的掌握。在收获知识的同时,还收获了阅历,收获了成熟。在此过程中,不仅培养了独立思考、动手制作的能力,在各种其它能力上也都有了提高。更重要的是,在课程序设计里,我们学会了很多学习的方法。而这是以后最实用的,真的是受益匪浅。要面对社会的挑战,只有不断的学习、实践,再学习、再实践。 七、源程序1、键盘扫描程序头文件keyscan.h:/*-矩阵键盘实验程序通过反转法循环扫描矩阵键盘-*/#include /包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义#define uchar unsigned char#define uint unsigned int /*- 函数声明-*/ uchar keyscan(void);/键盘扫描void delay(uint i); /演示程序/*- 主函数-*/*- 延时程序-*/void delay1(uint i) /延时函数while(i-);/*- 键盘扫描程序-*/uchar keyboard(void) /键盘扫描函数,使用行列反转扫描法 uchar cord_h,cord_l;/行列值中间变量 p1=0x0f; /行线输出全为0 cord_h=p1&0x0f; /读入列线值 if(cord_h!=0x0f) /先检测有无按键按下 delay1(100); /去抖 if(cord_h!=0x0f) cord_h=p1&0x0f; /读入列线值 p1=cord_h|0xf0; /输出当前列线值 cord_l=p1&0xf0; /读入行线值p1=0x0f;delay1(20);while(p1!=0x0f); /return(cord_h+cord_l);/键盘最后组合码值 switch(cord_h+cord_l) /*case 0xee:return(12);break;/0按下相应的键显示相对应的码值case 0xde:return(8);break;/1 按下相应的键显示相对应的码值 case 0xbe:return(4);break;/2case 0x7e:return(0);break;/3case 0xed:return(13);break;/4case 0xdd:return(9);break;/5case 0xbd:return(5);break;/6case 0x7d:return(1);break;/7case 0xeb:return(14);break;/8case 0xdb:return(10);break;/9case 0xbb:return(6);break;/acase 0x7b:return(2);break;/bcase 0xe7:return(15);break;/ccase 0xd7:return(11);break;/dcase 0xb7:return(7);break;/ecase 0x77:return(3);break;/fdefault:return(0xff);break; */case 0xee:return(0);break;/0按下相应的键显示相对应的码值case 0xde:return(1);break;/1 按下相应的键显示相对应的码值 case 0xbe:return(2);break;/2case 0x7e:return(3);break;/3case 0xed:return(4);break;/4case 0xdd:return(5);break;/5case 0xbd:return(6);break;/6case 0x7d:return(7);break;/7case 0xeb:return(8);break;/8case 0xdb:return(9);break;/9case 0xbb:return(10);break;/acase 0x7b:return(11);break;/bcase 0xe7:return(12);break;/ccase 0xd7:return(13);break;/dcase 0xb7:return(14);break;/ecase 0x77:return(15);break;/fdefault:return(0xff);break; return(0xff); /返回该值2、主程序如下:#include#include keyscan.h#define uint unsigned int#define uchar unsigned charuchar a,miao,shi,fen,ri=1,yue=1,nian,week=1,key1n=0,key2n=0,run,runl,bai,mstcnt,miao1=0,shi1=0,fen1=0,ril=1,yuel=1,nianl,weekl=1,wl,rl,yl,nl,w,r,y,n;uint count1=0,count2=0,clk_set=0,clk_switch=0;uchar msb_reload_value=(65536-100)/256,lsb_reload_value=(65536-100)%256;uchar key=0xff;#define yh 0x80+16 /lcd第一行的初始位置,因为lcd1602字符地址首位d7恒定为1(100000000=80)#define er 0x80+0x40+16 /lcd第二行初始位置(因为第二行第一个字符位置地址是0x40)#define yhl 0x80#define er1 0x80+0x40/液晶屏的与c51之间的引脚连接定义(显示数据线接c51的p0口)sbit rs=p20;sbit en=p22;sbit rw=p21; /如果硬件上rw接地,就不用写这句和后面的rw=0了sbit acc0=acc0;sbit acc7=acc7;/*acc累加器=aacc.0=e0h acc.0就是acc的第0位。acc可以位寻址。累加器acc是一个8位的存储单元,是用来放数据的。但是,这个存储单元有其特殊的地位,是单片机中一个非常关键的单元,很多运算都要通过acc来进行。以后在学习指令时,常用a来表示累加器。但有一些地方例外,比如在push指令中,就必须用acc这样的名字。一般的说法,a代表了累加器中的内容、而acc代表的是累加器的地址。 */sbit buzzer=p36;/蜂鸣器,通过三极管9012驱动,端口低电平响/*/uchar code tab0= wang zhe ;uchar code tab1= 0815232021 ;uchar code tab2=20 - - ; /年显示的固定字符uchar code tab3= : : clk:off;/时间显示的固定字符/延时函数,后面经常调用void delay(uint xms)/延时函数,有参函数uint x,y;for(x=xms;x0;x-) for(y=110;y0;y-); void delay2(uint z)/延时uint x,y;for(x=z;x0;x-)for(y=500;y0;y-);/*液晶写入指令函数与写入数据函数,以后可调用*/ write_1602com(uchar com)/*液晶写入指令函数*rs=0;/数据/指令选择置为指令rw=0; /读写选择置为写p0=com;/送入数据delay(1);en=1;/拉高使能端,为制造有效的下降沿做准备delay(1);en=0;/en由高变低,产生下降沿,液晶执行命令write_1602dat(uchar dat)/*液晶写入数据函数*rs=1;/数据/指令选择置为数据rw=0; /读写选择置为写p0=dat;/送入数据delay(1);en=1; /en置高电平,为制造下降沿做准备delay(1);en=0; /en由高变低,产生下降沿,液晶执行命令/*屏幕移动*/void zuoyi(uchar num3) /屏幕左移 uchar l;for(l=0;lnum3;l+)write_1602com(0x18); delay2(5);void youyi(uchar num4)/屏幕右移 uchar r;for(r=0;rnum4;r+)write_1602com(0x1c);delay2(5); lcd_init()/*液晶初始化函数*write_1602com(0x38);/设置液晶工作模式,意思:16*2行显示,5*7点阵,8位数据write_1602com(0x0c);/开显示不显示光标write_1602com(0x06);/整屏不移动,光标自动右移write_1602com(0x01);/清显示 /*/ write_1602com(0x80);for(a=0;a15;a+)write_1602dat(tab0a);write_1602com(0x80+0x40);for(a=0;a15;a+)write_1602dat(tab1a);/*write_1602com(0x80+16);for(a=0;a17;a+) write_1602dat(tab2a);write_1602com(0x80+0x40+16);for(a=0;a15;a+)write_1602dat(tab3a);*/ /*/write_1602com(yh+1);/日历显示固定符号从第一行第1个位置之后开始显示for(a=0;a14;a+)write_1602dat(tab2a);/向液晶屏写日历显示的固定符号部分/delay(3);write_1602com(er);/时间显示固定符号写入位置,从第2个位置后开始显示for(a=0;a=8)week=1; write_1602com(yh+0x0c);/指定加后的周数据显示位置write_week(week);/指定周数据显示内容 write_1602com(yh+0x0e);/因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位break;case 5:shi+;if(shi=24)shi=0;write_sfm(2,shi);/令lcd在正确的位置显示加设定好的小时数据 write_1602com(er-2+3);/因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位break;case 6:fen+;if(fen=60)fen=0;write_sfm(0x05,fen);/令lcd在正确位置显示加设定好的分数据 write_1602com(er-2+6);/因为设置液晶的模式是写入数据后,指针自动加一,在这里是写回原来的位置break;case 7:miao+; if(miao=60)miao=0;/秒超过59,再加1,就归零write_sfm(0x08,miao);/令lcd在正确位置显示加设定好的秒数write_1602com(er-0x02+0x09);/因为设置液晶的模式是写入数据后,指针自动加一,在这里是写回原来的位置 /write_1602com(0x0b);break;/-减键key3,各句功能参照加键注释-if(key=7) buzzer=0;/蜂鸣器短响一次 delay(20); buzzer=1;switch(key1n)case 1:nian-;ri=1;write_nyr(9,ri); if(nian=-1)nian=99;write_nyr(3,nian); write_1602com(yh+4);/因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位break;case 2:yue-;ri=1;write_nyr(9,ri);/令lcd在正确的位置显示加设定好的日期数据if(yue=0)yue=12;write_nyr(6,yue); write_1602com(yh+7);/因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位break;case 3:ri-;run=nian%4; if(run=0) else run=1; switch(yue) case 1 : if(ri=0) ri=31;break;case 2 : if(run=0) if(ri=0) ri=29;break; else if(ri=0) ri=28;break; case 3 : if(ri=0) ri=31;break;case 4 : if(ri=0) ri=30;break;case 5 : if(ri=0) ri=31;break;case 6 : if(ri=0) ri=30;break;case 7 : if(ri=0) ri=31;break;case 8 : if(ri=0) ri=31;break;case 9 : if(ri=0) ri=30;break;case 10: if(ri=0) ri=31;break;case 11:if(ri=0) ri=30;break;case 12:if(ri=0) ri=31;break;default:break;write_nyr(9,ri); write_1602com(yh+10);/因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位break;case 4:week-;if(week=0)week=7; write_1602com(yh+0x0c);/指定加后的周数据显示位置write_week(week);/指定周数据显示内容 write_1602com(yh+0x0e);/因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位break;case 5:shi-; if(shi=-1)shi=23;write_sfm(2,shi); write_1602com(er-2+3);/因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位break;case 6:fen-;if(fen=-1)fen=59;write_sfm(5,fen); write_1602com(er-2+6);/因为设置液晶的模式是写入数据后,指针自动加一,在这里是写回原来的位置break;case 7:miao-;if(miao=-1)miao=59;/秒数据减到-1时自动变成59write_sfm(0x08,miao);/在lcd的正确位置显示改变后新的秒数 write_1602com(er-0x02+0x09);/因为设置液晶的模式是写入数据后,指针自动加一,在这里是写回原来的位置/write_1602com(0x0b);break; if(key1n=0|key1n=8) if(key=5)/-12为功能键(闹钟设置键)- buzzer=0;delay(20);buzzer=1;key2n+;if(key2n=9)key2n=1;/设置按键共有年、月、日、星期、时、分、秒、返回,8个功能循环switch(key2n) case 1: clk_set=1; write_1602com(yh+0x00);write_1602dat(!);write_sfm(8,miao1);/秒,从第二行第8个字后开始显示(调用时分秒显示子函数) write_sfm(5,fen1);/分,从第二行第5个字符后开始显示 write_sfm(2,shi1);/小时,从第二行第2个字符后开始显示write_week(weekl);write_nyr(9,ril); write_nyr(6,yuel); write_nyr(3,nianl);write_1602com(yh+0x04);/按动1次,nianwrite_1602com(0x0f);/设置光标为闪烁 break;case 2: write_1602com(yh+0x07);/按动2次,yue break;case 3: write_1602com(yh+0x0a);/按动3次,ri break;case 4: write_1602com(yh+0x0e);/按动4次,week break;case 5: write_1602com(er-0x02+0x03);/按动5次,shi break;case 6: write_1602com(er-0x02+0x06);/按6次fen位置显示光标 break;case 7: write_1602com(er-0x02+0x09);/按7次,秒位置显示光标 break;case 8:write_1602com(0x0c);/按动到第8次,设置光标不闪烁 write_1602com(yh+0x00);write_1602dat( );clk_set=0;break;default:break; /-闹钟加-/ if(key2n!=0)/当key1按下以下。再按以下键才有效(按键次数不等于零) if(key=3) /上调键 write_1602com(er-0x02+0x09);/因为设置液晶的模式是写入数据后,指针自动加一,在这里是写回原来的位置 switch(key2n)case 1: nianl+;ril=1;write_nyr(9,ril); if(nianl=100)nianl=0;write_nyr(3,nianl);/令lcd在正确的位置显示加设定好的年份数据 write_1602com(yh+4);/因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位break;case 2:yuel+;ril=1;write_nyr(9,ril);/令lcd在正确的位置显示加设定好的日期数据if(yuel=13)yuel=1; write_1602com(yh+7);/因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位write_nyr(6,yuel);/令lcd在正确的位置显示加设定好的月份数据 write_1602com(yh+7);/因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位 break;case 3:ril+; runl=nianl%4; if(runl=0) el

温馨提示

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

评论

0/150

提交评论