lcd多功能计算器报告_第1页
lcd多功能计算器报告_第2页
lcd多功能计算器报告_第3页
lcd多功能计算器报告_第4页
lcd多功能计算器报告_第5页
已阅读5页,还剩39页未读 继续免费阅读

下载本文档

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

文档简介

1、: 规定类 自选类西南交通大学电气工程学院实验竞赛月活动Lcd多功能计算器作品报告作品名称: lcd多功能计算器 队员姓名: 常彦强 张盼 专 业: 电气工程及其自动化 指导老师: 无 作品完成起止时间: 2012-4-10到2012-5-3 报告完成时间: 2012-5-3 一、 功能介绍:Lcd1602多功能计算器可以实现的功能大体上可以分为计算和计时两个方面,具体如下所述:² 计时方面l 利用时钟芯片准确计时并显示年、月、日、时、分、秒、周;l 时间显示采用12小时制并具体有AM和PM提示功能;l 可以使用4*4矩阵键盘快捷的单独更改任意时分秒年月日时分秒周;l 可以使用4*4

2、矩阵键盘快捷设置闹铃并且利用蜂鸣器实现到点提示功能;l 具有整点提示功能;l 时间为个位数时,十位数字不显示,例如显示8而不是08;² 计算器方面l 具有进入计算器程序提示功能;l 可以实现八位数之内且小数点后不超过两位的加、减、乘、除计算;l 可以实现排列、组合、x的y次方、阶乘计算;l 具有错误提示功能;l 可以在任意时刻清零;并且以上两大功能可以任意转换。 二、功能流程图:三、作品图片四、protues仿真展示:l 原理图l 设置时间模式l 闹铃设置模式l 小数计算l 除计算l 阶乘计算l x的y次方计算l 组合计算l 排列计算五、制作流程我们最初想实现计算器功能,经过紧张艰难

3、的制作我们可以实现了一些计算器的基本功能,之后感觉单片机引脚还有很多空余,会造成很大的资源浪费,于是利用ds1302时钟芯片实现了数字钟的功能。六、心得体会:通过此次的制作充分让我感受到了实践是根本的道理,在此次作品制作过程中我学会了很多单片机编程的许多技巧和一些主要模块的应用,并且学会了PCB板的绘制与制作,虽然布局不太合理,但是从中积攒到了很多经验,相信在下一次的电子设计过程中可以做得更好。从前听同学说,把简单的事做到最好就是完美,现在深刻体会到了这一句话,在焊电路板时,出现了一个虚焊点,结果导致lcd1602只能显示最初时间,但是时间并不走动,经过我们的判断和大量的检测,才发现是ds13

4、02的晶振的一个引脚没有焊好,之后焊好后作品一切运行正常。在编写程序的时候我们总是用protues检测程序的正确性,但是有的时候仿真和检测相差很多,尤其是按键的消抖,在仿真上是不存在这种情况的,而在作品上这个问题却不得忽视。总之,在这一次的电子设计当中学到了很多知识,同时自己付出了很多精力,让我更加相信付出总会有回报。附:程序#include "reg52.h"#include<intrins.h>#define uint unsigned int #defineuchar unsigned char sbit sck=P16;/ds1302sbit io=P1

5、7; /ds1302sbit rst=P15; /ds1302sbit s1=P10; /调时开关, 进入调时程序sbit s2=P11;/进入计算器程序sbit s3=P14; /定时sbit FM=P13;sbit dula=P26; /段选sbit lcden=P21;sbit lcdrs=P20;sbit wela=P27; /位选sbit s4=P22;sbit s5=P23;sbit s6=P24;sbit s7=P25;uchar key,keyout,keyout2,i=0,a=1,b=0,fuhao,w,z=0,g,o,value,s1num,c,c1,j,clk=0,p,q

6、;signed long jg,m,n;uchar code tab1=" Welcome to use" /开始数组uchar code tab2=" caculater!" /说明数组uchar code tab3=" ERR0R"uchar code tab4="SA"uchar code tab5="TC"uchar code tab6=" It is time!"uchar code tab7="AMPM"uchar code table=&qu

