• 專注電子技術學習與研究
    當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

    單片機鍵盤c程序

    作者:佚名   來源:本站原創   點擊數:  更新時間:2008年08月29日   【字體:

    void int1proc() interrupt IE1_VECTOR using 1
    {
    unsigned char i, key;
    code unsigned char PS2TAB[] = {//20鍵PS2小鍵盤鍵碼表
      0x70,//0
      0x69,//1
      0x72,//2
      0x7a,//3
      0x6b,//4
      0x73,//5
      0x74,//6
      0x6c,//7
      0x75,//8
      0x7d,//9
      0x05,//F1
      0x06,//F2
      0x04,//F3
      0x0c,//F4
      0x03,//F5
      0x0b,//F6
      0x5a,//Enter
      0x76,//Esc
      0x66,//Bksp
      0x71//KP.
      };
      if (PS2Buffers.PS2KeyCount == 0){//PS2起始位測試
        if (!PS2CLOCK && !PS2DATA){//低電平是起始位
          if (PS2Buffers.PS2KeyExtFlage != 0xf0){
            PS2Buffers.PS2KeyTemp = 0;
            PS2Buffers.PS2KeyExtFlage = 0;
            PS2Buffers.PS2KeyPopError = 0;
          }
          PS2Buffers.PS2KeyCount ++;//脈沖計數
        }
        else PS2Buffers.PS2KeyPopError = 0xeb;//置鍵起始位錯誤號0xeb
      }
      else if (PS2Buffers.PS2KeyCount < 9){//PS2數據位
        key = PS2Buffers.PS2KeyTemp;//取鍵盤緩沖區移位數據
        key >>= 1;
        if (PS2DATA) key = 0x80;
        PS2Buffers.PS2KeyTemp = key;
        PS2Buffers.PS2KeyCount++;//脈沖計數
      }
      else if (PS2Buffers.PS2KeyCount == 9){//PS2數據奇校驗
        ACC = PS2Buffers.PS2KeyTemp;//取鍵盤緩沖區移位數據(C51取偶校驗位)
        if (P != PS2DATA) PS2Buffers.PS2KeyCount ++;//脈沖計數
        else{
          PS2Buffers.PS2KeyPopError = 0xec;////置鍵奇校驗位錯誤號0xec
          PS2Buffers.PS2KeyCount = 0;//脈沖計數歸零
        }
      }
      else if (PS2Buffers.PS2KeyCount == 10){//停止位
        key = PS2Buffers.PS2KeyTemp;//取鍵盤緩沖區移位數據
        PS2Buffers.PS2KeyCount = 0;//脈沖計數歸零
        if (PS2DATA){//高電平是停止位
          if (key == 0xe0){//本次是擴展鍵
            PS2Buffers.PS2KeyExtFlage = 0xe0;//置擴展鍵標志(小鍵盤只有回車鍵)
          }
          else if (key == 0xf0){//本次是鍵斷碼,鍵釋放
            PS2Buffers.PS2KeyExtFlage = 0xf0;//置鍵釋放標志
          }
          else{//本次必為鍵值
            if ((key == 0xaa) (key == 0xfa)) PS2Buffers.PS2KeyPushCount = 0;//長
    壓鍵計數器清零
            else{
                PS2CLOCK = 0;//阻止PS2鍵盤立即回送數據
              PS2Buffers.PS2KeyPopError = 0xaa;//出錯碼
              for (i = 0; i < 20; i++){
                if (key == (PS2TAB[i])){//搜索
                  key = i + 1;
                  if (PS2Buffers.PS2KeyExtFlage == 0xf0){
                    key = 0x80;//鍵釋放
                    PS2Buffers.PS2KeyPushCount = 0;//長壓鍵計數器清零
                    PS2Buffers.PS2KeyMessage = key;//存入當前鍵值并執行命令
                  }
                  else{
                    if (key != PS2Buffers.PS2KeyVal){//換了一個鍵
                      PS2Buffers.PS2KeyPushCount = 0;//長壓鍵計數器清零
                      PS2Buffers.PS2KeyMessage = key;//存入當前鍵值并執行命令
                    }
                    else{//未換鍵
                      PS2Buffers.PS2KeyPushCount ++;//長壓鍵計數器計數
                      if (PS2Buffers.PS2KeyPushCount > DEFPS2PUSHCOUNT){//長壓時間到
                        PS2Buffers.PS2KeyMessage = key 0x40;//存入當前鍵值并執行命

                        PS2Buffers.PS2KeyPushCount = 0;//長壓鍵計數器清零
                      }
                    }
                  }
                  PS2Buffers.PS2KeyVal = key;//存入當前鍵值值1~20或0x80+(1~20)
                  PS2Buffers.PS2KeyTemp = 0;//鍵碼移位記錄器
                  PS2Buffers.PS2KeyExtFlage = 0;//擴展鍵標志
                  PS2Buffers.PS2KeyPopError = 0;//鍵釋放標志或出錯碼
                  break;
                }
              }
              if (PS2Buffers.PS2KeyPopError) PS2Buffers.PS2KeyPushCount = 0;//長壓鍵
    計數器清零
              PS2CLOCK = 1;//釋放PS2時鐘總線
            }
          }
        }
        else PS2Buffers.PS2KeyPopError = 0xed;//置停止位錯誤號0xed
      }
      else PS2Buffers.PS2KeyCount = 0;//PS2鍵盤出錯
    }
    /*------------------------------------------------------------------
             利用函數指針數組運行PS2鍵盤散轉命令
    -------------------------------------------------------------------*/
    void PS2CommandExec(unsigned char key)
    {
    unsigned int i;
    code void *funcpushbuffers[] = {//命令散轉表(匯編中的16個DW)
    /*------------------------------------------------------------------
            鍵盤c程序15個壓鍵、放鍵及長壓鍵事件處理函數指針地址
    -------------------------------------------------------------------*/
      (void *)ClrWdt            + 0x0000,
    /*---------------------------------------------
               10個功能鍵壓鍵事件處理(獨立管理)
    ----------------------------------------------*/
      (void *)PS2F1KeyPush      + 0x5b7d,      //功能鍵F1壓鍵事件處理
      (void *)PS2F2KeyPush      + 0xa6ea,      //功能鍵F2壓鍵事件處理
      (void *)PS2F3KeyPush      + 0xf157,      //功能鍵F3壓鍵事件處理
      (void *)PS2F4KeyPush      + 0x4cc4,      //功能鍵F4壓鍵事件處理
      (void *)PS2F5KeyPush      + 0x9731,      //功能鍵F5壓鍵事件處理
      (void *)PS2F6KeyPush      + 0xe2ae,      //功能鍵F6壓鍵事件處理
      (void *)PS2EnterKeyPush   + 0x3d1b,      //功能鍵Enter壓鍵事件處理
      (void *)PS2EscKeyPush     + 0x8888,      //功能鍵Esc壓鍵事件處理
      (void *)PS2BkspKeyPush    + 0xd3f5,      //功能鍵Bksp壓鍵事件處理
      (void *)PS2KpKeyPush      + 0x2e62,      //功能鍵Kp壓鍵事件處理
    /*---------------------------------------------
               2個放鍵事件處理(集中管理)
    ----------------------------------------------*/
      (void *)PS2NumberKeyPop   + 0x79df,      //數字鍵放鍵事件處理
      (void *)PS2FuncKeyPop     + 0xc44c,      //功能鍵放鍵事件處理
    /*---------------------------------------------
               2個長壓鍵事件處理(集中管理)
    ----------------------------------------------*/
      (void *)PS2NumberKeyPushL + 0x1fb9,      //數字鍵長壓鍵事件處理
      (void *)PS2FuncKeyPushL   + 0x6a26,      //功能鍵長壓鍵事件處理
    /*---------------------------------------------
               1個數字鍵壓鍵事件處理(集中管理)
    ----------------------------------------------*/
      (void *)PS2NumberKeyPush  + 0xb593       //數字鍵0~9壓鍵事件處理
      };
    /*--------------------------------------------*/
      i = key;
      key &= 0x3f;//去掉鍵釋放及長壓鍵標志,取真鍵碼
      key --;
      if (key < 20){//只有20個鍵
        if (key < 10){//數字鍵0~9
          if (i <= 10) key = 15;//(散轉號0)壓數字鍵0~9
          else{
            if (i & 0x80) key = 11;//(散轉號11)放數字鍵0~9
            else key = 13;//(散轉號13)長壓數字鍵0~9
          }
        }
        else{//壓功能鍵F1~F6,Enter..KP
          if ((i & 0xc0) == 0) key -= 9;//(散轉號1~10)壓功能鍵F1~F6,Enter..KP
          else{
            if (i & 0x80) key = 12;//(散轉號12)放功能鍵
            else key = 14;//(散轉號14)長壓功能鍵
          }
        }
        ClrWdt();//喂狗(鬼知道鍵盤程序要運行多久,就替它先喂一次吧)
        i = ((key * 53 & 0xf) * 0x1000)+ ((key * 43 & 0xf) * 0x100) + ((key * 23 &
    0xf) * 0x10) + (key * 13 & 0xf);
        _icall_((void *)funcpushbuffers[key] - i);//取鍵盤散轉表并執行鍵盤命令
      }
    }
    這個鍵盤程序與一般網上的有很大區別,它充分利用了外部中斷(0字)hotpower[1次]

    ****下面是一個不版本的單片機鍵盤c程序歡迎廣大讀者實驗http://www.userform1.com 編制********************************

    unsigned CHAR key,key_h,kpush;
    unsigned int key_l;

    //按鍵連接到p1.0、p1.1、p1.2

    void int_t0(void) interrupt 1 {
        unsigned CHAR dd,i;
        TL0=TL0+30;TH0=0xfb;    //800
        /*    按鍵判別    */
        if ((P1&0x7)==0x7) {
            if ((key_l>30)&&(key_l<800)&&(key_h>30)) {        //釋放按鍵,如果之前按鍵時間少于1秒,讀入鍵值
                key=kpush;
            }
            if ((++key_h)>200) key_h=200;
            key_l=0;
            if (key>=0x80) key=0;                            //如果之前的按鍵為長按1秒,清除鍵值
        } else {
            kpush=P1&0x7;
            key_l++;
            if ((key_l>800)&&(key_h>30)) {                    //如果按鍵超過1秒,鍵值加0x80標志長按鍵
                key=kpush|0x80;
                key_h=0;
                key_l=0;
            }
        }
    }
    void main(void) {
        TMOD=0x1;TR0=1;ET0=1;EA=1;
        while (1) {
            while (!key) {}
            SWITCH (key) {
            case 1:break;
            case 2:break;
            }
        }
    }

     

    關閉窗口
    国产农村精品一级毛片视频_亚洲Av无码专区国产乱码在线观看_亚洲综合国产Av_天天影视网天天综合色