久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4183|回復: 3
打印 上一主題 下一主題
收起左側

51單片機制作的多位連續四則運算的計算器 Proteus仿真程序

[復制鏈接]
跳轉到指定樓層
樓主
     基于單片機制作的多位連續四則運算的計算器

仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)

單片機源程序如下:
  1. #include<reg52.h>//52單片機頭文件
  2. #include<math.h>//要用到數學計算公式,所以調用
  3. #include <intrins.h>//移位
  4. #define key P2    //定義矩陣鍵盤的I/O口
  5. #define GPIO_LCD P0//定義LCD1602  數據/命令的輸入端
  6. unsigned char number[20];//用來儲存我們所按鍵按下去的字符和數字
  7. unsigned char add=0;//是否按過+號
  8. unsigned char subtract=0;//是否按過-號
  9. unsigned char ride=0;//是否按過*號
  10. unsigned char divide=0;//是否按過/號
  11. unsigned char eliminate=0;//是否按過清除鍵
  12. unsigned char minus=0;//是否計算的數據需要添加負號
  13. unsigned char decimals=0;//是否計算的數據需要小數點
  14. unsigned char equal=0;//是否按下等號鍵
  15. sbit LCD_RS =P3^4;//定義LCD的模式選擇,1為寫數據,0為寫命令
  16. sbit LCD_RW =P3^5;//定義LCD功能  1是讀,0是寫
  17. sbit LCD_E =P3^6;//定義LCD使能端
  18. unsigned long a=0,b=0;//用于儲存我們所要運算的數據
  19. unsigned char i;//定義一個全局變量
  20. unsigned char LCD_Wait(void)//判忙函數
  21. {
  22.               LCD_RS=0;
  23.               LCD_RW=1;
  24.               _nop_();
  25.               LCD_E=1;
  26.               _nop_();
  27.             
  28.               LCD_E=0;
  29.               return               GPIO_LCD;                           
  30. }

  31. void delay(void)   //延時函數
  32. {
  33.     unsigned char x,z;
  34.     for(z=19;z>0;z--)
  35.         for(x=130;x>0;x--);
  36. }



  37. void LCD_Write_Com(unsigned char com)//LCD1602寫命令函數
  38. {
  39. LCD_RS =0;
  40. LCD_RW =0;
  41. GPIO_LCD=com;
  42. delay() ;
  43. LCD_E=1;
  44. delay() ;
  45. LCD_E=0;
  46. delay() ;
  47. }
  48. void LCD_Write_Date( unsigned char input)//LCD1602寫數據函數
  49. {
  50.               LCD_RS=1;
  51.               LCD_RW=0;              ;
  52.               LCD_E=0;
  53. _nop_();
  54.               GPIO_LCD =input;            
  55.               _nop_();
  56.               LCD_E=1;            
  57. _nop_();
  58.               LCD_E=0;                                          
  59. _nop_();
  60.               LCD_Wait();
  61. }
  62. void LCD_Initial()//LCD1602初始化函數
  63. {
  64. delay();
  65. LCD_Write_Com (0x38);
  66. delay() ;        
  67. LCD_Write_Com (0x38);
  68. delay() ;
  69. LCD_Write_Com (0x08);
  70. delay() ;
  71. LCD_Write_Com (0x0c);
  72. delay() ;  
  73. LCD_Write_Com (0x06);
  74. delay() ;
  75. LCD_Write_Com (0x01);
  76. delay() ;
  77. }
  78. 以上函數是LCD1602的模塊化函數庫,如果看不懂,需要先學習一下LCD1602.如果懶得學的話,可以直接用這個函數庫,前提是上面定義的變量要整體一一對應,各個端口的引腳也要和你的實際端口一一對應
  79. unsigned long calculate()//計算數據模塊
  80. {
  81.    unsigned long value=0;
  82.                
  83.                            
  84.                                           if(add)//如果我們按鍵按下了加號,那么在計算時進入這個加運算
  85.                                           {
  86.                                                         value=a+b;
  87.                                           }
  88.                                           if(subtract) //如果我們按鍵按下了減號,那么在計算時進入這個減運算
  89.                                           {
  90.                                                 if(a>=b)
  91.                                                                                                   value=a-b;
  92.                                                                                     else
  93.                                                                                     {
  94.                                                                                         value=b-a;
  95.                                                                                                   minus=1;//說明后面的數大于前面的額數,將其標志為一,在輸出結果是,可以利用它判斷是否輸出負號
  96.                                                                                     }
  97.                                                                       }
  98.                                           if(ride)//乘法運算
  99.                                           {
  100.                                           value=a*b;
  101.                                           }
  102.                                           if(divide)//除法運算
  103.                                           {
  104.                                           value=(unsigned long)(((float)a/b)*1000);//因為此計算器是,保留小數點后三位,所以,兩數相除,1/2=0.5,那么通過這個,可以讓其先等于200,方便我們后續的結果處理
  105.                                                         decimals=1;//標示結果已經<0,最后結果要出現小數點,
  106.                                           }
  107.                                          
  108.                                           return value;//返回計算的結果
  109.                                           }
  110.                            
  111.                            
  112.             
  113. void result()
  114.               {
  115.               unsigned char f=0;//標志結果需要保留什么數
  116.                             unsigned long value;
  117.                            
  118.                             if(equal==1)
  119.                             {
  120.                                           value=calculate();//將上面計算算出來的值賦值給這個函數中的value
  121.                                           LCD_Write_Com (0x40);//寫LCD1602的命令,使得結果數據顯示在第二排
  122.                                           delay();
  123.                   LCD_Write_Com (0xcf); //從第二排最后一個位置依次向左寫數據
  124.                                           delay();
  125.                                           LCD_Write_Com (0x04);//光標從第二排最后一個數據向左移動
  126.                                           delay();
  127.       do
  128.       {
  129.                                          
  130.                                                         LCD_Write_Date(0x30+value%10);//0x30是LCD字符庫中數字0的代號,例如我們想寫入 2這個結果,根據前面計算函數,計算函數已經將2變成2000,所以這里是讓其變回來從后往前依次寫數據到LCD1602上,
  131.                                                         delay();
  132.                                                         f++;//value的位數如果計算結果是0.2,則通過計算函數變成200,那么這時的f就會被加到3,
  133.                                                         if(decimals&&f==3)//接上如果f被加到三
  134.                                                         LCD_Write_Date(0x2e);//就在LCD1602上顯示小數點
  135.                                              delay();
  136.                                                         value/=10;//如果經過計算函數后是2000,則經過一次這個 value減少一位(減少的哪一位的數據已經寫入LCD1602中了)
  137.                                                         delay();
  138.                                           }
  139.                                           while(value);//當value 被用盡后跳出循環
  140.                                           if(decimals&&f<=3)//decimals是標志是否進行的是除法運算
  141.                                           {
  142.                                                         if(f==3)
  143.                                                         {
  144.                                                         LCD_Write_Date(0x30);//如果是三,因為前面程序已經在對應位置加了小數點了,這時我們住需要再在前面加一個0就可以了,如果沒有這條語句,0.5 的顯示就是.5
  145.                                                         }
  146.                                                         else
  147.                                                                       {
  148.                                                                       while(3-f)//當f<3時進入這程序
  149.                                               {LCD_Write_Date(0x30);
  150.                                                                                     f++;
  151.                                                                       }
  152.                                                                       LCD_Write_Date(0x2e);//寫小數點
  153.                                                                       delay();
  154.                                                           LCD_Write_Date(0x30);//寫數據0            
  155.                                                         }                                                                     
  156.                                           }                                                      
  157.                                 if(minus)//如果有負號標志
  158.                                                         LCD_Write_Date(0x2d);//在LCD1602上顯示負號
  159.                                                         add=0;
  160.                                 subtract=0;
  161.                                 ride=0;
  162.                                 divide=0;
  163.                                 equal=0;
  164.                                                         decimals=0;
  165.                                                         minus=0;
  166.                                                         eliminate=0;
  167.                             }            
  168.                            
  169.               }
  170. void main()
  171. {

  172.               int j,k=0,g;
  173.               i=0;

  174.               LCD_Initial();//初始化LCD1602

  175.               j=0;
  176.               while(1)
  177.               {
  178.               P2=0xfe;//掃描第一行是否有按鍵按下
  179.               while((P2&0xf0)!= 0xf0)               
  180.               {
  181.                             delay();              //延時消抖                     
  182.     while((P2&0xf0)!=0xf0)              //確認按下
  183.                             {
  184.                                           switch(key)              //鎖定按的是哪一個鍵                                         
  185.                                           {
  186.                                                         case 0xee: number[i]= 7; i++;k=1;break;//k=1表明按下的是數字鍵
  187.                                                         case 0xde: number[i]=8;i++;k=1; break;
  188.                                                         case 0xbe: number[i] =9; i++;k=1;break;
  189.                                                         case 0x7e: number[i]= '/';divide++;i++;break;//計算對應的表示功能鍵的變量按鍵次數
  190.                                                         default:   number[i] = '#';
  191.                                           }
  192.      while((P2& 0xf0) != 0xf0) ;//掃描第二行
  193.                             }
  194.               }
  195.               P2= 0xfd;            
  196.               while((P2&0xf0) != 0xf0)
  197.               {
  198.                             delay();

  199.                             while((P2& 0xf0) != 0xf0)
  200.                             {
  201.                                           switch(key)
  202.                                           {
  203.                                                         case 0xed: number[i]= 4;i++;k=1; break;
  204.                                                         case 0xdd: number[i] = 5; i++;k=1;break;
  205.                                                         case 0xbd: number[i] = 6;i++;k=1; break;
  206.                                                         case 0x7d: number[i] = '*';ride++;i++;break;
  207.                                                                      
  208.                                                         default:   number[i] = '#';
  209.                                           }

  210.                                           while((P2&0xf0)!= 0xf0)
  211.                                                         ;
  212.                             }
  213.               }
  214. P2= 0xfb;//掃描第三行
  215.               while((P2& 0xf0) != 0xf0)
  216.               {
  217.                             delay();
  218.                            
  219.                             while((P2& 0xf0) != 0xf0)
  220.                             {
  221.                                           switch(key)
  222.                                           {
  223.                                                         case 0xeb: number[i] =1; i++;k=1;break;
  224.                                                         case 0xdb: number[i]= 2; i++;k=1;break;
  225.                                                         case 0xbb: number[i] = 3; i++;k=1;break;
  226.                                                         case 0x7b: number[i]= '-';subtract++;i++;break;
  227.                                                                      
  228.                                                         default: number[i] = '#';
  229.                                           }

  230.                                           while((P2&0xf0)!= 0xf0);
  231.                             }
  232.               }
  233.               P2= 0xf7;//掃描第四行
  234.               while((P2&0xf0)!=0xf0)
  235.               {
  236.                             delay();
  237.     while((P2&0xf0)!=0xf0)
  238.                             {
  239.                                           switch(P2)
  240.                                           {
  241.                                                         case 0xe7: number[i]= 'eliminate=1;i++; break;
  242.                                                         case 0xd7: number[i]=0;i++;k=1; break;
  243.                                                         case 0xb7: number[i]= '=';i++;equal++;break;
  244.                                                         case 0x77: number[i]= '+';add++;i++;break;
  245.                                                         default:   number[i] = '#';
  246.                                           }

  247.                                           while((P2&0xf0)!= 0xf0);
  248.                             }
  249.               }
  250.               if(k==1)//如果有數字鍵按下,進入此程序
  251.               {
  252.               if(add+subtract+ride+divide==1)//如果有第一個加減乘除鍵被按下則進入負號符號鍵后面的數據存儲,如1+2  這里的b存 的是2
  253.               {
  254.                            
  255.               b=b*10+number[i-1];
  256.                             g=calculate();
  257.               }
  258.                            
  259.                                             if(add+subtract+ride+divide==2)//如果2+2+1,這里面的a=2+2, b=1,因為g村存儲了前面只有一個加號時的value
  260.               {
  261.                             a=g;
  262.                             b=0;
  263.                 b=b*10+number[i-1];
  264.               }
  265.                                             if(add+subtract+ride+divide==3)//如2+2+2+3,這里的a=2+2+2,b=3,同理往下
  266.               {
  267.                             a=g;
  268.                             b=0;
  269.                 b=b*10+number[i-1];
  270.               }
  271.                                             if(add+subtract+ride+divide==4)
  272.               {
  273.                             a=g;
  274.                             b=0;
  275.                 b=b*10+number[i-1];
  276.               }
  277. if(add+subtract+ride+divide==0)
  278.               {
  279.               a=a*10+number[i-1];
  280.               }
  281.               g=calculate();

  282.               k=0;
  283.   }
  284.               LCD_Write_Com (0x80); //將要輸入的數據放在首行
  285.               delay();
  286.               for(j=0;j<i;j++)
  287.               {
  288.                             if(number[j]=='+'||number[j]=='||number[j]=='-'||number[j]=='*'||number[j]=='/'||number[j]=='=')
  289.                  LCD_Write_Date( number[j]);//寫符號位
  290.                             else
  291.                                           LCD_Write_Date( number[j]+0x30);//寫數據位
  292.                             delay();
  293.               }
  294.               if(eliminate==1)//一旦按下清除鍵,LCD1602內數據會自動清零,可以反復輸入
  295.               {

  296.                             LCD_Initial();
  297.                             eliminate=0;
  298.                             i=0;
  299.                             a=0;
  300.                             b=0;
  301.               }
  302.               result();              //調用結果函數

  303.               }

  304. }
復制代碼

全部資料51hei下載地址:
簡易計算器.rar (375.26 KB, 下載次數: 125)

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

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

使用道具 舉報

沙發
ID:677934 發表于 2019-12-31 13:06 | 只看該作者
能不能實現連乘啊
回復

使用道具 舉報

板凳
ID:930485 發表于 2021-6-4 08:58 | 只看該作者
里面能進行小數的運算嗎
回復

使用道具 舉報

地板
ID:751615 發表于 2021-7-10 08:40 | 只看該作者
計算的都是錯的,你還直接超過來了?臥槽
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久久毛片网站 | 日一区二区 | 欧美成人精品欧美一级 | 天天插天天操 | 一区二区在线 | 成人在线视频免费观看 | 91社区在线观看播放 | 免费国产黄网站在线观看视频 | 欧美九九| 69精品久久久久久 | 日韩成人在线电影 | 国产一区二区在线免费观看 | 国产精品a级 | 在线视频一区二区 | 久草99| 草久久| 欧美 日韩 国产 成人 | 日韩网站在线 | 91久久国产综合久久91精品网站 | 国产精品久久久久久久久免费高清 | 中文字幕中文字幕 | 欧洲亚洲一区二区三区 | 久久另类 | 国产精品久久国产精品 | 一区二区不卡视频 | 欧美群妇大交群中文字幕 | 福利网站导航 | 精品国产乱码一区二区三 | 国产情侣一区 | 天天干天天干 | 久草在线视频中文 | 亚洲国产欧美91 | 在线精品一区二区 | 91观看 | 亚洲欧美一区在线 | 精品99久久久久久 | 久久久精彩视频 | 欧美精品在欧美一区二区 | 日本精品一区二区三区视频 | 精品国产乱码久久久久久1区2区 | 亚洲精品大全 |