找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 7681|回復(fù): 4
打印 上一主題 下一主題
收起左側(cè)

Lcd1602計(jì)算器設(shè)計(jì)(薄膜鍵盤,連續(xù)計(jì)算)附單片機(jī)源碼

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:243507 發(fā)表于 2017-11-22 00:10 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
利用STC89C52RC單片機(jī),LCD屏,薄膜式矩陣鍵盤,制作的計(jì)算器,可以連續(xù)計(jì)算,等號(hào)左邊的式子在第一行,等號(hào)右邊結(jié)果在第二行,清楚明了。


單片機(jī)源程序如下:
  1. #include <reg51.h>
  2. #include <math.h>
  3. #include <lcd.h>

  4. #define GPIO_KEY P1//薄膜按鍵所用I/O口,P1^0~P1^7

  5. unsigned char KeyValue=13;//矩陣鍵盤按鍵默認(rèn)值
  6. unsigned int error=0;//非法運(yùn)算標(biāo)志
  7. unsigned int bei=0;//標(biāo)志變量,若被加(減、乘、除)數(shù)未輸入,則bei為0
  8. unsigned char x=0;//儲(chǔ)存運(yùn)算符
  9. unsigned int xf=0;//標(biāo)志變量,若運(yùn)算符剛被輸入,則置為1
  10. unsigned char dan;//儲(chǔ)存剛輸入的單個(gè)數(shù)位上的字符型數(shù)字
  11. unsigned int y=0;//標(biāo)志變量,若要輸出運(yùn)算結(jié)果則置為1
  12. unsigned char e[9]=" Error!!!";

  13. void LcdDisplay_1(long number);//用于在第一行輸出被加減乘除數(shù)
  14. void LcdDisplay_2(long number);//用于在第二行輸出結(jié)果
  15. void Delay_ms(unsigned int ms);
  16. //void UsartConfiguration();

  17. void main()
  18. {
  19. //        UsartConfiguration();
  20.         LcdInit();                         //初始化LCD1602
  21.         while(1)
  22.            {
  23.             static long key=0,result=0,temp=0,a=0,b=0,c=0,d=0;//設(shè)置靜態(tài)局部變量,可保留上一次運(yùn)算的值
  24.             unsigned char i=0;

  25.             GPIO_KEY=0x0f;
  26.             if(GPIO_KEY!=0x0f)//讀取按鍵是否按下
  27.                 {
  28.                         Delay_ms(10);//延時(shí)消抖
  29.                         if(GPIO_KEY!=0x0f)//再次檢測鍵盤是否按下
  30.                         {                       
  31.                                 //測試列
  32.                                 GPIO_KEY=0X0f;
  33.                                 switch(GPIO_KEY)
  34.                                 {
  35.                                         case(0X07):        KeyValue=0;break;
  36.                                         case(0X0b):        KeyValue=1;break;
  37.                                         case(0X0d): KeyValue=2;break;
  38.                                         case(0X0e):        KeyValue=3;break;
  39.                                 }
  40.                                 //測試行
  41.                                 GPIO_KEY=0Xf0;
  42.                                 switch(GPIO_KEY)
  43.                                 {
  44.                                         case(0X70):        KeyValue=KeyValue+0;break;
  45.                                         case(0Xb0):        KeyValue=KeyValue+4;break;
  46.                                         case(0Xd0): KeyValue=KeyValue+8;break;
  47.                                         case(0Xe0):        KeyValue=KeyValue+12;break;
  48.                                 }
  49.                                 while((i<60)&&(GPIO_KEY!=0xf0))         //松手檢測
  50.                                 {
  51.                                         Delay_ms(10);
  52.                                         i++;
  53.                                 }

  54.                                 switch (KeyValue)
  55.                                 {
  56.                                         //key計(jì)算最新鍵入的值,用temp存放被加(減、乘、除)數(shù),result存放最新鍵入的值或計(jì)算結(jié)果
  57.                                         case  0:dan='1';key=key*10+1;result=key;break;//鍵入1,dan儲(chǔ)存剛輸入的單個(gè)數(shù)位上的數(shù)字
  58.                                            case  1:dan='2';key=key*10+2;result=key;break;//鍵入2
  59.                                          case  2:dan='3';key=key*10+3;result=key;break;//鍵入3
  60.                                         case  3:x='+';xf=1;temp=result;key=0;a=1;break;      //選擇加法,x儲(chǔ)存選擇的運(yùn)算符,選擇后xf置為1
  61.                                         case  4:dan='4';key=key*10+4;result=key;break;//鍵入4
  62.                                          case  5:dan='5';key=key*10+5;result=key;break;//鍵入5
  63.                                         case  6:dan='6';key=key*10+6;result=key;break;//鍵入6
  64.                                         case  7:x='-';xf=1;temp=result;key=0;b=1;break;          //選擇減法,
  65.                                         case  8:dan='7';key=key*10+7;result=key;break;//鍵入7
  66.                                         case  9:dan='8';key=key*10+8;result=key;break;//鍵入8
  67.                                         case 10:dan='9';key=key*10+9;result=key;break;//鍵入9
  68.                                         case 11:x='*';xf=1;temp=result;key=0;c=1;break;          //選擇乘法
  69.                                         case 12:temp=key=result=0;a=b=c=d=0;x=dan=0;xf=y=bei=0;break;//所有清零
  70.                                         case 13:dan='0';key=key*10+0;result=key;break;//鍵入0
  71.                                         case 14:if(a==1) {result=temp+result;a=0;key=0;}          //計(jì)算運(yùn)算結(jié)果
  72.                                                         if(b==1) {result=temp-result;b=0;key=0;}
  73.                                                         if(c==1) {result=temp*result;c=0;key=0;}
  74.                                                         if(d==1)
  75.                                                         {
  76.                                                                 if (result==0)         //若除數(shù)為0,運(yùn)算非法,error置為1
  77.                                                                         {error=1;result=0;d=0;key=0;}
  78.                                                                 else
  79.                                                                         {result=temp/result;d=0;key=0;}                               
  80.                                                         }
  81.                                                         y=1;                                //將要輸出運(yùn)算結(jié)果,則y置為1
  82.                                                         break;
  83.                                         case 15:x='/';xf=1;temp=result;key=0;d=1;break;           //選擇除法
  84.                                 }

  85.                                 //LCD顯示
  86.                                  if (y==0)//若y為0,則不是輸出結(jié)果,而是輸出等式的左邊       
  87.                                 {
  88.                                         if (KeyValue==12) LcdWriteCom(0x01);//清零則清屏
  89.                                         else if(x==0&&bei==0) bei=1,LcdWriteCom(0x01),LcdWriteData(dan);//若x和bei都為0,則當(dāng)前正開始輸入被加(減、乘、除)數(shù),要清屏再輸出,同時(shí)bei置為1
  90.                                          else if(x==0&&bei==1) LcdWriteData(dan);//若x為0,bei為1,則運(yùn)算符未選擇,即當(dāng)前仍然在輸入被加(減、乘、除)數(shù),繼續(xù)逐位輸出顯示
  91.                                         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
  92.                                         else if(x!=0&&xf==0) LcdWriteData(dan);//若運(yùn)算符已選但不是剛選,則當(dāng)前正輸入加(減、乘、除)數(shù),逐位輸出顯示
  93.                                 }
  94.                                 else         //否則輸出結(jié)果
  95.                                 {
  96.                                         LcdDisplay_2(result);        //輸出結(jié)果
  97.                                         x=0;                                        //運(yùn)算符已選,重新置為0
  98.                                         y=0;                                        //輸出結(jié)果后,重新置為0
  99.                                 }       
  100.                         }
  101.                 }
  102.         }
  103. }

  104. void LcdDisplay_1(long number)//在第一行輸出被加(減、乘、除)數(shù)
  105. {
  106.         int i,n[5]={0};                          //不能設(shè)成unsigned
  107.         if (number<0)
  108.                 LcdWriteData('-');
  109.         number=abs(number);                  //取絕對值
  110.         if (number-10000>=0) i=5; //判斷有效位數(shù)
  111.         else if (number-1000>=0) i=4;
  112.         else if (number-100>=0) i=3;
  113.         else if (number-10>=0) i=2;
  114.         else i=1;                       
  115.         n[4]=number/ 10000;                  //提取各位上的數(shù)
  116.         n[3]=number % 10000 / 1000;
  117.         n[2]=number % 1000 / 100;
  118.         n[1]=number % 100 / 10;
  119.         n[0]=number % 10;
  120.         for (i=i-1;i>=0;i--)          //若設(shè)成unsigned,此處形成死循環(huán)。!
  121.         {
  122.                 LcdWriteData(n[i]+48);//輸出
  123.         }
  124. }

  125. void LcdDisplay_2(long number)//在第二行輸出結(jié)果
  126. {
  127.         int i,n[5];                                //不能設(shè)成unsigned
  128.         //判斷運(yùn)算是否合法
  129.         if (error==1)                        //若error為1,則運(yùn)算非法
  130.         {
  131.                 error=0;                        //error重新置為0
  132.                 LcdWriteCom(0x01);  //清屏
  133.                 LcdWriteCom(0x80);  //數(shù)據(jù)指針返回首位
  134.                 for (i=0;i<9;i++)        //輸出提示
  135.                         LcdWriteData(e[i]);
  136.                 Delay_ms(1500);
  137.                 LcdWriteCom(0x01);  //再次清屏
  138.         }
  139.         else                                        //合法則輸出結(jié)果
  140.         {
  141.                  LcdWriteData('=');        //先在第一行輸出'='
  142.                  LcdWriteCom(0xc0);        //數(shù)據(jù)指針設(shè)置在第二行首位
  143.                  if (number<0)                //負(fù)數(shù)則輸出負(fù)號(hào)
  144.                          LcdWriteData('-');
  145.                  number=abs(number);
  146.                  if (number-10000>=0) i=5; //判斷有效位數(shù)
  147.                  else if (number-1000>=0) i=4;
  148.                  else if (number-100>=0) i=3;
  149.                  else if (number-10>=0) i=2;
  150.                  else i=1;                       
  151.                  n[4]=number/10000;
  152.                  n[3]=number%10000/1000;
  153.                  n[2]=number%1000/100;
  154.                  n[1]=number%100/10;
  155.                  n[0]=number%10;
  156.                  for (i=i-1;i>=0;i--)           //若設(shè)成unsigned,此處形成死循環(huán)!!!
  157.                  {
  158.                         LcdWriteData(n[i]+48);
  159.                  }
  160.         }
  161. /*
  162.         SBUF = '0'+m;        //將接收到的數(shù)據(jù)放入到發(fā)送寄存器
  163.         while (!TI);        //等待發(fā)送數(shù)據(jù)完成
  164.         TI = 0;                        //發(fā)送完成標(biāo)志位清零
  165. */
  166. }

  167. void Delay_ms(unsigned int ms)//延時(shí)函數(shù),延時(shí)1ms
  168. {
  169.         int j;
  170.         for(;ms>0;ms--)
  171.           for(j=140;j>0;j--);
  172. }

  173. /*        //此函數(shù)適合數(shù)碼管顯示時(shí)使用
  174. unsigned int num(long num,unsigned int p)//提取各位上的數(shù)
  175. {
  176.     unsigned int i,t,n;
  177.     for(t=1,i=0;i<p;i++)
  178.         {
  179. ……………………

  180. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復(fù)制代碼


所有資料51hei提供下載:
Lcd計(jì)算器(Lcd適應(yīng)版,薄膜鍵盤).zip (48.97 KB, 下載次數(shù): 166)



評(píng)分

參與人數(shù) 2黑幣 +59 收起 理由
陽光的360zz + 9 很給力!成功試驗(yàn)
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏3 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:425307 發(fā)表于 2018-11-12 21:38 | 只看該作者
正好需要 謝謝樓主開源
回復(fù)

使用道具 舉報(bào)

板凳
ID:594206 發(fā)表于 2019-8-2 16:40 | 只看該作者
正好需要 謝謝
回復(fù)

使用道具 舉報(bào)

地板
ID:633321 發(fā)表于 2019-12-5 15:15 | 只看該作者
很受用,感謝
回復(fù)

使用道具 舉報(bào)

5#
ID:787061 發(fā)表于 2020-6-22 22:42 | 只看該作者
很好 還不錯(cuò)
回復(fù)

使用道具 舉報(bào)

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表