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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

51單片機C語言程序位置的不對,導致的意外問題

[復制鏈接]
跳轉到指定樓層
樓主
這是個矩陣按鍵,按下任意一個按鍵,數碼管顯示從0-F的值。
單片機C語言源程序如下:
  1. #include<reg52.h>

  2. sbit ADDR0 = P1^0;
  3. sbit ADDR1 = P1^1;
  4. sbit ADDR2 = P1^2;
  5. sbit ADDR3 = P1^3;
  6. sbit ENLED = P1^4;
  7. sbit KeyIn_1 = P2^7;
  8. sbit KeyIn_2 = P2^6;
  9. sbit KeyIn_3 = P2^5;
  10. sbit KeyIn_4 = P2^4;
  11. sbit KeyOut_1 = P2^3;
  12. sbit KeyOut_2 = P2^2;
  13. sbit KeyOut_3 = P2^1;
  14. sbit KeyOut_4 = P2^0;

  15. unsigned char code LedChar[16] = {                                         //數碼管真值表
  16.     0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
  17.                 0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
  18. };

  19. unsigned char keyStatus[4][4] = {                                          //全部矩陣按鍵當前的狀態
  20.     {1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}
  21. };


  22. void main(){
  23.     unsigned char i,j;
  24.     unsigned char cnt = 0;
  25.     unsigned char backUp[4][4] = {{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}}; //按鍵狀態,保存前一次的值

  26.     EA = 1;
  27.     ENLED = 0;
  28.     ADDR3 = 1;
  29.     ADDR2 = 0;
  30.     ADDR1 = 0;
  31.     ADDR0 = 0;
  32.     TMOD = 0x01;
  33.     TH0 = 0xFC;
  34.     TL0 = 0x67;
  35.     ET0 = 1;
  36.     TR0 = 1;
  37.         P0 = LedChar[cnt];
  38.                         
  39.     while(1){
  40.         for(i = 0; i < 4; i++){
  41.             for(j = 0;j < 4; j++){
  42.                 if(backUp[i][j] != keyStatus[i][j]){
  43.                     if(backUp[i][j] == 0){ //按鍵抬起
  44.                     cnt++;
  45.                     if(cnt >= 16){
  46.                         cnt = 0;
  47.                     }
  48.                     P0 = LedChar[cnt];
  49.                     }
  50.                     backUp[i][j] = keyStatus[i][j];
  51.                 }
  52.             }
  53.                 }   
  54.         }
  55. }
  56. /*T0中斷服務函數,判斷按鍵狀態并消抖*/
  57. void interruptTimer0() interrupt 1{
  58.     unsigned char i;
  59.     static unsigned char keyOut = 0;
  60.     static unsigned char keyBuff[4][4] = {
  61.         {0xFF,0xFF,0xFF,0xFF},{0xFF,0xFF,0xFF,0xFF},{0xFF,0xFF,0xFF,0xFF},{0xFF,0xFF,0xFF,0xFF}          //矩陣按鍵掃描緩沖區
  62.     };  

  63.     TH0 = 0xFC;
  64.     TL0 = 0x67;
  65.     keyBuff[keyOut][0] = (keyBuff[keyOut][0] << 1) | KeyIn_1;  //按位與,將KeyIn_1的最后一位移入緩沖區。按位與的結果:最后1位是0就移入0,是1就移入1。
  66.     keyBuff[keyOut][1] = (keyBuff[keyOut][1] << 1) | KeyIn_2;  //按位與,將KeyIn_2的最后一位移入緩沖區。按位與的結果:最后1位是0就移入0,是1就移入1。
  67.     keyBuff[keyOut][2] = (keyBuff[keyOut][2] << 1) | KeyIn_3;  //按位與,將KeyIn_3的最后一位移入緩沖區。按位與的結果:最后1位是0就移入0,是1就移入1。
  68.     keyBuff[keyOut][3] = (keyBuff[keyOut][3] << 1) | KeyIn_4;  //按位與,將KeyIn_4的最后一位移入緩沖區。按位與的結果:最后1位是0就移入0,是1就移入1。
  69.     //更新消抖狀態
  70.     for(i = 0; i <= 3 ; i++){
  71.         if((keyBuff[keyOut][i] & 0x0F) == 0x00){
  72.             keyStatus[keyOut][i] = 0;
  73.         }
  74.         else if((keyBuff[keyOut][i] & 0x0F) == 0x0F){
  75.             keyStatus[keyOut][i] = 1;
  76.         }
  77.     }
  78.     //執行下一次的掃描輸出
  79.     keyOut++;
  80.     if(keyOut > 4){
  81.         keyOut = 0;
  82.     }
  83.     //根據索引keyOut,釋放當前輸出引腳,拉低下次的輸出引腳。
  84.     switch(keyOut){
  85.         case 0: KeyOut_4 = 1; KeyOut_1 = 0; break;
  86.         case 1: KeyOut_1 = 1; KeyOut_2 = 0; break;
  87.         case 2: KeyOut_2 = 1; KeyOut_3 = 0; break;
  88.         case 3: KeyOut_3 = 1; KeyOut_4 = 0; break;
  89.         default: break;
  90.     }

  91. }
