找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 24997|回復(fù): 32
收起左側(cè)

51單片機(jī)實現(xiàn)計算器 proteus仿真及其程序源碼 帶教程

  [復(fù)制鏈接]
ID:115512 發(fā)表于 2016-4-20 19:03 | 顯示全部樓層 |閱讀模式
0.png
51單片機(jī)計算器資料包(本帖附件可以下載全部資料)
下載地址: 51簡單計算器.zip (578.5 KB, 下載次數(shù): 419)

硬件部分比較簡單,當(dāng)鍵盤按鍵按下時它的那一行、那一列的端口為低電平。因此,只要掃描行、列端口是否都為低電平就可以確定是哪個鍵被按下。

proteus仿真圖:
2.png

程序的主要思想是:將按鍵抽象為字符,然后就是對字符的處理。將操作數(shù)分別轉(zhuǎn)化為字符串存儲,操作符存儲為字符形式。然后調(diào)用compute()函數(shù)進(jìn)行計算并返回結(jié)果。具體程序及看注釋還有流程圖。
009.gif
51單片機(jī)實現(xiàn)的計算器流程圖

ppt教程文檔預(yù)覽:
1.png
3.png

計算器程序源碼(51單片機(jī)實現(xiàn)):
  1. #include <reg51.h>
  2. #include <intrins.h>
  3. #include <ctype.h>                        /*   isdigit()函數(shù)   */
  4. #include <stdlib.h>                        /*    atoi()函數(shù)     */

  5. #define uchar unsigned char
  6. #define uint unsigned int

  7. uchar operand1[9], operand2[9];  /*   操作數(shù)   */
  8. uchar operator;                                         /*   操作符   */

  9. void delay(uint);
  10. uchar keyscan();
  11. void disp(void);
  12. void buf(uint value);
  13. uint compute(uint va1,uint va2,uchar optor);

  14. uchar code table[] = {0xc0,0xf9,0xa4,0xb0,0x99,
  15.                                 0x92,0x82,0xf8,0x80,0x90,0xff};     /*   字符碼表   */

  16. uchar dbuf[8] = {10,10,10,10,10,10,10,10};                    /*   顯示緩存   */

  17. /*   延時函數(shù)   */               
  18. void delay(uint z)
  19. {
  20. uint x,y;
  21. for(x=z;x>0;x--)
  22.         for(y=110;y>0;y--);
  23. }

  24. /*******************************************
  25.               鍵盤掃描程序
  26.        將按鍵轉(zhuǎn)化為字符并作為輸出
  27.     '

  28. ,'#'分別表示清零鍵和沒有鍵按下
  29. *******************************************/
  30. uchar keyscan()
  31. {
  32.         uchar skey;                     /*   按鍵值標(biāo)記變量    */
  33.    
  34. /***********************
  35.      掃描鍵盤第1行   
  36. ************************/
  37.         P1 = 0xfe;
  38.         while((P1 & 0xf0) != 0xf0)            /*      有按鍵按下     */
  39.         {
  40.                 delay(3);                            /*      去抖動延時     */

  41.                 while((P1 & 0xf0) != 0xf0)        /*      仍有鍵按下     */
  42.                 {
  43.                         switch(P1)                                /*    識別按鍵并賦值   */
  44.                         {
  45.                                 case 0xee: skey = '7'; break;
  46.                                 case 0xde: skey = '8'; break;
  47.                                 case 0xbe: skey = '9'; break;
  48.                                 case 0x7e: skey = '/'; break;
  49.                                        
  50.                                 default:   skey = '#';
  51.                         }

  52.                         while((P1 & 0xf0) != 0xf0) /*   等待按鍵松開   */
  53.                                 ;
  54.                 }
  55.         }

  56. /***********************
  57.      掃描鍵盤第2行   
  58. ************************/
  59.         P1 = 0xfd;        
  60.         while((P1 & 0xf0) != 0xf0)
  61.         {
  62.                 delay(3);

  63.                 while((P1 & 0xf0) != 0xf0)
  64.                 {
  65.                         switch(P1)
  66.                         {
  67.                                 case 0xed: skey = '4'; break;
  68.                                 case 0xdd: skey = '5'; break;
  69.                                 case 0xbd: skey = '6'; break;
  70.                                 case 0x7d: skey = '*'; break;
  71.                                        
  72.                                 default:   skey = '#';
  73.                         }

  74.                         while((P1 & 0xf0) != 0xf0)
  75.                                 ;
  76.                 }
  77.         }


  78. /***********************
  79.      掃描鍵盤第3行   
  80. ************************/
  81.         P1 = 0xfb;
  82.         while((P1 & 0xf0) != 0xf0)
  83.         {
  84.                 delay(3);
  85.                
  86.                 while((P1 & 0xf0) != 0xf0)
  87.                 {
  88.                         switch(P1)
  89.                         {
  90.                                 case 0xeb: skey = '1'; break;
  91.                                 case 0xdb: skey = '2'; break;
  92.                                 case 0xbb: skey = '3'; break;
  93.                                 case 0x7b: skey = '-'; break;
  94.                                        
  95.                                 default: skey = '#';
  96.                         }

  97.                         while((P1 & 0xf0) != 0xf0)
  98.                                 ;
  99.                 }
  100.         }


  101. /***********************
  102.      掃描鍵盤第4行   
  103. ************************/
  104.         P1 = 0xf7;
  105.         while((P1 & 0xf0) != 0xf0)
  106.         {
  107.                 delay(3);

  108.                 while((P1 & 0xf0) != 0xf0)
  109.                 {
  110.                         switch(P1)
  111.                         {
  112.                                 case 0xe7: skey = '

  113. ; break;
  114.                                 case 0xd7: skey = '0'; break;
  115.                                 case 0xb7: skey = '='; break;
  116.                                 case 0x77: skey = '+'; break;
  117.                                        
  118.                                 default:   skey = '#';
  119.                         }

  120.                         while((P1 & 0xf0) != 0xf0)
  121.                                 ;
  122.                 }
  123.         }

  124.         return skey;
  125. }

  126. void main()
  127. {        
  128.         uint value1, value2, value;                   /*    數(shù)值1,數(shù)值2,結(jié)果    */
  129.         uchar ckey, cut1 = 0, cut2 = 0;    /*    ckey鍵盤輸入字符    */
  130.         uchar operator;                               /*         運算符         */
  131.         uchar i, bool = 0;

  132. init:                                                                   /*    goto語句定位標(biāo)簽    */

  133.         buf(0);                            /*         初始化         */
  134.         disp();
  135.         value = 0;
  136.         cut1 = cut2 = 0;
  137.         bool = 0;
  138.         for(i = 0;i < 9;i++)
  139.         {
  140.                 operand1[i] = '\0';
  141.                 operand2[i] = '\0';
  142.         }                                  /*         初始化         */

  143.         while(1)
  144.         {
  145.                 ckey = keyscan();             /*         讀取鍵盤        */
  146.                 if(ckey != '#')
  147.                 { /*  isdigit函數(shù),字符是阿拉伯?dāng)?shù)字返回非0值,否則返回0  */
  148.                         if(isdigit(ckey))         
  149.                         {
  150.                                 switch(bool)        
  151.                                 {
  152.                                         case 0:
  153.                                                         operand1[cut1] = ckey;
  154.                                                         operand1[cut1+1] = '\0';
  155.                                                         value1 = atoi(operand1);  /*  atoi函數(shù),將字符串轉(zhuǎn)化為,int整數(shù)  */
  156.                                                         cut1++;
  157.                                                         buf(value1);
  158.                                                         disp();
  159.                                                         break;
  160.                                         case 1:
  161.                                                         operand2[cut2] = ckey;
  162.                                                         operand2[cut2+1] = '\0';
  163.                                                         value2 = atoi(operand2);
  164.                                                         cut2++;
  165.                                                         buf(value2);
  166.                                                         disp();
  167.                                                         break;
  168.                                                         
  169.                                         default: break;
  170.                                 }
  171.                         }
  172.                         else if(ckey=='+'||ckey=='-'||ckey=='*'||ckey=='/')
  173.                         {
  174.                                 bool = 1;        
  175.                                 operator = ckey;
  176.                                 buf(0);
  177.                                 dbuf[7] = 10;
  178.                                 disp();
  179.                         }
  180.                         else if(ckey == '=')
  181.                         {
  182.                                 value = compute(value1,value2,operator);
  183.                                 buf(value);
  184.                                 disp();
  185.                                 while(1)                     /*   計算結(jié)束等待清零鍵按下   */
  186.                                 {
  187.                                         ckey = keyscan();
  188.                                         if(ckey == '

  189. )          /* 如果有清零鍵按下跳轉(zhuǎn)到開始 */
  190.                                                 goto init;
  191.                                         else
  192.                                                 {
  193.                                                         buf(value);
  194.                                                         disp();
  195.                                                 }
  196.                                 }
  197.                         }
  198.                         else if(ckey == '

  199. )
  200.                         {        goto init;}
  201.                 }
  202.                 disp();
  203.         }

  204. }

  205. /******************************************
  206.                  運算函數(shù)

  207. 輸入:操作數(shù)和操作符
  208. 輸出:計算結(jié)果
  209. *******************************************/
  210. uint compute(uint va1,uint va2,uchar optor)
  211. {
  212.         uint value;

  213.         switch(optor)
  214.         {
  215.                 case '+' : value = va1+va2;        break;
  216.                 case '-' : value = va1-va2;        break;
  217.                 case '*' : value = va1*va2;        break;
  218.                 case '/' : value = va1/va2;        break;
  219.                
  220.                 default :  break;
  221.         }
  222.         return value;
  223. }

  224. /*******************************************
  225.               更新顯示緩存

  226. 輸入:無符號整數(shù)
  227. 輸出:將輸入送入顯示緩存
  228. *******************************************/
  229. void buf(uint val)
  230. {
  231.         uchar i;
  232.         if(val == 0)
  233.         {
  234.                 dbuf[7] = 0;
  235.                 i = 6;
  236.         }
  237.         
  238.         else
  239.                 for(i = 7; val > 0; i--)
  240.                 {
  241.                         dbuf[i] = val % 10;
  242.                         val /= 10;
  243.                 }
  244.         
  245.         for( ; i > 0; i--)
  246.                 dbuf[i] = 10;
  247. }

  248. /*******************************************
  249.                顯示函數(shù)      
  250. *******************************************/
  251. void disp(void)
  252. {
  253.         uchar bsel, n;
  254.         
  255.         bsel=0x01;
  256.     for(n=0;n<8;n++)
  257.     {
  258.                 P2=bsel;
  259.                 P0=table[dbuf[n]];
  260.                 bsel=_crol_(bsel,1);
  261.                 delay(3);
  262.                 P0=0xff;
  263.     }
  264. }
