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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

單片機計算器仿真程序(注釋很全)實現9999以內簡單的四則運算

[復制鏈接]
跳轉到指定樓層
樓主
矩陣鍵盤輸入,LCD屏幕顯示,可以實現9999以內簡單的四則運算

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


單片機源程序如下,代碼有詳細的中文注釋:
  1. /*
  2. 接盤按鍵說明:
  3. --------------------------------------------------
  4.             |  7  |  8  |  9  |  /  |  
  5.             - - - - - - - - - - - - -
  6.             |  4  |  5  |  6  |  *  |
  7.             - - - - - - - - - - - - -
  8.             |  1  |  2  |  3  |  -  |
  9.             - - - - - - - - - - - - -
  10.                         | C   |  0  |  =  |  +  |
  11. --------------------------------------------------*/
  12. //操作簡介
  13. // 按第一個數,再按'+-*/',再按'='顯示出結果,然后按C清屏
  14. // 加最大9999+9999=19998
  15. // 減最大9999-0   =9999
  16. // 乘最大9999*9999=99980001
  17. // 除 1/9=0.1111 保留小數點后4位
  18. #include<reg51.h>
  19. #define uint unsigned int
  20. #define uchar unsigned char
  21. //--------LCD1602-------------------
  22. //P00-07==== D0-7
  23. sbit rs=P2^7;        //指令or數據
  24. sbit wela=P2^6;      //讀or寫
  25. sbit lcden=P2^5;         //使能信號
  26. //--------LCD1602-------------------
  27. //--------KEY-----------------------
  28. //P1口
  29. //--------KEY-----------------------
  30. uchar code table[]= "                ";

  31. long  int data_a,data_b;         //第一個數和第二個數
  32. long  int data_c;                        //計算結果

  33. uchar dispaly[10];         //顯示緩沖

  34. //************************************************************************/
  35. // 描述: 延時t us函數
  36. //************************************************************************/
  37. void LCD_Delay_us(unsigned int t)
  38. {
  39.         while(t--);           //t=0,退出
  40. }
  41. //************************************************************************/
  42. // 描述: 延時t ms函數
  43. //************************************************************************/
  44. void LCD_Delay_ms(unsigned int t)
  45. {
  46.         unsigned int i,j;
  47.         for(i=0;i<t;i++)                       //執行t次循環
  48.         for(j=0;j<113;j++)                     //執行113次循環
  49.         ;
  50. }
  51. //************************************************************************/
  52. // 描述: 1602液晶寫指令
  53. //************************************************************************/
  54. void write_com(uchar com)            //1602液晶寫指令
  55. {
  56.         rs=0;                       //寫指令
  57.         lcden=0;                    //使能1602
  58.         P0=com;                     //寫入指令com
  59.         LCD_Delay_ms(1);            //延時1ms
  60.         lcden=1;                    //使能1602
  61.         LCD_Delay_ms(2);            //延時2ms  
  62.         lcden=0;                        //使能1602
  63. }
  64. //************************************************************************/
  65. // 描述:1602液晶寫數據
  66. //************************************************************************/
  67. void write_date(uchar date) //1602液晶寫數據
  68. {
  69.         rs=1;                        //寫數據
  70.         lcden=0;                     //使能1602
  71.         P0=date;                     //寫入數據date
  72.         LCD_Delay_ms(1);             //延時1ms
  73.         lcden=1;                     //使能1602
  74.         LCD_Delay_ms(2);             //延時2ms
  75.         lcden=0;                         //使能1602
  76. }
  77. //************************************************************************/
  78. // 描述:指定x,y寫入字符函數
  79. //************************************************************************/
  80. void W_lcd(unsigned char x,unsigned char y,unsigned char Data)
  81. {     
  82.          if (y == 0){write_com(0x80 + x);}   //第一行  
  83.          else{write_com(0xc0 + x);}          //第二行
  84.          write_date( Data);                  //寫入數據
  85. }
  86. //指定x,y寫入字符串函數
  87. void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
  88. {     
  89. if (y == 0){write_com(0x80 + x);}                 //第一行
  90. else{write_com(0xC0 + x);}                        //第二行
  91. while (*s)                                        //
  92.          {write_date( *s); s++;}                      //寫入數據
  93. }
  94. //************************************************************************/
  95. // 描述:初始化液晶,及畫面初始化
  96. //************************************************************************/
  97. void init_lcd(void)            //初始化液晶,及畫面初始化
  98. {
  99.         wela=0;                      //寫液晶
  100.         lcden=0;                     //使能1602
  101.         write_com(0x38);             //8 位總線,雙行顯示,5X7 的點陣字符
  102.         LCD_Delay_us(100);           //延時100us
  103.         write_com(0x0c);             //開顯示,無光標,光標不閃爍
  104.         write_com(0x06);             //光標右移動
  105.         write_com(0x01);             //清屏
  106.         write_com(0x80);             //DDRAM 地址歸0
  107. }
  108. //************************************************************************/
  109. // 描述: 反轉法鍵盤掃描
  110. //************************************************************************/
  111. short keycheckdown()                                /* 反轉法鍵盤掃描 */
  112. {

  113.         short temp1,temp2,temp,a=0xff;
  114.         P1=0xf0;                                                /* 輸入行值(或列值) */
  115.         LCD_Delay_ms(20);                                /* 延時 */
  116.         temp1=P1;                                                /* 讀列值(或行值) */
  117.         P1=0xff;
  118.         LCD_Delay_ms(20);                                /* 延時 */
  119.         P1=0x0f;                                                /* 輸入列值(或行值) */
  120.         LCD_Delay_ms(20);                                /* 延時 */        
  121.         temp2=P1;                                                /* 讀行值(或列值) */
  122.         P1=0xff;
  123.         temp=(temp1&0xf0)|(temp2&0xf);        /* 將兩次讀入數據組合 */
  124.         switch(temp)                                        /* 通過讀入數據組合判斷按鍵位置 */
  125.         {


  126.                 case 0x77 :a=0x0a;break;//  按鍵+   
  127.                 case 0x7b :a=0x0e; break;// 按鍵=        
  128.                 case 0x7d :a=0;           break;// 按鍵0
  129.                 case 0x7e :a=0x0f; break;// 按鍵CE

  130.                 case 0xe7 :a=0x0d;break;//         按鍵/
  131.                 case 0xeb :a=0x9;break; //  按鍵9
  132.                 case 0xed :a=0x8;break; //  按鍵8
  133.                 case 0xee :a=0x7;break; //         按鍵7

  134.                 case 0xd7 :a=0x0c;break;//  按鍵*
  135.                 case 0xdb :a=0x6;break; //         按鍵6
  136.                 case 0xdd :a=0x5;break; //         按鍵5
  137.                 case 0xde :a=0x4;break; //         按鍵4

  138.                 case 0xb7 :a=0x0b; break;// 按鍵-
  139.                 case 0xbb :a=3;break;        //  按鍵3
  140.                 case 0xbd :a=2;break;        //  按鍵2
  141.                 case 0xbe :a=1;break;        //  按鍵1

  142.                 default :a=0xff;
  143.         }
  144.         return a;                                                /* 返回按鍵值 */
  145. }
  146. void display_a() //顯示數據a
  147. {
  148.         dispaly[3]=data_a%10000/1000;    //千
  149.         dispaly[2]=data_a%1000/100;      //百
  150.         dispaly[1]=data_a%100/10;        //十
  151.         dispaly[0]=data_a%10;            //個

  152.         write_com(0x80+0);               //顯示數據a
  153.         if(data_a>999){        write_date('0'+dispaly[3]);}      //顯示千位
  154.         if(data_a>99){        write_date('0'+dispaly[2]);}                 //顯示百位
  155.         if(data_a>9){        write_date('0'+dispaly[1]);}     //顯示十位
  156.                               write_date('0'+dispaly[0]);      //顯示個位
  157. }

  158. void display_b() //顯示數據b
  159. {
  160.         write_com(0x80+7); //第一行
  161.         dispaly[3]=data_b%10000/1000;    //千
  162.         dispaly[2]=data_b%1000/100;      //百
  163.         dispaly[1]=data_b%100/10;        //十
  164.         dispaly[0]=data_b%10;            //個

  165. if(data_b>999){        write_date('0'+dispaly[3]); }     //顯示千位   
  166. if(data_b>99) {        write_date('0'+dispaly[2]); }    //顯示百位  
  167. if(data_b>9)  {        write_date('0'+dispaly[1]); }     //顯示十位
  168.                               write_date('0'+dispaly[0]);      //顯示個位
  169. }

  170. //計算結果
  171. void display_c(x)
  172. {

  173.         if(data_c<100000000&&data_c>-1)//溢出時顯示錯誤
  174.         {        

  175.                 dispaly[8]=data_c%1000000000/100000000;            //萬萬
  176.                 dispaly[7]=data_c%100000000/10000000;            //千萬
  177.                 dispaly[6]=data_c%10000000/1000000;                    //百萬
  178.                 dispaly[5]=data_c%1000000/100000;                    //十萬
  179.                 dispaly[4]=data_c%100000/10000;                            //萬
  180.                 dispaly[3]=data_c%10000/1000;                            //千
  181.                 dispaly[2]=data_c%1000/100;                              //百
  182.                 dispaly[1]=data_c%100/10;                                //十
  183.                 dispaly[0]=data_c%10;                                    //個
  184.                 write_com(0x80+6+0x40); //第一行
  185.                 if(x==4)
  186.                 {   
  187.                         if(data_c>99999999)        {        write_date('0'+dispaly[8]);}    //顯示萬萬
  188.                         if(data_c>9999999)        {        write_date('0'+dispaly[7]);}   //千萬
  189.                         if(data_c>999999)        {        write_date('0'+dispaly[6]);}    //百萬
  190.                         if(data_c>99999)        {        write_date('0'+dispaly[5]);}    //十萬
  191.                         if(data_b!=0)                {
  192.                                                                         write_date('0'+dispaly[4]);    //萬
  193.                                                                         write_date('.');
  194.                                                                         write_date('0'+dispaly[3]);    //千
  195.                                                                         write_date('0'+dispaly[2]);    //百
  196.                                                                         write_date('0'+dispaly[1]);    //十
  197.                                                                         write_date('0'+dispaly[0]);    //個
  198.                                                                 }
  199.                 }
  200.         else{
  201.                 if(data_c>99999999)        {        write_date('0'+dispaly[8]);}    //顯示萬萬
  202.                 if(data_c>9999999)        {        write_date('0'+dispaly[7]);}    //千萬
  203.                 if(data_c>999999)        {        write_date('0'+dispaly[6]);}    //百萬
  204.                 if(data_c>99999)        {        write_date('0'+dispaly[5]);}    //十萬
  205.                 if(data_c>9999)                {        write_date('0'+dispaly[4]);}    //萬
  206.                 if(data_c>999)                {        write_date('0'+dispaly[3]);}    //千
  207.                 if(data_c>99)                {        write_date('0'+dispaly[2]);}    //百
  208.                 if(data_c>9)                {        write_date('0'+dispaly[1]);}    //十
  209.                                                                 write_date('0'+dispaly[0]);    //個
  210.                 }
  211.         }
  212. //        else  //溢出時顯示錯誤
  213. //        {
  214. //                write_com(0x80+11+0x40); //第一行
  215. //                write_date('E');         //顯示 E
  216. //                write_date('r');         //顯示R
  217. //                write_date('r');                 //顯示R
  218. //                write_date('o');                 //顯示O
  219. //                write_date('r');                 //顯示E
  220. //        }
  221. }

  222. void eql(uchar x)//加減乘除運算
  223. {
  224.         switch(x)                /*功能鍵選擇*/
  225.                         {   
  226.                                 case 1:data_c=data_a+data_b;break;                   //加  /* + S=1 */ /* 數值轉換函數 */                                                                        
  227.                                 case 2:if(data_a>=data_b){data_c=data_a-data_b;} /* - S=2 *///減
  228.                        else{data_c=data_b-data_a;W_lcd(5,1,'-');} //負數符號
  229.                                            break;           
  230.                                 case 3:data_c=(data_a*data_b);break;                  /* * S=3 *///乘
  231.                                 case 4:if(data_b==0){LCD_Write_String(0,1,"Error !         ");}else{data_c=(data_a*10000)/data_b;}break;                  /* / S=4 *///除//溢出時顯示錯誤
  232.                                 case 0:break;
  233.                         }         

  234. }

  235. void main()
  236. {
  237.         uchar   key=0xff;               //鍵值初始化
  238.         uchar   n=0;                                         //第1個數可以按1-4次
  239.         uchar   m=5;                                         //第2個數可以按1-4次
  240.         uchar   x=0;
  241.         data_a=0;                       //前一個數
  242.         data_b=0;                       //后一個數
  243.         data_c=0;                       //結果
  244.         init_lcd();                                          //1602液晶初始化
  245.         display_a();
  246.     while(1)
  247.           {
  248.                   key=keycheckdown();                        /*動態掃描鍵盤,返回按鍵對應值,賦給j        key=0到f */
  249.                 if(0xff!=key)                                /*若返回值有效,進入內部處理程序*/
  250.                 {
  251.                   if(key<10)
  252.                   {
  253.                           if(key==0&&n==0) ;
  254.                         else
  255.                         {
  256.                                 if(n<4){data_a=data_a*10+key;m=5;display_a();}n++;  //首先輸入第一個數        
  257.                         }
  258.                 if(key==0&&m==0) ;
  259.                         else
  260.                         {
  261.                                 if(m<4){data_b=data_b*10+key;n=5;display_b();}m++;  //必須按了+-*/才能輸入第二個數        
  262.                         }
  263.                   }
  264.           else
  265.           {        switch(key)                /*功能鍵選擇*/
  266.                                         {
  267.                                                 case 0xa:n=5;m=0;x=1;W_lcd(5,0,'+');break; //加  /* + S=1 */ /* 數值轉換函數 */                                                                        
  268.                                                 case 0xb:n=5;m=0;x=2;W_lcd(5,0,'-');break;                  /* - S=2 *///減
  269.                                                 case 0xc:n=5;m=0;x=3;W_lcd(5,0,'*');break;                  /* * S=3 *///乘
  270.                                                 case 0xd:n=5;m=0;x=4;W_lcd(5,0,'/');break;                  /* / S=4 *///除
  271.                                                 case 0xe:n=5;m=5;eql(x);W_lcd(12,0,'=');display_c(x);break;           /* = */
  272.                                                 case 0xf:n=0;x=0;m=5; data_a=0;data_b=0;data_c=0;LCD_Write_String(0,0,table);LCD_Write_String(0,1,table);W_lcd(0,0,'0');break; /*     C*/
  273.                                         }                           
  274.                   }
  275.                         do{P1=0xf0;}while(P1!=0xf0);                /*等待按鍵松開*/
  276.                   }//(0xff!=key)         
  277.           }//while
  278. }//main