7、ot;.789/456*123-c0=+AC!"uchar code tab="0123456789"uchar s8;uchar dingshi7=0,0,0,0,0,0,0;uchar time_data=11,7,3,15,23,59,50; /11年6周3月15日11时35分55秒 7个数uchar linshi7;uchar write_add=0x8c,0x8a,0x88,0x86,0x84,0x82,0x80;/时间写操作的地址 7个数第二个数是周uchar read_add=0x8d,0x8b,0x89,0x87,0x85,0x83,0x81; /

8、时间读操作地址 7个数uchar diap13;uchar code xianshi="0123456789-: "/*键盘扫描子函数*/uchar keyscan();/*延时子函数*/void delay(uint z);/*lcd1602*/void write_com(uchar com);void write_data(uchar date);void init();/*ds1302*/void write_ds1302_byte(uchar dat);void write_ds1302(uchar add,uchar dat);uchar read_ds1302

9、(uchar add);void set_rtc();void read_rtc();/*计算器部分*/void welcome();void getm();void shusign();void getn();void jisuan();void getshu();void jisuanqi();void intocacu();void out();/*时钟部分*/void disp();void display();void s1jiance();void tiaoyue();void tiaoshi();void tiaoyue2();void s3jiance();void clock

10、();void shijiandao();/*键盘扫描子函数*/uchar keyscan() keyout=0;keyout2=0;P3=0xfe;/11111110,检测P10口key=P3; /这里有可能有键盘按下key=key&0xf0;/提取高四位while(key!=0xf0)/有键盘按下delay(5); /延迟5ms,消除抖动P3=0xfe; /重新赋值key=P3;key=key&0xf0;while(key!=0xf0) /真的有键盘按下switch(key)case 0xe0:keyout=1;keyout2=7; /11100000break;case

11、0xd0:keyout=2;keyout2=8; /11010000break;case 0xb0:keyout=3;keyout2=9; /10110000break;case 0x70:keyout=4; /01110000break;while(key!=0xf0) /松手检测P3=0xfe;key=P3;key=key&0xf0;delay(5);P3=0xfd;key=P3;key=key&0xf0;while(key!=0xf0)delay(5);P3=0xfd;key=P3;key=key&0xf0;while(key!=0xf0)switch(key)c

12、ase 0xe0:keyout=5;keyout2=4;break;case 0xd0:keyout=6;keyout2=5;break;case 0xb0:keyout=7;keyout2=6;break;case 0x70:keyout=8;break;while(key!=0xf0)P3=0xfd;key=P3;key=key&0xf0; delay(5);P3=0xfb;key=P3;key=key&0xf0;while(key!=0xf0)delay(5);P3=0xfb;key=P3;key=key&0xf0;while(key!=0xf0)switch(k

13、ey)case 0xe0:keyout=9;keyout2=1;break;case 0xd0:keyout=10;keyout2=2;break;case 0xb0:keyout=11;keyout2=3;break;case 0x70:keyout=12;break;while(key!=0xf0)P3=0xfb;key=P3;key=key&0xf0;delay(5);P3=0xf7;key=P3;key=key&0xf0;while(key!=0xf0)delay(5);P3=0xf7;key=P3;key=key&0xf0;while(key!=0xf0)sw

14、itch(key)case 0xd0:keyout=14;keyout2=0;break;case 0xb0:keyout=15; break;case 0x70:keyout=16;break;case 0xe0:keyout=13;while(key!=0xf0)P3=0xf7;key=P3;key=key&0xf0;delay(5);if(s4=0)delay(20);if(s4=0)delay(800);if(s4=0)while(!s4);keyout=18;elsekeyout=17; if(s5=0)delay(20);if(s5=0)delay(800);if(s5=0

15、)while(!s5);keyout=19;elsekeyout=20; if(s6=0)/小数点delay(20);if(s6=0)while(!s6);keyout=21;if(s7=0)delay(20);if(s7=0)delay(800);if(s7=0)while(!s7);keyout=22;elsekeyout=23; return keyout,keyout2;/*延时子函数*OKKKKKKKKK*/void delay(uint z) uint x,y;for(x=z;x>0;x-)for(y=110;y>0;y-);/*以下是lcd1602系列子函数*/*写指

