單片機論壇

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1639|回復: 7
收起左側

沃特福德对曼联直播: 單片機課程設計 簡易計算器仿真圖+代碼(含注釋)

[復制鏈接]
火車開往海邊 發表于 2018-11-14 16:11 | 顯示全部樓層 |閱讀模式
僅供參考,需要的自取。
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
0.png 0.png

單片機源程序如下:
  1. ///////////////////////////////////////////////////
  2. //功能 0 1 2 3 4 5 6 7 8 9 + - × ÷ = 清零  表3-1  3.2 計算器的軟件設計
  3. #include<reg51.h>   //頭文件
  4. #define uint unsigned int //  
  5. #define uchar unsigned char   
  6. sbit lcden=P2^3; //定義引腳
  7. sbit rs=P2^4;
  8. sbit rw=P2^0;
  9. sbit busy=P0^7;
  10. char i,j,temp,num,num_1;
  11. long a,b,c;     //a,第一個數 b,第二個數 c,得數
  12. float a_c,b_c;
  13. uchar flag,fuhao;//flag表示是否有符號鍵按下,fuhao表征按下的是哪個符號  
  14. uchar code table[]={ 7,8,9,0, 4,5,6,0, 1,2,3,0, 0,0,0,0};
  15. uchar code table1[]={
  16. ///////////////////////////////////////////////////
  17. 7,8,9,0x2f-0x30,
  18. 4,5,6,0x2a-0x30,
  19. 1,2,3,0x2d-0x30,
  20.   0x01-0x30,0,0x3d-0x30,0x2b-0x30};  
  21. void delay(uchar z) // 延遲函數
  22. {
  23. uchar y;
  24. for(z;z>0;z--)
  25.      for(y=0;y<110;y++);
  26. }   void check() // 判斷忙或空閑
  27. {
  28. do{
  29.      P0=0xFF;
  30.      rs=0;     //指令
  31.      rw=1;     //讀
  32.       lcden=0;     //禁止讀寫
  33.       delay(1); //等待,液晶顯示器處理數據
  34.      lcden=1;     //允許讀寫
  35.       }while(busy==1); //判斷是否為空閑,1為忙,0為空閑
  36. }  
  37. void write_com(uchar com) // 寫指令函數  
  38. ///////////////////////////////////////////////////
  39. {
  40.   P0=com;    //com指令付給P0口
  41. rs=0;
  42. rw=0;
  43. lcden=0;
  44. check();
  45. lcden=1;
  46. }   
  47. void write_date(uchar date) // 寫數據函數
  48. {
  49.      P0=date;
  50. rs=1;
  51. rw=0;
  52. lcden=0;
  53. check();
  54. lcden=1;
  55. }   
  56. void init() //初始化
  57. {
  58.      num=-1;
  59.   lcden=1; //使能信號為高電平
  60. write_com(0x38); //8位,2行
  61. ///////////////////////////////////////////////////
  62. write_com(0x0c); //顯示開,光標關,不閃爍*/
  63. write_com(0x06); //增量方式不移位 顯竟獗暌貧 柚?
  64. write_com(0x80); //檢測忙信號
  65.   write_com(0x01); //顯示開,光標關,不閃爍
  66. num_1=0;
  67. i=0;
  68. j=0;
  69.   a=0;     //第一個參與運算的數
  70. b=0;     //第二個參與運算的數
  71. c=0;
  72.   flag=0; //flag表示是否有符號鍵按下,
  73.   fuhao=0; // fuhao表征按下的是哪個符號
  74. }
  75.   void keyscan() // 鍵盤掃描程序
  76. {
  77.    P3=0xfe;
  78.   if(P3!=0xfe)
  79. {
  80.      delay(20); //延遲20ms
  81.     if(P3!=0xfe)
  82.     {
  83.      temp=P3&0xf0;
  84.      switch(temp)
  85. ///////////////////////////////////////////////////
  86.     {
  87.       case 0xe0:num=0;
  88.         break;
  89.        case 0xd0:num=1;
  90.         break;
  91.        case 0xb0:num=2;
  92.         break;
  93.       case 0x70:num=3;
  94.         break;
  95.      }
  96.    }
  97.      while(P3!=0xfe);
  98.      if(num==0||num==1||num==2)//如果按下的是'7','8'或'9
  99.    {
  100.         if(j!=0)
  101.          {
  102.              write_com(0x01);
  103.           j=0;
  104.           }
  105.         if(flag==0)//沒有按過符號鍵
  106.      {
  107.        a=a*10+table[num];
  108.      }
  109.       else//如果按過符號鍵
  110. ///////////////////////////////////////////////////
  111.     {
  112.       b=b*10+table[num];
  113.      }
  114.     }
  115.      else//如果按下的是'/'
  116.    {
  117.      flag=1;
  118.      fuhao=4;//4表示除號已按
  119.    }
  120.      i=table1[num];
  121.    write_date(0x30+i);
  122. }
  123.   P3=0xfd;
  124. if(P3!=0xfd)
  125. {
  126.      delay(5);
  127.     if(P3!=0xfd)
  128.     {
  129.       temp=P3&0xf0;
  130.      switch(temp)
  131.      {
  132.       case 0xe0:num=4;
  133.          break;
  134. ///////////////////////////////////////////////////
  135.      case 0xd0:num=5;
  136.           break;
  137.               case 0xb0:num=6;
  138.           break;
  139.               case 0x70:num=7;
  140.           break;
  141.      }
  142.     }
  143.      while(P3!=0xfd);
  144.      if(num==4||num==5||num==6&&num!=7)//如果按下的是'4','5'或'6'
  145.     {
  146.       if(j!=0)
  147.          {
  148.             write_com(0x01);
  149.           j=0;
  150.           }
  151.          if(flag==0)//沒有按過符號鍵
  152.      {
  153.       a=a*10+table[num];
  154.       }
  155.       else//如果按過符號鍵
  156. ///////////////////////////////////////////////////
  157.     {
  158.        b=b*10+table[num];
  159.      }
  160.    }
  161.      else//如果按下的是'/'
  162.     {
  163.      flag=1;
  164.      fuhao=3;//3表示乘號已按
  165.     }
  166.      i=table1[num];
  167.     write_date(0x30+i);
  168. }
  169.   P3=0xfb; if(P3!=0xfb)
  170. {
  171.      delay(5);
  172.     if(P3!=0xfb)
  173.     {
  174.       temp=P3&0xf0;
  175.      switch(temp)
  176.      {
  177.       case 0xe0:num=8;
  178.          break;
  179. ///////////////////////////////////////////////////
  180.      case 0xd0:num=9;
  181.          break;
  182.              case 0xb0:num=10;
  183.           break;
  184.               case 0x70:num=11;
  185.           break;
  186.      }
  187.     }
  188.     while(P3!=0xfb);
  189.     if(num==8||num==9||num==10)//如果按下的是'1','2'或'3'
  190.    {
  191.       if(j!=0)
  192.          {
  193.              write_com(0x01);
  194.            j=0;
  195.           }
  196.        if(flag==0)//沒有按過符號鍵
  197.      {
  198.        a=a*10+table[num];
  199.       }
  200.      else//如果按過符號鍵
  201. ///////////////////////////////////////////////////
  202.     {
  203.        b=b*10+table[num];
  204.       }
  205.     }
  206.      else if(num==11)//如果按下的是'-'
  207.     {
  208.      flag=1;
  209.       fuhao=2;//2表示減號已按
  210.     }
  211.      i=table1[num];
  212.     write_date(0x30+i);
  213. }
  214.   P3=0xf7;
  215.   if(P3!=0xf7)
  216. {
  217.      delay(5);
  218.     if(P3!=0xf7)
  219.     {
  220.       temp=P3&0xf0;
  221.      switch(temp)
  222.      {
  223.        case 0xe0:num=12;
  224.           break;
  225. ///////////////////////////////////////////////////
  226.               case 0xd0:num=13;
  227.           break;
  228.              case 0xb0:num=14;
  229.           break;
  230.               case 0x70:num=15;
  231.           break;
  232.      }
  233.     }
  234.     while(P3!=0xf7);
  235.     switch(num)
  236.     {
  237.       case 12:{write_com(0x01);a=0;b=0;flag=0;fuhao=0;}//按下的是"清零"
  238.       break;
  239.       case 13:{                //按下的是"0"
  240.         if(flag==0)          //沒有按過符號鍵
  241.         {
  242.          a=a*10;
  243.         write_date(0x30);
  244.          P1=0;
  245.         }
  246.         else if(flag==1)//如果按過符號鍵  
  247. ///////////////////////////////////////////////////
  248.        {
  249.          b=b*10;
  250.          write_date(0x30);
  251.          }
  252.        }
  253.       break;
  254.      case 14:{j=1;
  255.             if(fuhao==1){write_com(0x80+0x4f);//按下等于鍵,光標前進至第二行最后一個顯示處
  256.             write_com(0x04);     //設置從后住前寫數據,每寫完一個數據,光標后退一格
  257.             c=a+b;
  258.             while(c!=0)
  259.             {
  260.                 write_date(0x30+c%10);
  261.               c=c/10;
  262.             }
  263.               write_date(0x3d);     //再寫"="
  264.             a=0;b=0;flag=0;fuhao=0;
  265.             }
  266.         else if(fuhao==2){write_com(0x80+0x4f);   //光標前進至第二行最后一個顯示處
  267.              write_com(0x04);     //設置從后住前寫數據,每寫完一個數據,光標后退一格
  268.                                            //(這個照理說順序不對,可顯示和上段一樣)
  269.             if(a-b>0)
  270.              c=a-b;
  271. ///////////////////////////////////////////////////
  272.          else
  273.                c=b-a;
  274.             while(c!=0)
  275.             {
  276.                 write_date(0x30+c%10);
  277.               c=c/10;
  278.             }
  279.              if(a-b<0)
  280.                write_date(0x2d);
  281.              write_date(0x3d);     //再寫"="
  282.                       a=0;b=0;flag=0;fuhao=0;
  283.           }
  284.        else if(fuhao==3){write_com(0x80+0x4f);
  285.             write_com(0x04);
  286.               c=a*b;
  287.              while(c!=0)
  288.               {
  289.                write_date(0x30+c%10);
  290.              c=c/10;
  291.               }
  292.                write_date(0x3d);
  293.                 a=0;b=0;flag=0;fuhao=0;
  294.               }
  295.        else if(fuhao==4){write_com(0x80+0x4f);
  296. ///////////////////////////////////////////////////
  297.             write_com(0x04);
  298.              i=0;
  299.               c=(long)(((float)a/b)*1000);
  300.              while(c!=0)
  301.              {
  302.                  write_date(0x30+c%10);
  303.                 c=c/10;
  304.             i++;
  305.            if(i==3)
  306.                 write_date(0x2e);
  307.               }
  308.              if(a/b<=0)
  309.               write_date(0x30);
  310.               write_date(0x3d);
  311.                                           a=0;b=0;flag=0;fuhao=0;
  312.                      }
  313.       }
  314.       break;
  315.        case 15:{write_date(0x30+table1[num]);flag=1;fuhao=1;}
  316.      break;
  317.     }
  318. }
  319. }

  320. ///////////////////////////////////////////////////
  321. main()
  322. {
  323. init();
  324. while(1)
  325. {
  326.      keyscan();
  327. }
  328. }
復制代碼

所有資料51hei提供下載:
計算器2.zip (23.68 KB, 下載次數: 57)
HWL0541 發表于 2018-11-20 14:47 | 顯示全部樓層
不錯,學習了,謝謝樓主分享
嘻你還 發表于 2018-12-4 14:40 | 顯示全部樓層
很有用 謝謝樓主
楊楊1694628475 發表于 2018-12-18 20:16 | 顯示全部樓層
謝謝樓主分享
wjxi16 發表于 2018-12-19 00:57 來自手機 | 顯示全部樓層
最近正在做這個,謝謝樓主
wer12 發表于 2019-6-9 16:39 來自手機 | 顯示全部樓層
運行不了,說源程序出錯,,,
shehuikunshao 發表于 2019-7-15 15:01 | 顯示全部樓層
正要用這個 ,謝謝樓主
半夏易水寒 發表于 2019-8-4 21:05 | 顯示全部樓層
wer12 發表于 2019-6-9 16:39
運行不了,說源程序出錯,,,

#include<reg52.h> ?
您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

QQ|手機版|小黑屋|單片機論壇 |51黑電子論壇單片機 聯系QQ:125739409;技術交流QQ群582644647

Powered by 曼联vs曼城

快速回復 曼联vs曼城 返回列表