|
最近在學(xué)習(xí)單片機(jī),把自己的資料分享給有需要的童鞋。
源碼:(部分預(yù)覽 完整代碼請(qǐng)下載附件):
計(jì)算器設(shè)計(jì).7z
(384.54 KB, 下載次數(shù): 410)
2021-1-4 01:03 上傳
點(diǎn)擊文件名下載附件
- #include<reg52.h>
- #include<math.h>
- #include "lcd1602_8.h"
- uint temp,num;//鍵盤(pán)掃描數(shù)值
- uchar keynum1=0,keynum2=0,sign=0,i=0,j=0; //按鍵計(jì)數(shù),符號(hào)標(biāo)示
- uchar num1[8]={0},num2[8]={0}; //按鍵存儲(chǔ)數(shù)組
- float ans1=0,ans2=0,ans=0,point=0; //運(yùn)算數(shù)據(jù)
- bit conflag=0; //繼續(xù)運(yùn)算標(biāo)志位
- bit newcalc=0; //新運(yùn)算標(biāo)志
- bit ac=0; //清零標(biāo)志,1為清零
- bit beepflag=0; //蜂鳴器標(biāo)志位
- bit sqrtflag1=0; //開(kāi)方1標(biāo)志位
- bit sqrtflag2=0; //開(kāi)方2標(biāo)志位
- bit powflag=0;
- sbit keybeep=P3^3;//蜂鳴器開(kāi)關(guān)按鍵
- sbit beep=P2^3; //蜂鳴器控制口
- sbit keysqrt=P3^4;//開(kāi)方按鍵
- sbit keypow=P3^5;//任意次方按鍵
- uchar keyscan();
- void maininit(void);
- /****主程序***/
- void main(void)
- {
- maininit();//初始化
- while(1) //整個(gè)系統(tǒng)大循環(huán),讓計(jì)算器一直處于工作狀態(tài)
- {
- while(1) //第一運(yùn)算數(shù)掃描
- {
- if(ac==1)
- break; //若清零,則退出輸入
- if((keyscan()!='N')&&((num>=0&&num<=9)||num=='.')) //記錄按下的數(shù)字
- {
- if(newcalc==1) //新一次運(yùn)算開(kāi)始
- {
- lcdwrite_com(0x01);//清屏
- newcalc=0;
- lcd_setxy(0,0);
- }
- if(keynum1<=7) //限制輸入位數(shù)
- {
- if(num=='.')
- {
- lcdwrite_data('.'); //顯示小數(shù)點(diǎn)
- }
- else
- lcdwrite_num1(num);
- num1[keynum1]=num;
- keynum1++;
- }
- }
- else if(num=='+'||num=='-'||num=='*'||num=='/'||num=='='||num=='^'||keysqrt==0)
- {
- if(keynum1==0&&num1[0]==0) //若直接輸入運(yùn)算符而沒(méi)有輸入數(shù)字則執(zhí)行連續(xù)運(yùn)算
- {
- 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++) //計(jì)算按下的數(shù)字的大小
- {
- 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; //清除開(kāi)方標(biāo)志
- sqrtflag2=0;//清除開(kāi)方標(biāo)志
- if(keysqrt==0) //計(jì)算開(kāi)方
- {
- delayms(5);
- if(keysqrt==0)
- {
- if(beepflag==1) //若開(kāi)聲音則每一次按鍵均鳴叫
- {
- 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; //記住運(yùn)算符號(hào)
- lcdwrite_data(num);
- break; //輸入運(yùn)算符號(hào)則退出第一運(yùn)算數(shù)的輸入
- }
- }
- while(1)
- {
- if(ac==1)
- break; //若清零,則退出輸入
- if(sqrtflag1==1) //若第一次按鍵為開(kāi)方,則直接顯示結(jié)果
- {
- break;
- }
- if((keyscan()!='N')&&((num>=0&&num<=9)||num=='.')) //記錄按下的數(shù)字
- {
- if(keynum2<=7)
- {
- if(num=='.')
- {
- lcdwrite_data('.'); //顯示小數(shù)點(diǎn)
- }
- else
- lcdwrite_num1(num);
- num2[keynum2]=num;
- keynum2++;
- }
- }
- else if(num=='='||keysqrt==0)
- {
- sqrtflag2=0;//清除開(kāi)方標(biāo)志
- if(keysqrt==0) //進(jìn)入開(kāi)方
- {
- delayms(5);
- if(keysqrt==0)
- {
- sqrtflag2=1; //開(kāi)方標(biāo)志
- lcdwrite_data(0xe8); //寫(xiě)開(kāi)方符號(hào)
- if(beepflag==1) //若開(kāi)聲音則每一次按鍵均鳴叫
- {
- beep=0;
- delayms(100);
- beep=1;
- }
- while(keysqrt==0);
- delayms(10);
- while(keysqrt==0);
- }
- }
- point=0;
- for(i=0;keynum2>0;i++) //計(jì)算按下的數(shù)字的大小
- {
- 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; //輸入等于號(hào)則退出第二運(yùn)算數(shù)的輸入
- }
- else if(num=='+'||num=='-'||num=='*'||num=='/'||num=='^')
- {
- point=0;
- for(i=0;keynum2>0;i++) //計(jì)算按下的數(shù)字的大小
- {
- 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; //進(jìn)行連續(xù)計(jì)算
- }
- }
- if(ac==1)
- {
- ac=0;
- continue; //清零后進(jìn)行下一次運(yùn)算
- }
- if(sign=='+') //計(jì)算結(jié)果
- ans=ans1+ans2;
- if(sign=='-')
- ans=ans1-ans2;
- if(sign=='*')
- ans=ans1*ans2;
- if(sign=='/')
- ans=ans1/ans2;
- if(sign=='^') //計(jì)算多次方
- ans=pow(ans1,ans2);
- if(sqrtflag2==1) //計(jì)算開(kāi)方
- ans=sqrt(ans1);
- lcd_setxy(1,0);
- if((ans2==0&&sign=='/')||(ans1<0&&sqrtflag2==1))
- lcdwrite_string("math error");//ans2=0或被開(kāi)方數(shù)小于0時(shí)提示錯(cuò)誤
- else lcdwrite_float(ans); //顯示結(jié)果
- sqrtflag1=0,newcalc=1; //為新的一次運(yùn)算準(zhǔn)備
- 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; //跳轉(zhuǎn)到連續(xù)運(yùn)算
- }
- }
- }
- /*****初始化程序*****/
- void maininit(void)
- {
- delayms(100); //等待液晶初始化
- lcd_init();
- lcd_setxy(0,0);
- lcdwrite_data('0');
- lcd_setxy(0,0);
- IT0=1;//下降沿觸發(fā)
- EX0=1;//開(kāi)外部中斷0
- IT1=1;//下降沿觸發(fā)
- EX1=1;//開(kāi)外部中斷1
- EA=1; //開(kāi)中斷
- }
- /***清零中斷程序******/
- void EX0_int() interrupt 0
- {
- if(beepflag==1) //若開(kāi)聲音則每一次按鍵均鳴叫
- {
- beep=0;
- delayms(500);
- beep=1;
- }
- lcdwrite_com(0x01); //顯示清屏
- lcd_setxy(0,0);
- lcdwrite_data('0');
- lcd_setxy(0,0);
- num='N'; //數(shù)字初始化
- 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) //若開(kāi)聲音則每一次按鍵均鳴叫
- {
- beep=0;
- delayms(500);
- beep=1;
- }
- }
- /*****鍵盤(pán)掃描程序*****/
- uchar keyscan()
- {
- num='N'; //若沒(méi)有按下任何按鍵,則返回'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') //若開(kāi)聲音則每一次按鍵均鳴叫
- {
- beep=0;
- delayms(100);
- beep=1;
- }
- return num;
- }
復(fù)制代碼
|
評(píng)分
-
查看全部評(píng)分
|