16、令子函数*OKKKKKKKK*/void write_com(uchar com) lcdrs=0; /写指令选择P0=com;delay(5); /延迟5mslcden=1; /高脉冲delay(5);/高脉冲延迟lcden=0; /高脉冲结束/*写数据子函数*OKKKKKKKKK*/void write_data(uchar date) lcdrs=1; /写命令选择P0=date;delay(5); /延迟5mslcden=1; /高脉冲delay(5);/高脉冲延迟lcden=0; /高脉冲结束*/*初始化子函数*OKKKKKKKKKKK*/void init() dula=0;wel

17、a=0;lcden=1; /允许write_com(0x38);/显示模式设置write_com(0x0e);/开显示,显示光标,光标闪烁write_com(0x06);/ 光标加1,指针加一,不左移动write_com(0x80);/这里控制数据在哪里显示/*以上是lcd1602器件使用子函数*/*以下是ds1302器件使用子函数*/*向ds1302中写单字节*okkkkkkk*/void write_ds1302_byte(uchar dat) /向ds1302中写单字节uchar i; /局部变量for(i=0;i<8;i+)sck=0; /时钟为0io=dat&0x01;

18、 /数据从最低为开始传输dat=dat>>1; /数据右移一位sck=1; /一个高脉冲,数据被传输进去/*向ds1302中写数据或者地址*okkkkkkkkkk*/void write_ds1302(uchar add,uchar dat) /向ds1302中写数据或者地址rst=0;_nop_(); /复位键为0sck=0;_nop_();/时钟为0rst=1;_nop_();/复位键为1write_ds1302_byte(add);/向ds1302中写入地址write_ds1302_byte(dat);/向ds1302中写入数据rst=0;_nop_();io=1;_nop_

19、();/*读取ds1302中某地址的的数据*okkkkkkkkkkk*/uchar read_ds1302(uchar add) /读取ds1302中某地址的的数据uchar i;rst=0;_nop_();sck=0;_nop_();rst=1;_nop_();write_ds1302_byte(add); /先写入地址for(i=0;i<8;i+) value=value>>1;sck=0;if(io)value=value|0x80;sck=1;rst=0; _nop_();sck=0;_nop_();sck=1;_nop_();return value; /value

20、是从ds1302中读出来的数据/*写入初始值*okkkkkkkk*/void set_rtc() /写入初始值,这里的初始值为十进制uchar i,j;for(i=0;i<7;i+) /把要输进去的年周月日时分秒转化为8421bcd码进制,因为ds1302储存的是8421bcd码 j=time_datai/10; /十位 例如35 3*16+5=53(十进制)转化为二进制位110101,使用8421bcd码即是35time_datai=time_datai%10;time_datai=time_datai+j*16;/这里转化为538421bcd码为110101读出来为35write_d

21、s1302(0x8e,0x00); /去除写保护for(i=0;i<7;i+) /这里写入的为8421bcd码write_ds1302(write_addi,time_datai); /把年周月日时分输进去write_ds1302(0x8e,0x80); /加上写保护/*读取初始值*okkkkkkk*/void read_rtc() /uchar i;for(i=0;i<7;i+)time_datai=read_ds1302(read_addi);/依次读出ds1302各个存储器上的数据(8421bcd码)并储存在time_datai中/这时time_data中的数为8421bcd

22、码/*以上是ds1302器件使用子函数*/*以下是计算器部分子函数*/*计算器*welcome*/void welcome() for(g=0;g<=14;g+) /i从0变到14 write_data(tab1g); /刚进入说明welcome to use! delay(5);/延时 write_com(0x80+0x40); /从第二行开始显示for(g=0;g<=12;g+) write_data(tab2g); /刚进入说明 make by JunRu! delay(5);/延时 delay(900); / 延时300uswrite_com(0x01); /显示一段时间后

