|
最近在學習單片機,把自己的資料分享給有需要的童鞋。
捕獲.PNG (98 KB, 下載次數: 169)
下載附件
2016-4-28 10:36 上傳
51hei.png (20 KB, 下載次數: 50)
下載附件
2021-1-4 01:03 上傳
源碼:(部分預覽 完整代碼請下載附件):
計算器設計.7z
(384.54 KB, 下載次數: 410)
2021-1-4 01:03 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
- #include<reg52.h>
- #include<math.h>
- #include "lcd1602_8.h"
- uint temp,num;//鍵盤掃描數值
- uchar keynum1=0,keynum2=0,sign=0,i=0,j=0; //按鍵計數,符號標示
- uchar num1[8]={0},num2[8]={0}; //按鍵存儲數組
- float ans1=0,ans2=0,ans=0,point=0; //運算數據
- bit conflag=0; //繼續運算標志位
- bit newcalc=0; //新運算標志
- bit ac=0; //清零標志,1為清零
- bit beepflag=0; //蜂鳴器標志位
- bit sqrtflag1=0; //開方1標志位
- bit sqrtflag2=0; //開方2標志位
- bit powflag=0;
- sbit keybeep=P3^3;//蜂鳴器開關按鍵
- sbit beep=P2^3; //蜂鳴器控制口
- sbit keysqrt=P3^4;//開方按鍵
- sbit keypow=P3^5;//任意次方按鍵
- uchar keyscan();
- void maininit(void);
- /****主程序***/
- void main(void)
- {
- maininit();//初始化
- while(1) //整個系統大循環,讓計算器一直處于工作狀態
- {
- while(1) //第一運算數掃描
- {
- if(ac==1)
- break; //若清零,則退出輸入
- if((keyscan()!='N')&&((num>=0&&num<=9)||num=='.')) //記錄按下的數字
- {
- if(newcalc==1) //新一次運算開始
- {
- lcdwrite_com(0x01);//清屏
- newcalc=0;
- lcd_setxy(0,0);
- }
- if(keynum1<=7) //限制輸入位數
- {
- if(num=='.')
- {
- lcdwrite_data('.'); //顯示小數點
- }
- else
- lcdwrite_num1(num);
- num1[keynum1]=num;
- keynum1++;
- }
- }
- else if(num=='+'||num=='-'||num=='*'||num=='/'||num=='='||num=='^'||keysqrt==0)
- {
- if(keynum1==0&&num1[0]==0) //若直接輸入運算符而沒有輸入數字則執行連續運算
- {
- here: ans1=ans;
- sign=num;
- lcdwrite_com(0x01);
- delayms(5);
- lcd_setxy(0,0);
- lcdwrite_float(ans1);
- if(sqrtflag2!=1&&num!='N')
- lcdwrite_data(num);
- break;
- }
- for(i=0;keynum1>0;i++) //計算按下的數字的大小
- {
- if(num1[i]!='.')
- ans1=ans1*10+num1[i];
- else if(num1[i]=='.')
- break;
- keynum1--;
- }
- for(keynum1--,i++,j=0;keynum1>0;j++,i++,keynum1--)
- point=point*10+num1[i];
- for(;j>0;j--)
- point*=0.1;
- ans1=ans1+point;
- sqrtflag1=0; //清除開方標志
- sqrtflag2=0;//清除開方標志
- if(keysqrt==0) //計算開方
- {
- delayms(5);
- if(keysqrt==0)
- {
- if(beepflag==1) //若開聲音則每一次按鍵均鳴叫
- {
- beep=0;
- delayms(100);
- beep=1;
- }
- ans=sqrt(ans1);
- sqrtflag1=1;
- lcdwrite_data(0xe8);
- while(keysqrt==0);
- delayms(10);
- while(keysqrt==0);
- break;
- }
- }
- sign=num; //記住運算符號
- lcdwrite_data(num);
- break; //輸入運算符號則退出第一運算數的輸入
- }
- }
- while(1)
- {
- if(ac==1)
- break; //若清零,則退出輸入
- if(sqrtflag1==1) //若第一次按鍵為開方,則直接顯示結果
- {
- break;
- }
- if((keyscan()!='N')&&((num>=0&&num<=9)||num=='.')) //記錄按下的數字
- {
- if(keynum2<=7)
- {
- if(num=='.')
- {
- lcdwrite_data('.'); //顯示小數點
- }
- else
- lcdwrite_num1(num);
- num2[keynum2]=num;
- keynum2++;
- }
- }
- else if(num=='='||keysqrt==0)
- {
- sqrtflag2=0;//清除開方標志
- if(keysqrt==0) //進入開方
- {
- delayms(5);
- if(keysqrt==0)
- {
- sqrtflag2=1; //開方標志
- lcdwrite_data(0xe8); //寫開方符號
- if(beepflag==1) //若開聲音則每一次按鍵均鳴叫
- {
- beep=0;
- delayms(100);
- beep=1;
- }
- while(keysqrt==0);
- delayms(10);
- while(keysqrt==0);
- }
- }
- point=0;
- for(i=0;keynum2>0;i++) //計算按下的數字的大小
- {
- if(num2[i]!='.')
- ans2=ans2*10+num2[i];
- else if(num2[i]=='.')
- break;
- keynum2--;
- }
- for(keynum2--,i++,j=0;keynum2>0;j++,i++,keynum2--)
- point=point*10+num2[i];
- for(;j>0;j--)
- point*=0.1;
- if(sqrtflag2!=1)
- lcdwrite_data(num);
- ans2=ans2+point;
- break; //輸入等于號則退出第二運算數的輸入
- }
- else if(num=='+'||num=='-'||num=='*'||num=='/'||num=='^')
- {
- point=0;
- for(i=0;keynum2>0;i++) //計算按下的數字的大小
- {
- if(num2[i]!='.')
- ans2=ans2*10+num2[i];
- else if(num2[i]=='.')
- break;
- keynum2--;
- }
- for(keynum2--,i++,j=0;keynum2>0;j++,i++,keynum2--)
- point=point*10+num2[i];
- for(;j>0;j--)
- point*=0.1;
- lcdwrite_data(num);
- ans2=ans2+point;
- conflag=1;
- break; //進行連續計算
- }
- }
- if(ac==1)
- {
- ac=0;
- continue; //清零后進行下一次運算
- }
- if(sign=='+') //計算結果
- ans=ans1+ans2;
- if(sign=='-')
- ans=ans1-ans2;
- if(sign=='*')
- ans=ans1*ans2;
- if(sign=='/')
- ans=ans1/ans2;
- if(sign=='^') //計算多次方
- ans=pow(ans1,ans2);
- if(sqrtflag2==1) //計算開方
- ans=sqrt(ans1);
- lcd_setxy(1,0);
- if((ans2==0&&sign=='/')||(ans1<0&&sqrtflag2==1))
- lcdwrite_string("math error");//ans2=0或被開方數小于0時提示錯誤
- else lcdwrite_float(ans); //顯示結果
- sqrtflag1=0,newcalc=1; //為新的一次運算準備
- ans1=0;
- ans2=0;
- for(i=0;i<8;i++) //清除按鍵緩存
- num1[i]=0;
- for(i=0;i<8;i++)
- num2[i]=0;
- if(conflag==1)
- {
- conflag=0;
- goto here; //跳轉到連續運算
- }
- }
- }
- /*****初始化程序*****/
- void maininit(void)
- {
- delayms(100); //等待液晶初始化
- lcd_init();
- lcd_setxy(0,0);
- lcdwrite_data('0');
- lcd_setxy(0,0);
- IT0=1;//下降沿觸發
- EX0=1;//開外部中斷0
- IT1=1;//下降沿觸發
- EX1=1;//開外部中斷1
- EA=1; //開中斷
- }
- /***清零中斷程序******/
- void EX0_int() interrupt 0
- {
- if(beepflag==1) //若開聲音則每一次按鍵均鳴叫
- {
- beep=0;
- delayms(500);
- beep=1;
- }
- lcdwrite_com(0x01); //顯示清屏
- lcd_setxy(0,0);
- lcdwrite_data('0');
- lcd_setxy(0,0);
- num='N'; //數字初始化
- keynum1=0,keynum2=0,sign=0;
- ans1=0,ans2=0,ans=0,point=0;
- conflag=0,newcalc=0;
- ac=1;
- }
- /***聲音中斷程序******/
- void EX1_int() interrupt 2
- {
- beepflag=~beepflag;
- if(beepflag==1) //若開聲音則每一次按鍵均鳴叫
- {
- beep=0;
- delayms(500);
- beep=1;
- }
- }
- /*****鍵盤掃描程序*****/
- uchar keyscan()
- {
- num='N'; //若沒有按下任何按鍵,則返回'N'
- P1=0xfe; //掃描第一行
- temp=P1;
- temp=temp&0xf0;
- while(temp!=0xf0) //掃描列
- {
- delayms(10);
- temp=P1;
- temp=temp&0xf0;
- while(temp!=0xf0)
- {
- temp=P1;
- switch(temp)
- {
- case 0xee:num=7;
- break;
- case 0xde:num=8;
- break;
- case 0xbe:num=9;
- break;
- case 0x7e:num='/';
- break;
- }
- while(temp!=0xf0) //等待松手
- {
- temp=P1;
- temp=temp&0xf0;
- }
- }
- }
- P1=0xfd; //掃描第二行
- temp=P1;
- temp=temp&0xf0;
- while(temp!=0xf0) //掃描列
- {
- delayms(10);
- temp=P1;
- temp=temp&0xf0;
- while(temp!=0xf0)
- {
- temp=P1;
- switch(temp)
- {
- case 0xed:num=4;
- break;
- case 0xdd:num=5;
- break;
- case 0xbd:num=6;
- break;
- case 0x7d:num='*';
- break;
- }
- while(temp!=0xf0)
- {
- temp=P1;
- temp=temp&0xf0; //等待松手
- }
- }
- }
- P1=0xfb; //掃描第三行
- temp=P1;
- temp=temp&0xf0;
- while(temp!=0xf0) //掃描列
- {
- delayms(10);
- temp=P1;
- temp=temp&0xf0;
- while(temp!=0xf0)
- {
- temp=P1;
- switch(temp)
- {
- case 0xeb:num=1;
- break;
- case 0xdb:num=2;
- break;
- case 0xbb:num=3;
- break;
- case 0x7b:num='-';
- break;
- }
- while(temp!=0xf0) //等待松手
- {
- temp=P1;
- temp=temp&0xf0;
- }
- }
- }
- P1=0xf7; //掃描第四行
- temp=P1;
- temp=temp&0xf0;
- while(temp!=0xf0) //掃描列
- {
- delayms(10);
- temp=P1;
- temp=temp&0xf0;
- while(temp!=0xf0)
- {
- temp=P1;
- switch(temp)
- {
- case 0xe7:num=0;
- break;
- case 0xd7:num='.';
- break;
- case 0xb7:num='=';
- break;
- case 0x77:num='+';
- break;
- }
- while(temp!=0xf0)
- {
- temp=P1;
- temp=temp&0xf0; //等待松手
- }
- }
- }
- if(keypow==0)
- {
- delayms(5);
- if(keypow==0)
- {
- powflag=1;
- num='^';
- }
- while(keypow==0); //掃描多次方按鍵
- delayms(5);
- while(keypow==0);
- }
- if(beepflag==1&&num!='N') //若開聲音則每一次按鍵均鳴叫
- {
- beep=0;
- delayms(100);
- beep=1;
- }
- return num;
- }
復制代碼
|
評分
-
查看全部評分
|