色婷婷AⅤ一区二区三区|亚洲精品第一国产综合亚AV|久久精品官方网视频|日本28视频香蕉

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應用 > 單片機矩陣按鍵定時器消抖程序源碼

          單片機矩陣按鍵定時器消抖程序源碼

          作者: 時間:2016-12-02 來源:網(wǎng)絡 收藏

          uchar key = 0;

          //16個按鍵初始化1
          uchar keysta[4][4] =
          {
          {1, 1, 1, 1}, //K1 - K4
          {1, 1, 1, 1}, //K5 - K8
          {1, 1, 1, 1}, //K9 - K 12
          {1, 1, 1, 1} //K13 - K16
          };

          //16個按鍵的備份值初始值1
          uchar keybackup[4][4] = {
          {1, 1, 1, 1},
          {1, 1, 1, 1},
          {1, 1, 1, 1},
          {1, 1, 1, 1}
          };

          void keymatrixScan();
          void timer0_init();
          void refresh();
          void HC138_init();

          void main()
          {
          timer0_init();
          HC138_init();

          while (1)
          {
          keymatrixScan();
          }
          }

          /********timer0 init*************/
          void timer0_init()
          {
          TMOD |= 0x01;
          TMOD &= 0xF1; //1111 0001,配置T0方式1
          TH0 = 0xFC;
          TL0 = 0x67;//1ms
          TR0 = 1;//start T0
          EA = 1; //open main int
          ET0 = 1;//open T0 int
          }

          /***********HC138 init*********/
          void HC138_init()
          {
          ADDR3 = 1;
          ENLED = 0;//使能U3
          }

          /***********刷新數(shù)碼管************/
          void refresh()
          {
          static uchar j = 0;//刷新數(shù)碼管
          P0 = 0xFF;//消隱
          switch(j)
          {
          case 0: ADDR2 = 0; ADDR1 = 0; ADDR0 = 0;
          break;
          case 1: ADDR2 = 0; ADDR1 = 0; ADDR0 = 1;
          break;
          case 2: ADDR2 = 0; ADDR1 = 1; ADDR0 = 0;
          break;
          case 3: ADDR2 = 0; ADDR1 = 1; ADDR0 = 1;
          break;
          case 4: ADDR2 = 1; ADDR1 = 0; ADDR0 = 0;
          break;
          case 5: ADDR2 = 1; ADDR1 = 0; ADDR0 = 1;
          break;
          default:
          break;
          }
          P0 = table[key]; //在此處送入顯示的數(shù)據(jù),很正常的顯示出來,當放到while(1)中時會出現(xiàn)抖動
          j++;
          if (j >= 6)
          {
          j = 0;
          }
          }

          /**********矩陣按鍵檢測***********/
          void keymatrixScan()
          {
          //16個按鍵檢測
          uchar i = 0, j = 0;
          for (i = 0; i < 4; i++) //4行
          {
          for (j = 0; j < 4; j++) //4列
          {
          if (keysta[j] != keybackup[j]) //檢測第i行第j列按鍵是否有動作
          {
          if (keybackup[j] == 0) //若第i行第j列的按鍵的前一個狀態(tài)為0,則由0-1,即按鍵彈起
          {
          key = i * 4 + j;//按鍵定位
          }
          //備份當前按鍵的值,以備下一次比較
          keybackup[j] = keysta[j];
          }
          }
          }
          }

          /**********timer0 int****************/
          void timer0_int() interrupt 1 using 3
          {
          static uchar keybuf[4][4] = {
          {0xFF, 0xFF, 0xFF, 0xFF},
          {0xFF, 0xFF, 0xFF, 0xFF},
          {0xFF, 0xFF, 0xFF, 0xFF},
          {0xFF, 0xFF, 0xFF, 0xFF}
          };//16個按鍵的掃描緩沖區(qū)
          static uchar keyout = 0;//按鍵的列,即KeyOut1 - KeyOut4
          uchar i = 0;
          TH0 = 0xFC;
          TL0 = 0x67; //1ms

          refresh();

          //掃描第keyout列的按鍵的值
          keybuf[keyout][0] = (keybuf[keyout][0] << 1) | KeyIn1;//將按鍵1的掃描值存入keybuf中
          keybuf[keyout][1] = (keybuf[keyout][1] << 1) | KeyIn2;
          keybuf[keyout][2] = (keybuf[keyout][2] << 1) | KeyIn3;
          keybuf[keyout][3] = (keybuf[keyout][3] << 1) | KeyIn4; //每1ms掃描一列,4ms掃描四列,共掃描四位,設(shè)定掃描16ms,即每個按鍵掃描4次

          //更新消抖后按鍵的值
          for (i = 0; i < 4; i++) //4行, 一列4個按鍵
          {
          if ((keybuf[keyout] & 0x0F) == 0x00) //按鍵的緩沖區(qū)的低四位都是0,因為16ms只掃描了4次,移入了四位狀態(tài)值
          {
          keysta[keyout] = 0;//按鍵按下
          }
          else if ((keybuf[keyout] & 0x0F) == 0x0F) //按鍵的緩沖區(qū)的第四位都是1
          {
          keysta[keyout] = 1;//第keyout列第i行的按鍵彈起
          }
          }

          //列++
          keyout++;
          //keyout 0-3
          /*if (keyout >= 4)
          keyout = 0;
          */
          keyout &= 0x03;//當keyout到4則會等于3
          //通過keyout列數(shù)選中列
          switch(keyout)
          {
          case 0: KeyOut1 = 0; KeyOut4 = 1; KeyOut2 = 1; KeyOut3 = 1; //選中第一列,開發(fā)板上的第一行
          break;
          case 1: KeyOut2 = 0; KeyOut1 = 1; KeyOut3 = 1; KeyOut4 = 1;
          break;
          case 2: KeyOut3 = 0; KeyOut1 = 1; KeyOut2 = 1; KeyOut4 = 1;
          break;
          case 3: KeyOut4 = 0; KeyOut1 = 1; KeyOut2 = 1; KeyOut3 = 1;
          break;
          default:
          break;
          }
          }


          上一頁 1 2 下一頁

          評論


          技術(shù)專區(qū)

          關(guān)閉