復(fù)制代碼


評分

參與人數(shù) 3黑幣 +60 收起 理由
威威威威11112 + 5 共享資料的黑幣獎勵!
3535435345 + 5 共享資料的黑幣獎勵!
admin + 50 共享資料的黑幣獎勵!

查看全部評分

相關(guān)帖子

回復(fù)

使用道具 舉報

ID:262 發(fā)表于 2022-3-16 00:21 | 顯示全部樓層

是不是你的Keil沒安裝好 我編譯出來是0個錯誤呢 你看
51hei.png

c樣本51hei.7z

17.02 KB, 下載次數(shù): 6, 下載積分: 黑幣 -5

回復(fù)

使用道具 舉報

ID:144173 發(fā)表于 2016-10-24 11:40 | 顯示全部樓層
這個不錯的,學(xué)習(xí)一下
回復(fù)

使用道具 舉報

ID:157542 發(fā)表于 2016-12-25 17:05 | 顯示全部樓層
好好學(xué)習(xí)學(xué)習(xí)
回復(fù)

使用道具 舉報

ID:58293 發(fā)表于 2017-1-15 16:44 | 顯示全部樓層
教程很好,值得我們好好學(xué)習(xí)。
回復(fù)

使用道具 舉報

ID:58293 發(fā)表于 2017-1-15 16:45 | 顯示全部樓層
教程很好,程序?qū)懙挠兴,值得我們好好學(xué)習(xí)。
回復(fù)

