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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

單片機行列式按鍵及計算器仿真及程序 顯示錯誤 求幫助

[復制鏈接]
跳轉到指定樓層
樓主
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)


行列式按鍵及計算器仿真及程序程序如下
  1. #include"at89x51.h"     //  C計時器參考
  2.                                                                                                                                                          
  3. unsigned int  da1=0, da2=0, resu=0;
  4. unsigned char fh=0, zhuangtai=0, key, keyzhi, jianzhi;
  5. unsigned char code  tv[]={0xfe,0xfd,0xfb,0xf7};        //位選數組
  6. unsigned char code  a[]={0x3f,0x06,0x5b,0x4f,
  7.                      0x66,0x6d,0x7d,0x07,0x7f,
  8.                      0x6f,0x77,0x7c,0x39,0x5e,
  9.                                  0x79,0x71,0x00};                 //顯示是P0口的值對應的數組
  10. unsigned char data led[4] = {0, 16, 16, 16}; //將首位定義成零,在計算器的初始顯示的時候右邊有‘0’表示計算器已經開始工作

  11. //函數名:delay                        時間:
  12. //作用:在顯示函數中延時
  13. //說明:延時的時間不用太長即i的峰值不要定太大
  14. //作者:ymx                                

  15. void delay()
  16. {
  17.         unsigned char i;
  18.         for (i=0; i<200; i++)
  19.         {
  20.                 ;
  21.         }
  22. }


  23. //函數名:keydeal                        時間:
  24. //作用:掃描鍵盤,通過低電位會將高電位拉成低電位的原理,分別判斷出按鍵的橫縱坐標并將jianzhi傳遞到jianhao函數
  25. //說明:傳遞0x0f判斷縱坐標,傳遞0xf0判斷橫坐標
  26. //作者:ymx

  27. unsigned char keydeal()
  28. {
  29.         unsigned char x, y;
  30.         P3 = 0xff;
  31.         P3 = 0x0f;
  32.         x = P3;
  33.         P3 = 0xff;
  34.         P3 = 0xf0;
  35.         y = P3;
  36.         jianzhi = x + y;
  37.         return jianzhi;
  38. }

  39. //函數名:jisuan                        時間:
  40. //作用:根據記錄的運算符號和兩個數的值計算出結果
  41. //說明:
  42. //作者:ymx

  43.     jisuan(void)
  44. {
  45.         switch(fh)
  46.         {
  47.                 case '+':
  48.                         resu = da1+da2;
  49.                         break;
  50.                 case '-':
  51.                         resu = da1-da2;
  52.                         break;
  53.                 case '*':
  54.                         resu = da1*da2;
  55.                         break;
  56.                 case '/':
  57.                         resu = da1/da2;
  58.                         break;
  59.         }
  60.             fh=0;   //將符號清零
  61. }

  62. //函數名:jianhao                        時間:
  63. //作用:通過keydeal傳遞的數值判斷按下的按鍵分別代表的意義,如數字,運算符號等。并根據按鍵和按下鍵盤前的狀態來切換此時的狀態
  64. //說明:                                                                                                                                                                  
  65. //作者:ymx

  66. void jianhao()
  67. {
  68.         key = keydeal();
  69.         switch(key)
  70.         {
  71.                   case 0xff: keyzhi=16; break; //什么鍵都沒有按下
  72.               case 0xd7: keyzhi=0; break;
  73.                   case 0xeb: keyzhi=1; break;
  74.                   case 0xdb: keyzhi=2; break;
  75.                   case 0xbb: keyzhi=3; break;
  76.                   case 0xed: keyzhi=4; break;
  77.                   case 0xdd: keyzhi=5; break;
  78.                   case 0xbd: keyzhi=6; break;
  79.                   case 0xee: keyzhi=7; break;
  80.                   case 0xde: keyzhi=8; break;
  81.                   case 0xbe: keyzhi=9; break;

  82.                   case 0xe7:
  83.                   keyzhi=10; da1=0; da2=0; fh=0; resu=0; zhuangtai=0;
  84.                   led[1]=led[2]=led[3]=16; led[0]=0;break; //按下no鍵時將所有的值與狀態復位,顯示清零
  85.                   case 0xb7: keyzhi=11; zhuangtai=3; break; //按下等號鍵將狀態換為3

  86.           case 0x77: keyzhi=12; break;
  87.                   case 0x7b: keyzhi=13; break;
  88.                   case 0x7d: keyzhi=14; break;
  89.                   case 0x7e: keyzhi=15; break;
  90.         }

  91.         //如果按下的鍵在0~9的時候
  92.         if (keyzhi<10)
  93.         {
  94.                 if(zhuangtai==1)//如果前一狀態為1。表示完成運算符號的記錄,應當記錄第二個數。狀態切換為2
  95.                 {
  96.                         zhuangtai=2;
  97.                 }
  98.                 else if(zhuangtai==3) //如果前一狀態為3,表示已經進行過一次運算并且得出了結果。此時將結果和原有數據清零進行新的運算。狀態切換為0.
  99.                 {
  100.                         da1=da2=resu=0;
  101.                         zhuangtai=0;
  102.                 }
  103.         }

  104.         //如果按下的鍵在12~15的時候
  105.         if (keyzhi>11 && keyzhi<16)
  106.         {
  107.                 if (zhuangtai==0) //如果前一狀態為0,表示記錄好第一個數,此時應當記錄運算符號。狀態切換為1
  108.                 {                                                   
  109.                         zhuangtai=1;
  110.                 }
  111.                 else if(zhuangtai==3)//如果前一狀態為3,即表示按下運算符號表示要利用原有結果進行運算。將結果值賦給da1并將
  112.                 {
  113.                         da1=resu;                 //并將結果值賦給da1,resu和da2清零。否則原有的值會影響第二次的運算結果。并將狀態切換為1,記錄下運算符號。
  114.                         da2=resu=0;
  115.                         zhuangtai=1;
  116.                 }
  117.                 else if(zhuangtai==2)//如果前一狀態為2,即表示已經完成了da1和運算符和da2的記錄。現在不按下等號進行連續運算(如1+2+3)。
  118.                 {                                         
  119.                         jisuan();   //先計算出前面兩個數的結果
  120.                         da1=resu;   //將結果賦給da1
  121.                         da2=0;            //結果和da2清零,并且將狀態切換為1
  122.                         resu=0;
  123.                         zhuangtai=1;
  124.                 }
  125.         }
  126. }

  127. //函數名:ysf                        時間:
  128. //作用:記錄下在狀態1時所按下的運算符號
  129. //說明:
  130. //作者:ymx

  131. void ysf()
  132. {
  133.         switch(keyzhi)
  134.         {
  135.                 case 12:
  136.                         fh='+';
  137.                         break;
  138.                 case 13:
  139.                         fh='-';
  140.                         break;
  141.                 case 14:
  142.                         fh='*';
  143.                         break;
  144.                 case 15:
  145.                         fh='/';
  146.                         break;
  147.                 default:
  148.                         break;
  149.         }
  150.         
  151. }



  152. void move()
  153. {
  154.         unsigned int  linshi=0;
  155.         linshi = keyzhi;  //保存下按下的數值
  156.          while(keyzhi != 16)
  157.         {
  158.                  jianhao();
  159.         }
  160.         if(led[0]==0&&led[1]==16&&led[2]==16&&led[3]==16&&linshi!=16) //if里的條件表示初始的只是0的時候
  161.         {
  162.                 led[0]=linshi;  //移位時要將原有的0替換掉否則數顯示的數的前面都會有一個零如:0123
  163.         }
  164.         else
  165.         {
  166.                 if(linshi!=16)  //如果按下了鍵才開始移位,否則會有空白
  167.                 {
  168.                         led[3] = led[2];
  169.                         led[2] = led[1];
  170.                         led[1] = led[0];
  171.                         led[0] = linshi;
  172.                 }
  173.         }               
  174.         if(zhuangtai==0) //狀態為0時記錄第一個數
  175.         {                                
  176.                 da1=da1*10+linshi;
  177.         }
  178.         if(zhuangtai==2) //狀態為2時記錄第二個數
  179.         {
  180.                 da2=da2*10+linshi;
  181.         }

  182. }


  183. //函數名:jieguo                        時間:
  184. //作用:將結果轉化為可以顯示的形式
  185. //說明:
  186. //作者:ymx

  187. void jieguo()  //計算出的結果是        一個整型的書,數碼管并不能直接顯示,需要把它替換成單個的數賦給顯示的led數組
  188. {                                
  189.         if(resu<10000) //如果顯示的結果小于5位才顯示
  190.         {
  191.                 if (resu>999)
  192.                 {
  193.                         led[3]=resu/1000; //記錄下千位的值
  194.                 }
  195.                 else
  196.                 {
  197.                         led[3]=16;
  198.                 }
  199.                 if(resu>99)
  200.                 {
  201.                         led[2]=(resu/100)%10;  //記錄下百位的值
  202.                 }
  203.                 else
  204.                 {
  205.                         led[2]=        16;
  206.                 }
  207.                 if(resu>9)
  208.                 {
  209.                         led[1]=(resu/10)%10;
  210.                 }
  211.                 else
  212.                 {
  213.                         led[1]=16;
  214.                 }
  215.                 if(resu>0)
  216.                 {
  217.                         led[0]=resu%10;
  218.                 }
  219.                 else
  220.                 {
  221.                         led[0]=0;
  222.                 }
  223.         }
  224.         else        //如果不是小于5位的話,則顯示‘E’表示錯誤
  225.         {
  226.                 led[0]=14;
  227.         }
  228. }


  229. //函數名:xianshi                        時間:
  230. //作用:位選和顯示不同的數時所對應的P0口的電位值
  231. //說明:
  232. //作者:ymx

  233. void xianshi()
  234. {
  235.         unsigned char i, k;
  236.          for (i=0; i<4; i++)
  237.         {
  238.                 k = led[i];
  239.                 P0 = a[k];
  240.                 P2 = tv[3-i];
  241.                 delay();
  242.         }
  243. }

  244. //函數名:main                        時間:
  245. //作用:完成整個程序的循環
  246. //說明:main函數中除了記錄數值得兩個狀態之外剩下的的狀態里的jianhao函數均是用于切換狀態和復位用的
  247. // zhuangtai=0表示記錄第一個數,1表示記錄運算符號,2表示記錄第二個數,3表示計算結果并顯示
  248. //作者:ymx
  249.                                 
  250. void main(void)
  251. {                                 
  252.         while(1)
  253.         {
  254.                 while(zhuangtai==0)
  255.                 {
  256.                         resu=0;
  257.                         jianhao();
  258.                         if(keyzhi<=9)//判斷是按下的是否是數,是得話才移位和顯示數值否則顯示不變。下面狀態2同
  259.                         {
  260.                                 move();
  261.                         }
  262.                                 xianshi();
  263.                                 resu=0;
  264.                 }
  265.                 while(zhuangtai==1)
  266.                 {
  267.                         led[0]=led[1]=led[2]=led[3]=16;//將顯示清零
  268.                         jianhao();                                       
  269.                         ysf(); //記錄下運算符號
  270.                 }
  271.                 while(zhuangtai==2)
  272.                 {         
  273.                         resu=0;
  274.                         jianhao();
  275.                         if(keyzhi<=9)
  276.                         {
  277.                                 move();
  278.                         }
  279.                                 xianshi();
  280.                 }
  281.                 while(zhuangtai==3)
  282.                 {
  283.                         jianhao();
  284.                         jisuan();
  285.                         jieguo();
  286.                         xianshi();
  287.                 }
  288.         }
  289. }