23、清屏/*计算器*得到数第一个数m*/void getm()if(keyout!=0&&keyout!=13&&keyout!=15&&keyout!=4&&keyout!=8&&keyout!=12&&keyout!=16&&keyout!=17&&keyout!=18&&keyout!=19&&keyout!=20&&keyout!=22&&keyout!=23&&keyout!=24)

24、 /有输入的数且输入的数不是清零不是等于if(keyout=21)write_com(0x80+i);write_data(table0);i+;p=1;elsewrite_com(0x80+i); /不等于无意义、清零、等于、加减乘除write_data(tablekeyout);a+;i+;if(a=1) /把输入的第一个数值取出来m=keyout2;elsem=m*10+keyout2;delay(1000);/*计算器*输出加减乘除*/void shusign()switch(keyout)case 4:write_com(0x80+i);i+;write_data(table4);b

25、reak;case 8:write_com(0x80+i);i+;write_data(table8);break;case 12:write_com(0x80+i);i+; write_data(table12);break;case 16:write_com(0x80+i);i+;write_data(table16);break;case 17:write_com(0x80+i);i+;write_data(table17);break;case 18:write_com(0x80+i);i+;write_data(table18);break;case 19:write_com(0x8

26、0+i);i+;write_data(0x5e);break;case 20:write_com(0x80+i);i+;write_data(table19);break;/*计算器*得到数第2个数n并输出*/void getn()if(keyout!=0&&keyout!=13&&keyout!=15&&keyout!=4&&keyout!=8&&keyout!=12&&keyout!=16&&keyout!=17&&keyout!=18&&keyo

27、ut!=19&&keyout!=20&&keyout!=22&&keyout!=23&&keyout!=24)if(keyout=21)write_com(0x80+i);write_data(table0);i+;p=1;elsewrite_com(0x80+i); /不等于无意义、清零、等于、加减乘除write_data(tablekeyout);b+;i+;if(b=1) /把输入进去的值取出来n=keyout2;elsen=n*10+keyout2;/*计算器计算*计算器计算子函数*/void jisuan()uchar

28、x=1,y=1,g;switch(fuhao)case 16:jg=m+n;if(p=1)q=2;break;case 12:jg=m-n;if(p=1)q=2;break;case 8:jg=m*n;if(p=1)q=4;break;case 4:m=m*100;jg=m/n;q=2;break;case 17:for(y=n;y>0;y-)x=x*m;m-; jg=x;q=0;break;case 18:for(g=n;g>0;g-)x=x*m;m-;for(g=n;g>0;g-)y=y*n;n-;jg=x/y;q=0;break;case 19:y=m;for(g=n;

29、g>0;g-)x=x*y; jg=x;q=0;break;case 20:y=m;for(g=m;g>0;g-)x=x*y;y-; jg=x;q=0;break;/*取结果各位数子函数*OKKKK*/void getshu() if(jg>=0&&jg<10)s0=jg;w=0; /一位数if(jg>=10&&jg<99) /两位数s0=jg/10;s1=jg%10;w=1;if(jg>=100&&jg<999) /三位数s0=jg/100;s1=jg/10%10;s2=jg%10;w=2;if(j

30、g>=1000&&jg<9999) /四位数s0=jg/1000;s1=jg/100%10;s2=jg/10%10;s3=jg%10;w=3;if(jg>=10000&&jg<99999) /五位数s0=jg/10000;s1=jg/1000%10;s2=jg/100%10;s3=jg/10%10;s4=jg%10;w=4;if(jg>=100000&&jg<999999) /六位数s0=jg/100000;s1=jg/10000%10;s2=jg/1000%10;s3=jg/100%10;s4=jg/10%1

31、0;s5=jg%10;w=5;if(jg>=1000000&&jg<9999999)/七位数s0=jg/1000000;s1=jg/100000%10;s2=jg/10000%10;s3=jg/1000%10;s4=jg/100%10;s5=jg/10%10;s6=jg%10;w=6;if(jg>=10000000&&jg<99999999) /八位数s0=jg/10000000;s1=jg/1000000%10;s2=jg/100000%10;s3=jg/10000%10;s4=jg/1000%10;s5=jg/100%10;s6=jg