復制代碼


問題:其中這段代碼放在switch的前面,有一排按鍵按下,數碼管就一直在累加。
雖然keyOut初始值為0,++一次為1,錯過了keyOut為0的判斷,但是KeyOut加到4的時候,就置0了,下一輪,case0就可以覆蓋的到。

  1. //執行下一次的掃描輸出
  2. keyOut++;
  3. if(keyOut > 4){
  4. keyOut = 0;
  5. }
復制代碼

這段代碼放到switch后就ok了,但是邏輯上我 實在不明白為什么放在前面就不可以。求各位大神給指點一下,答疑解惑!


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

使用道具 舉報

沙發
ID:1034164 發表于 2022-6-12 19:17 | 只看該作者
為了方便格式化 閱讀,我生成了代碼的圖片

回復

使用道具 舉報

板凳
ID:213173 發表于 2022-6-13 06:05 | 只看該作者
xcopter 發表于 2022-6-12 19:17
為了方便格式化 閱讀,我生成了代碼的圖片

發生錯誤的根本原因是代碼錯誤,改變代碼位置只是改變發生錯誤的矩陣行。
錯誤:if(keyOut > 4)
正確:if(keyOut >= 4) 或 if(keyOut > 3)
回復

使用道具 舉報

地板
ID:688692 發表于 2022-6-13 09:02 | 只看該作者
轉成就成圖看看

回復

使用道具 舉報

5#
ID:979299 發表于 2022-6-13 11:54 | 只看該作者
條件表達式語句,動作里面沒有包括switchy語句,放到前后都沒有作用。
這個格式是java語言寫法吧
| 這個管道符在這里是按位或啊
回復

使用道具 舉報

6#
ID:275826 發表于 2022-6-13 15:53 | 只看該作者
這個程序代碼長,內存大,不好
回復

使用道具 舉報

7#
ID:428114 發表于 2022-6-13 17:52 | 只看該作者
// 執行下一次的掃描輸出
        keyOut++;
        
       if(keyOut > 4)
       {
            keyOut = 0;
        }
=======================
這個是要給下一次掃描處理的吧?


    switch(keyOut)
   {
    ....
   }
====================
這個switch處理的是keyOut當前值


要先處理當前的,然后再考慮下一個,邏輯要清楚啊
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 羞羞午夜 | 久久精品视频在线观看 | 亚洲狠狠爱 | 国产激情视频在线观看 | 婷婷去俺也去 | 国产亚洲一区二区三区在线观看 | 精品国产一区二区三区久久久蜜月 | 91久久精品一区二区二区 | 99国产视频 | 国产精品99一区二区 | www亚洲精品 | 成在线人视频免费视频 | 成人免费视频在线观看 | 久久精品成人 | 精品免费视频 | 免费在线观看一区二区 | 成人午夜激情 | 黑人精品欧美一区二区蜜桃 | 久久久久久久久久久久久9999 | 国产在线资源 | 免费毛片网站在线观看 | 欧美国产日韩一区二区三区 | 欧美国产亚洲一区二区 | 青娱乐av| 毛色毛片免费看 | 免费观看黄网站 | 日韩精品1区2区3区 爱爱综合网 | 日韩视频在线免费观看 | 日韩三级在线观看 | 97超碰人人 | 91在线看 | 国产欧美日韩 | 99久久婷婷| 国产一区二区三区网站 | www免费视频| 久久精品二区亚洲w码 | 在线中文字幕av | 中文字幕日韩欧美 | 黄色毛片免费看 | 在线观看中文字幕 | 免费观看的黄色网址 |