復制代碼

全部資料51hei下載地址:
行列式按鍵及計算器.rar (46.07 KB, 下載次數: 9)

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

使用道具 舉報

沙發
ID:332444 發表于 2020-10-12 08:30 | 只看該作者
掃描鍵盤如果不用消抖和檢測釋放大部分會有問題
回復

使用道具 舉報

板凳
ID:332444 發表于 2020-10-12 08:31 | 只看該作者
回復

使用道具 舉報

地板
ID:276663 發表于 2020-10-12 08:51 | 只看該作者
授予魚不如授予漁,你先單獨顯示,然后加入按鍵。
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美精品久久久久 | 亚洲精品久久久9婷婷中文字幕 | 亚洲精色 | 国产精品久久毛片av大全日韩 | 日韩精品激情 | 国产成人自拍av | 天天综合成人网 | 在线成人福利 | 99国产精品久久久久老师 | 日韩在线欧美 | 亚洲一区二区日韩 | 国产成人在线视频 | 国产一区 | 99精品欧美一区二区蜜桃免费 | 九九热在线精品视频 | 国产精品久久777777 | 欧美日韩高清免费 | 日韩一区二区福利视频 | 国产人成精品一区二区三 | 欧美日韩在线观看视频网站 | 人人叉 | 成人av电影在线观看 | 中文字幕在线国产 | 99久久免费精品视频 | 伊大人久久 | 久久人人网 | 久久aⅴ乱码一区二区三区 亚洲国产成人精品久久久国产成人一区 | 日本免费小视频 | 亚洲精品免费视频 | 欧美日韩一 | 91在线看片 | 欧美日韩国产精品 | 亚洲精品一区二区网址 | 美女逼网站 | 逼逼网| 亚洲一区二区三区四区av | 免费成人av网站 | 成人三级在线观看 | 黄色毛片在线播放 | 欧美a级成人淫片免费看 | 波多野结衣中文视频 |