32、/10%10;s7=jg%10;w=7;/*计算器整体*计算器整体子函数*/void jisuanqi()w=8;init();welcome(); /刚进入时的显示内容start1:while(j)keyscan();getm();if(keyout=13)i=0;z=0;w=8;write_com(0x01);keyout=0;a=0;b=0;continue;out();/ 不等于无意义、清零、等于、加减乘除,从键盘得到第一个数mwhile(keyout=4|keyout=8|keyout=12|keyout=16|keyout=17|keyout=18|keyout=19|keyout

33、=20|keyout=22|keyout=23|keyout=24)/输入加减乘除之后 fuhao=keyout;shusign();while(1) /输入加减乘除keyscan();getn();/不等于无意义、清零、等于、加减乘除的情况下/*主函数*如果按键是等于*/if(keyout=15) /等于号jisuan();getshu();/取出结果的各位上的数字if(fuhao=4&&n=0)write_com(0x01);init(); for(o=0;o<=8;o+)write_data(tab3o);w=8;delay(100); while(w>=0&

34、amp;&w<8)write_com(0x80+0x4f-z);write_data(tabsw);delay(20);w-;z+;if(z=q)write_com(0x80+0x4f-z);write_data(table0);z+; if(z<q)for(z;z<=q+1;z+)if(z=q)write_com(0x80+0x4f-z);write_data(table0); elsewrite_com(0x80+0x4f-z);write_data(tab0);w=8;jg=0;q=0;if(keyout=13)i=0;z=0;w=8;write_com(0x0

35、1);keyout=0;a=0;b=0;goto start1;if(s2=0)delay(20);if(s2=0)while(!s2);j=0;i=0;z=0;w=8;write_com(0x01);keyout=0;a=0;b=0;break;/如果按键是等于 if(keyout=15) /输入加减乘除之后运算/输入加减乘除/刚开始按键/*进入计算器程序*/void intocacu() j=1;if(s2=0)delay(20);/*?()()()()()()*/if(s2=0)while(!s2); /松手检测write_com(0x01);jisuanqi();/*/void out

36、()if(s2=0)delay(20);/*?()()()()()()*/if(s2=0)while(!s2);j=0;i=0;z=0;w=8;write_com(0x01);keyout=0;a=0;b=0;/break;/*以上是计算器部分子函数*/*以下是时钟部分子函数*/*时钟部分*对读出来的数据进行处理*/void disp()uchar g,r;diap0=time_data6%16; /秒的个位 53=3*16+5 ,这里边分别读出了3和5diap1=time_data6/16; /秒的十位diap2=time_data5%16; /分的个位diap3=time_data5/16

37、; /分的时位if(diap0=6&&diap1=5&&diap2=9&&diap3=5) FM=0; delay(770); FM=1;diap4=time_data4%16; /时的个位diap5=time_data4/16; /时的十位 if(diap5*10+diap4>12)r=diap5*10+diap4-12;diap5=r/10;diap4=r%10;write_com(0x80+0x40);for(g=2;g<4;g+)write_data(tab7g);elsewrite_com(0x80+0x40);for(g=

38、0;g<2;g+)write_data(tab7g);diap6=time_data3%16; /日的个位diap7=time_data3/16; /日的十位diap8=time_data2%16; /月的个位diap9=time_data2/16; /月的十位diap10=time_data1%16; /周的个位diap11=time_data0%16; /年的个位diap12=time_data0/16; /年的十位/*时钟部分*显示子函数*/void display()write_com(0x80+2);write_data(xianshidiap12); /年十位write_data(xianshidiap11); /年个位write_data(xianshi10); write_data(xianshidiap9);/月十位 write_data(xianshidiap8);/月个位write_data(xianshi10);write_data(xianshidiap7);/日十位write_data(xianshidiap6);/日个位write_com(0x80+0x0d);write_data(xianshidiap10);/周位write_com(0xc0+4);if(diap5=0)write_dat

温馨提示

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

评论

0/150

提交评论