復制代碼

所有資料51hei提供下載:
新建文件夾 (2).zip (83.8 KB, 下載次數: 88)

評分

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

查看全部評分

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

使用道具 舉報

沙發
ID:473034 發表于 2019-1-26 10:36 | 只看該作者
一直不太清楚發一個帖子長多少
回復

使用道具 舉報

板凳
ID:88256 發表于 2019-9-29 23:00 | 只看該作者
這個給新手學習不錯
回復

使用道具 舉報

地板
ID:253767 發表于 2019-9-30 08:05 | 只看該作者
謝謝分享。。
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久久99精品久久久久久 | 亚洲国产成人精品女人久久久 | 丝袜 亚洲 另类 欧美 综合 | 黄色一级大片在线免费看产 | 国产亚洲成av人片在线观看桃 | 天天操天天射天天 | 91免费高清 | 岛国av免费在线观看 | 中文字幕av一区 | 国产一区二区三区久久久久久久久 | 色吊丝在线 | 国产美女视频 | 麻豆精品国产免费 | 草草在线观看 | 国产日韩欧美激情 | 美女视频一区 | 日韩中文在线 | www久久99 | 黑人性hd | 亚洲 精品 综合 精品 自拍 | 国产aⅴ精品 | 精品日韩| 欧美精品在线一区二区三区 | 毛片免费观看视频 | 欧美成人激情 | 97国产在线观看 | 青娱乐国产 | www久久国产| 欧美一二三区 | 久久久亚洲一区 | 亚州av在线 | 日韩毛片网 | 国产精品美女久久久久久不卡 | 日本中文字幕在线视频 | 欧美成年网站 | 国产成人免费视频网站视频社区 | av夜夜操| 青青草精品 | 国产激情| 成人在线精品 | 国产免费一区二区 |