使用道具 舉報

ID:170442 發(fā)表于 2017-3-13 21:29 | 顯示全部樓層
好東西
回復(fù)

使用道具 舉報

ID:32305 發(fā)表于 2017-3-29 21:44 | 顯示全部樓層
好東西
回復(fù)

使用道具 舉報

ID:214190 發(fā)表于 2017-6-24 10:04 | 顯示全部樓層
學(xué)習(xí)學(xué)習(xí)
回復(fù)

使用道具 舉報

ID:215965 發(fā)表于 2017-6-29 22:39 | 顯示全部樓層
學(xué)習(xí)學(xué)習(xí)
回復(fù)

使用道具 舉報

ID:219101 發(fā)表于 2017-7-12 13:53 | 顯示全部樓層
下載下來,好好學(xué)習(xí)一番
回復(fù)

使用道具 舉報

ID:219910 發(fā)表于 2017-7-15 21:42 | 顯示全部樓層
拿走拿走
回復(fù)

使用道具 舉報

ID:291482 發(fā)表于 2018-5-10 09:06 | 顯示全部樓層
6666666666666666666666666666666666666666666666666666666666666666666666
回復(fù)

使用道具 舉報

ID:323496 發(fā)表于 2018-5-11 06:42 來自手機(jī) | 顯示全部樓層
好好學(xué)習(xí)學(xué)習(xí)啊
回復(fù)

