




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
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
提交評論