欢迎来到三一办公! | 帮助中心 三一办公31ppt.com(应用文档模板下载平台)
三一办公
全部分类
  • 办公文档>
  • PPT模板>
  • 建筑/施工/环境>
  • 毕业设计>
  • 工程图纸>
  • 教育教学>
  • 素材源码>
  • 生活休闲>
  • 临时分类>
  • ImageVerifierCode 换一换
    首页 三一办公 > 资源分类 > DOC文档下载  

    单片机课程设计实验报告基于STC89C52RC的电子万历设计.doc

    • 资源ID:4147593       资源大小:251.50KB        全文页数:31页
    • 资源格式: DOC        下载积分:8金币
    快捷下载 游客一键下载
    会员登录下载
    三方登录下载: 微信开放平台登录 QQ登录  
    下载资源需要8金币
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    单片机课程设计实验报告基于STC89C52RC的电子万历设计.doc

    单片机实验报告题 目:基于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<reg52.h> /包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义#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<reg52.h>#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;x>0;x-) for(y=110;y>0;y-); void delay2(uint z)/延时uint x,y;for(x=z;x>0;x-)for(y=500;y>0;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;l<num3;l+)write_1602com(0x18); delay2(5);void youyi(uchar num4)/屏幕右移 uchar r;for(r=0;r<num4;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;a<15;a+)write_1602dat(tab0a);write_1602com(0x80+0x40);for(a=0;a<15;a+)write_1602dat(tab1a);/*write_1602com(0x80+16);for(a=0;a<17;a+) write_1602dat(tab2a);write_1602com(0x80+0x40+16);for(a=0;a<15;a+)write_1602dat(tab3a);*/ /*/write_1602com(yh+1);/日历显示固定符号从第一行第1个位置之后开始显示for(a=0;a<14;a+)write_1602dat(tab2a);/向液晶屏写日历显示的固定符号部分/delay(3);write_1602com(er);/时间显示固定符号写入位置,从第2个位置后开始显示for(a=0;a<16;a+)write_1602dat(tab3a);/写显示时间固定符号,两个冒号/delay(3); delay2(600); zuoyi(16);/*over*/时分秒显示子函数void write_sfm(uchar add,uchar dat)/向LCD写时分秒,有显示位置加、现示数据,两个参数uchar gw,sw;gw=dat%10;/取得个位数字sw=dat/10;/取得十位数字write_1602com(er+add-2);/er是头文件规定的值0x80+0x40write_1602dat(0x30+sw);/数字+30得到该数字的LCD1602显示码write_1602dat(0x30+gw);/数字+30得到该数字的LCD1602显示码void write_sfm1(uchar add,uchar dat)/向LCD写时分秒,有显示位置加、现示数据,两个参数uchar gw,sw;gw=dat%10;/取得个位数字sw=dat/10;/取得十位数字write_1602com(er1+add);/er是头文件规定的值0x80+0x40write_1602dat(0x30+sw);/数字+30得到该数字的LCD1602显示码write_1602dat(0x30+gw);/数字+30得到该数字的LCD1602显示码/-/年月日显示子函数void write_nyr(int add,int dat)/向LCD写年月日,有显示位置加数、显示数据,两个参数int gw,sw;gw=dat%10;/取得个位数字sw=dat/10;/取得十位数字write_1602com(yh+add);/设定显示位置为第一个位置+addwrite_1602dat(0x30+sw);/数字+30得到该数字的LCD1602显示码write_1602dat(0x30+gw);/数字+30得到该数字的LCD1602显示码void write_nyrl(int add,int dat)/向LCD写年月日,有显示位置加数、显示数据,两个参数int gw,sw;gw=dat%10;/取得个位数字sw=dat/10;/取得十位数字write_1602com(yhl+add);/设定显示位置为第一个位置+addwrite_1602dat(0x30+sw);/数字+30得到该数字的LCD1602显示码write_1602dat(0x30+gw);/数字+30得到该数字的LCD1602显示码/-void write_week(uchar week)/写星期函数write_1602com(yh+0x0c);/星期字符的显示位置switch(week)case 1:write_1602dat('M');/星期数为1时,显示 write_1602dat('O'); write_1602dat('N'); break; case 2:write_1602dat('T');/星期数据为2时显示 write_1602dat('U'); write_1602dat('E'); break;case 3:write_1602dat('W');/星期数据为3时显示 write_1602dat('E'); write_1602dat('D'); break;case 4:write_1602dat('T');/星期数据为4是显示 write_1602dat('H'); write_1602dat('U'); break;case 5:write_1602dat('F');/星期数据为5时显示 write_1602dat('R'); write_1602dat('I'); break;case 6:write_1602dat('S');/星期数据为6时显示 write_1602dat('T'); write_1602dat('A'); break;case 7:write_1602dat('S');/星期数据为7时显示 write_1602dat('U'); write_1602dat('N'); break;/*键盘扫描有关函数*/void key16()key=keyboard();/*闹钟开关显示*/if(key=1)if(clk_switch=0)clk_switch=1; TR0=0; /write_1602com(0x0f);/设置光标为闪烁 write_1602com(er-0x02+0x0f); write_1602dat('O'); write_1602com(er-0x01+0x0f); write_1602dat('N'); write_1602com(er+0x0f); write_1602dat(' '); TR0=1;elseclk_switch=0; TR0=0; /write_1602com(0x0f);/设置光标为闪烁 write_1602com(er-0x02+0x0f); write_1602dat('O'); write_1602com(er-0x01+0x0f); write_1602dat('F'); write_1602com(er+0x0f); write_1602dat('F'); TR0=1; if(key2n=0|key2n=8) if(key=11)/-12为功能键(时间设置键)- buzzer=0;delay(20);buzzer=1;key1n+;if(key1n=9)key1n=1;/设置按键共有年、月、日、星期、时、分、秒、返回,8个功能循环switch(key1n) case 1: TR0=0;/关闭定时器 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次,设置光标不闪烁TR0=1;break;/打开定时器default:break; if(key1n!=0)/当key1按下以下。再按以下键才有效(按键次数不等于零) if(key=3) /上调键write_1602com(er-0x02+0x09);/因为设置液晶的模式是写入数据后,指针自动加一,在这里是写回原来的位置 buzzer=0;/蜂鸣器短响一次 delay(20); buzzer=1; switch(key1n)case 1:nian+;ri=1;write_nyr(9,ri); if(nian=100)nian=0;write_nyr(3,nian);/令LCD在正确的位置显示"加"设定好的年份数据 write_1602com(yh+4);/因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位break;case 2:yue+;ri=1;write_nyr(9,ri);/令LCD在正确的位置显示"加"设定好的日期数据if(yue=13)yue=1; write_1602com(yh+7);/因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位write_nyr(6,yue);/令LCD在正确的位置显示"加"设定好的月份数据 write_1602com(yh+7);/因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位break;case 3:ri+; run=nian%4; if(run=0) else run=1; switch(yue) case 1 : if(ri=32) ri=1;break;case 2 : if(run=0) if(ri=30) ri=1;break; else if(ri=29) ri=1;break; case 3 : if(ri=32) ri=1;break;case 4 : if(ri=31) ri=1;break;case 5 : if(ri=32) ri=1;break;case 6 : if(ri=31) ri=1;break;case 7 : if(ri=32) ri=1;break;case 8 : if(ri=32) ri=1;break;case 9 : if(ri=31) ri=1;break;case 10: if(ri=32) ri=1;break;case 11:if(ri=31) ri=1;break;case 12:if(ri=32) ri=1;break;default:break;write_nyr(9,ri);/令LCD在正确的位置显示"加"设定好的日期数据 write_1602com(yh+10);/因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位break;case 4:week+;if(week>=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(ru

    注意事项

    本文(单片机课程设计实验报告基于STC89C52RC的电子万历设计.doc)为本站会员(laozhun)主动上传,三一办公仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一办公(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    备案号:宁ICP备20000045号-2

    经营许可证:宁B2-20210002

    宁公网安备 64010402000987号

    三一办公
    收起
    展开