|
利用STC89C52RC單片機(jī),LCD屏,薄膜式矩陣鍵盤,制作的計(jì)算器,可以連續(xù)計(jì)算,等號(hào)左邊的式子在第一行,等號(hào)右邊結(jié)果在第二行,清楚明了。
IMG_20170828_201502_HDR.jpg (1.35 MB, 下載次數(shù): 84)
下載附件
2017-11-22 00:06 上傳
單片機(jī)源程序如下:
- #include <reg51.h>
- #include <math.h>
- #include <lcd.h>
- #define GPIO_KEY P1//薄膜按鍵所用I/O口,P1^0~P1^7
- unsigned char KeyValue=13;//矩陣鍵盤按鍵默認(rèn)值
- unsigned int error=0;//非法運(yùn)算標(biāo)志
- unsigned int bei=0;//標(biāo)志變量,若被加(減、乘、除)數(shù)未輸入,則bei為0
- unsigned char x=0;//儲(chǔ)存運(yùn)算符
- unsigned int xf=0;//標(biāo)志變量,若運(yùn)算符剛被輸入,則置為1
- unsigned char dan;//儲(chǔ)存剛輸入的單個(gè)數(shù)位上的字符型數(shù)字
- unsigned int y=0;//標(biāo)志變量,若要輸出運(yùn)算結(jié)果則置為1
- unsigned char e[9]=" Error!!!";
- void LcdDisplay_1(long number);//用于在第一行輸出被加減乘除數(shù)
- void LcdDisplay_2(long number);//用于在第二行輸出結(jié)果
- void Delay_ms(unsigned int ms);
- //void UsartConfiguration();
- void main()
- {
- // UsartConfiguration();
- LcdInit(); //初始化LCD1602
- while(1)
- {
- static long key=0,result=0,temp=0,a=0,b=0,c=0,d=0;//設(shè)置靜態(tài)局部變量,可保留上一次運(yùn)算的值
- unsigned char i=0;
- GPIO_KEY=0x0f;
- if(GPIO_KEY!=0x0f)//讀取按鍵是否按下
- {
- Delay_ms(10);//延時(shí)消抖
- if(GPIO_KEY!=0x0f)//再次檢測鍵盤是否按下
- {
- //測試列
- GPIO_KEY=0X0f;
- switch(GPIO_KEY)
- {
- case(0X07): KeyValue=0;break;
- case(0X0b): KeyValue=1;break;
- case(0X0d): KeyValue=2;break;
- case(0X0e): KeyValue=3;break;
- }
- //測試行
- GPIO_KEY=0Xf0;
- switch(GPIO_KEY)
- {
- case(0X70): KeyValue=KeyValue+0;break;
- case(0Xb0): KeyValue=KeyValue+4;break;
- case(0Xd0): KeyValue=KeyValue+8;break;
- case(0Xe0): KeyValue=KeyValue+12;break;
- }
- while((i<60)&&(GPIO_KEY!=0xf0)) //松手檢測
- {
- Delay_ms(10);
- i++;
- }
- switch (KeyValue)
- {
- //key計(jì)算最新鍵入的值,用temp存放被加(減、乘、除)數(shù),result存放最新鍵入的值或計(jì)算結(jié)果
- case 0:dan='1';key=key*10+1;result=key;break;//鍵入1,dan儲(chǔ)存剛輸入的單個(gè)數(shù)位上的數(shù)字
- case 1:dan='2';key=key*10+2;result=key;break;//鍵入2
- case 2:dan='3';key=key*10+3;result=key;break;//鍵入3
- case 3:x='+';xf=1;temp=result;key=0;a=1;break; //選擇加法,x儲(chǔ)存選擇的運(yùn)算符,選擇后xf置為1
- case 4:dan='4';key=key*10+4;result=key;break;//鍵入4
- case 5:dan='5';key=key*10+5;result=key;break;//鍵入5
- case 6:dan='6';key=key*10+6;result=key;break;//鍵入6
- case 7:x='-';xf=1;temp=result;key=0;b=1;break; //選擇減法,
- case 8:dan='7';key=key*10+7;result=key;break;//鍵入7
- case 9:dan='8';key=key*10+8;result=key;break;//鍵入8
- case 10:dan='9';key=key*10+9;result=key;break;//鍵入9
- case 11:x='*';xf=1;temp=result;key=0;c=1;break; //選擇乘法
- case 12:temp=key=result=0;a=b=c=d=0;x=dan=0;xf=y=bei=0;break;//所有清零
- case 13:dan='0';key=key*10+0;result=key;break;//鍵入0
- case 14:if(a==1) {result=temp+result;a=0;key=0;} //計(jì)算運(yùn)算結(jié)果
- if(b==1) {result=temp-result;b=0;key=0;}
- if(c==1) {result=temp*result;c=0;key=0;}
- if(d==1)
- {
- if (result==0) //若除數(shù)為0,運(yùn)算非法,error置為1
- {error=1;result=0;d=0;key=0;}
- else
- {result=temp/result;d=0;key=0;}
- }
- y=1; //將要輸出運(yùn)算結(jié)果,則y置為1
- break;
- case 15:x='/';xf=1;temp=result;key=0;d=1;break; //選擇除法
- }
- //LCD顯示
- if (y==0)//若y為0,則不是輸出結(jié)果,而是輸出等式的左邊
- {
- if (KeyValue==12) LcdWriteCom(0x01);//清零則清屏
- else if(x==0&&bei==0) bei=1,LcdWriteCom(0x01),LcdWriteData(dan);//若x和bei都為0,則當(dāng)前正開始輸入被加(減、乘、除)數(shù),要清屏再輸出,同時(shí)bei置為1
- else if(x==0&&bei==1) LcdWriteData(dan);//若x為0,bei為1,則運(yùn)算符未選擇,即當(dāng)前仍然在輸入被加(減、乘、除)數(shù),繼續(xù)逐位輸出顯示
- else if(x!=0&&xf==1) xf=0,bei=0,LcdWriteCom(0x01),LcdDisplay_1(result),LcdWriteData(x);//若x和xf都不為0,則為剛選擇運(yùn)算符,將運(yùn)算符輸出且xf重新置為0,此時(shí)被加(減、乘、除)數(shù)已輸完,bei也要重新置為0
- else if(x!=0&&xf==0) LcdWriteData(dan);//若運(yùn)算符已選但不是剛選,則當(dāng)前正輸入加(減、乘、除)數(shù),逐位輸出顯示
- }
- else //否則輸出結(jié)果
- {
- LcdDisplay_2(result); //輸出結(jié)果
- x=0; //運(yùn)算符已選,重新置為0
- y=0; //輸出結(jié)果后,重新置為0
- }
- }
- }
- }
- }
- void LcdDisplay_1(long number)//在第一行輸出被加(減、乘、除)數(shù)
- {
- int i,n[5]={0}; //不能設(shè)成unsigned
- if (number<0)
- LcdWriteData('-');
- number=abs(number); //取絕對值
- if (number-10000>=0) i=5; //判斷有效位數(shù)
- else if (number-1000>=0) i=4;
- else if (number-100>=0) i=3;
- else if (number-10>=0) i=2;
- else i=1;
- n[4]=number/ 10000; //提取各位上的數(shù)
- n[3]=number % 10000 / 1000;
- n[2]=number % 1000 / 100;
- n[1]=number % 100 / 10;
- n[0]=number % 10;
- for (i=i-1;i>=0;i--) //若設(shè)成unsigned,此處形成死循環(huán)。!
- {
- LcdWriteData(n[i]+48);//輸出
- }
- }
- void LcdDisplay_2(long number)//在第二行輸出結(jié)果
- {
- int i,n[5]; //不能設(shè)成unsigned
- //判斷運(yùn)算是否合法
- if (error==1) //若error為1,則運(yùn)算非法
- {
- error=0; //error重新置為0
- LcdWriteCom(0x01); //清屏
- LcdWriteCom(0x80); //數(shù)據(jù)指針返回首位
- for (i=0;i<9;i++) //輸出提示
- LcdWriteData(e[i]);
- Delay_ms(1500);
- LcdWriteCom(0x01); //再次清屏
- }
- else //合法則輸出結(jié)果
- {
- LcdWriteData('='); //先在第一行輸出'='
- LcdWriteCom(0xc0); //數(shù)據(jù)指針設(shè)置在第二行首位
- if (number<0) //負(fù)數(shù)則輸出負(fù)號(hào)
- LcdWriteData('-');
- number=abs(number);
- if (number-10000>=0) i=5; //判斷有效位數(shù)
- else if (number-1000>=0) i=4;
- else if (number-100>=0) i=3;
- else if (number-10>=0) i=2;
- else i=1;
- n[4]=number/10000;
- n[3]=number%10000/1000;
- n[2]=number%1000/100;
- n[1]=number%100/10;
- n[0]=number%10;
- for (i=i-1;i>=0;i--) //若設(shè)成unsigned,此處形成死循環(huán)!!!
- {
- LcdWriteData(n[i]+48);
- }
- }
- /*
- SBUF = '0'+m; //將接收到的數(shù)據(jù)放入到發(fā)送寄存器
- while (!TI); //等待發(fā)送數(shù)據(jù)完成
- TI = 0; //發(fā)送完成標(biāo)志位清零
- */
- }
- void Delay_ms(unsigned int ms)//延時(shí)函數(shù),延時(shí)1ms
- {
- int j;
- for(;ms>0;ms--)
- for(j=140;j>0;j--);
- }
- /* //此函數(shù)適合數(shù)碼管顯示時(shí)使用
- unsigned int num(long num,unsigned int p)//提取各位上的數(shù)
- {
- unsigned int i,t,n;
- for(t=1,i=0;i<p;i++)
- {
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復(fù)制代碼
0.png (10.79 KB, 下載次數(shù): 95)
下載附件
2017-11-22 02:55 上傳
所有資料51hei提供下載:
Lcd計(jì)算器(Lcd適應(yīng)版,薄膜鍵盤).zip
(48.97 KB, 下載次數(shù): 166)
2017-11-22 00:01 上傳
點(diǎn)擊文件名下載附件
51單片機(jī),keil4編譯 下載積分: 黑幣 -5
|
評(píng)分
-
查看全部評(píng)分
|