使用道具 舉報

ID:336429 發(fā)表于 2018-5-23 13:32 來自手機(jī) | 顯示全部樓層
最近在做基于LPC2106的計算器系統(tǒng),拿走學(xué)習(xí)一下。
回復(fù)

使用道具 舉報

ID:336462 發(fā)表于 2018-5-23 14:10 | 顯示全部樓層
有仿真的結(jié)果圖嗎
回復(fù)

使用道具 舉報

ID:505584 發(fā)表于 2019-4-6 11:23 | 顯示全部樓層
很好的模擬入門介紹材料
回復(fù)

使用道具 舉報

ID:647395 發(fā)表于 2019-11-29 14:06 | 顯示全部樓層
很強(qiáng)大哦
回復(fù)

使用道具 舉報

ID:625113 發(fā)表于 2019-11-30 12:33 來自手機(jī) | 顯示全部樓層
收藏了,謝謝分享
回復(fù)

使用道具 舉報

ID:677934 發(fā)表于 2019-12-31 00:26 | 顯示全部樓層
來學(xué)習(xí)啦
回復(fù)

使用道具 舉報

ID:677934 發(fā)表于 2019-12-31 12:20 | 顯示全部樓層
沒有辦法連乘,不然就會出錯
回復(fù)

使用道具 舉報

ID:681489 發(fā)表于 2020-1-5 22:56 來自手機(jī) | 顯示全部樓層
ykxdsy 發(fā)表于 2019-12-31 12:20
沒有辦法連乘,不然就會出錯

為什么我的顯示不出來啊
回復(fù)

使用道具 舉報

ID:775080 發(fā)表于 2020-6-17 10:44 | 顯示全部樓層
感謝樓主
回復(fù)

使用道具 舉報

ID:786925 發(fā)表于 2020-6-22 18:08 | 顯示全部樓層
我的顯示有好幾個錯誤,程序不能運行
回復(fù)

使用道具 舉報

ID:790447 發(fā)表于 2020-6-27 14:57 | 顯示全部樓層
我的可以,你要參考參考么
回復(fù)

使用道具 舉報

ID:937844 發(fā)表于 2021-6-18 15:16 | 顯示全部樓層
感謝大佬又給了思路
回復(fù)

使用道具 舉報

ID:696966 發(fā)表于 2021-6-20 16:19 | 顯示全部樓層
很有含量的教程,這樣的教程多多益善啊
回復(fù)

使用道具 舉報

ID:943990 發(fā)表于 2021-6-24 14:57 | 顯示全部樓層
支持混合運算嗎
回復(fù)

使用道具 舉報

ID:944054 發(fā)表于 2021-6-24 15:51 | 顯示全部樓層

這個不錯的,學(xué)習(xí)一下
回復(fù)

使用道具 舉報

ID:943990 發(fā)表于 2021-6-28 08:56 | 顯示全部樓層
outlier_ 發(fā)表于 2020-6-27 14:57
我的可以,你要參考參考么

咱能不能參考一下
回復(fù)

使用道具 舉報

ID:1010607 發(fā)表于 2022-3-15 22:57 | 顯示全部樓層
程序有錯誤怎么改
回復(fù)

使用道具 舉報

ID:1134947 發(fā)表于 2024-11-13 16:02 | 顯示全部樓層
這個不錯的
回復(fù)

使用道具 舉報

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

本版積分規(guī)則

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

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

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