新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 帶緩存中斷響應的4*4鍵盤函數

        帶緩存中斷響應的4*4鍵盤函數

        作者: 時間:2016-11-13 來源:網絡 收藏
        #include "key.h"

        #include "scom.h"

        本文引用地址:http://www.104case.com/article/201611/316505.htm

        unsigned char KeyNum[8]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; //鍵值緩存
        unsigned char KeyCntWr;//寫鍵值計數器
        unsigned char KeyCntRd; //讀鍵值計數器
        //unsigned char KeyNum;

        void KeyInit(void)
        {
        P1DIR=0Xf0;
        P1REN=0X0f; //使能上拉
        P1OUT=0X0f;

        P1IFG=0x00;
        P1IE=0X0f; //中斷使能
        P1IES=0X0f; //列線下降沿允許P1中斷
        }

        void key_delay(Word _us)
        {
        while(_us--);
        }
        //行號譯碼
        unsigned char coding(unsigned char n) //譯碼
        {
        switch(n)
        {
        case 0x0e: return 3; //輸入為 11111110 即為行號3
        case 0x0d: return 2; //輸入為 11111101 即為行號2
        case 0x0b: return 1; //輸入為 11111011 即為行號1
        case 0x07: return 0; //輸入為 11110111 即為行號0
        default :return 0xf0;
        }
        }

        //獲取健值
        unsigned char key(void)
        {
        char temp,shift,keyname,a;
        temp=0x10;
        keyname=0xff;

        for(shift=0;shift<4;shift++)
        {
        P1OUT=temp^0xff;//高四位輸出11101111 、11011111、101111111、011111111、11111111
        temp<<=1;
        a=P1IN&0x0f;
        if(a!=0x0f) //低四位輸入,如果檢測到端口值不為高電平,說明此列有按鍵摁下
        keyname=coding(a)+shift*4; //健值=行號+例號*4
        }
        return keyname;
        }

        //檢測有無鍵值按下
        unsigned char keyj(void)
        {
        unsigned char x;
        x=(P1IN&0X0f); // P1.0--P1.3為列線,輸入,P1.4——P1.7為行線,出輸
        return(x); // 無按鍵,返回 0x0f; 有按鍵返回 非0x0f
        }

        //以查詢方式獲取鍵值,且譯碼。
        unsigned char GetKey(void)
        {
        unsigned char key_value=0xff;

        if(KeyCntRd!=KeyCntWr) //相等鍵盤緩存區無鍵值
        {
        switch(KeyNum[KeyCntRd])
        {
        case 0x00:key_value=0x0a; break;//dot
        case 0x01:key_value=0x06; break; //six
        case 0x02:key_value=0x07; break; //seven
        case 0x03:key_value=0x08; break; //eight
        case 0x04:key_value=0x09; break; //nine
        case 0x05:key_value=0x00; break; //zero
        case 0x06:key_value=0x0b; break; //Down
        case 0x07:key_value=0x0c; break; //Enter

        case 0x08:key_value=0x0d; break; //Esc
        case 0x09:key_value=0x01; break; //one
        case 0x0a:key_value=0x02; break; //two
        case 0x0b:key_value=0x03; break; //three
        case 0x0c:key_value=0x04; break; //four
        case 0x0d:key_value=0x05; break; //five
        case 0x0e:key_value=0x0e; break; //UP
        case 0x0f:key_value=0x0f; break; //Clear

        default :key_value=0xff; break;

        }
        KeyCntRd++;
        if(KeyCntRd==8)
        KeyCntRd=0;
        }
        return(key_value);
        }

        #pragma vector=PORT1_VECTOR
        __interrupt void Key_INT(void)
        {
        if(keyj()!=0X0f)
        {
        key_delay(5000); //消抖動
        if(keyj()!=0X0f)
        {
        KeyNum[KeyCntWr++]=key();
        if(KeyCntWr==8) //鍵盤緩存區滿則從頭開始
        KeyCntWr=0;

        if(KeyCntWr==KeyCntRd) //寫計數器與讀計數器相等,則讀計數器相應加1
        {
        KeyCntRd++;
        if(KeyCntRd==8)
        KeyCntRd=0;
        }
        BellOn(1);
        }
        }
        P1OUT=0X0f;
        P1IFG=0X00; //清除中斷標志
        }

        緩存鍵值為7或8個。即最后7或8個鍵值有效。



        評論


        技術專區

        關閉
        主站蜘蛛池模板: 友谊县| 浦县| 宁津县| 工布江达县| 泰兴市| 彭阳县| 海南省| 五家渠市| 枝江市| 玛沁县| 霸州市| 宁都县| 个旧市| 彰化县| 青阳县| 通化市| 浦北县| 邵武市| 苍山县| 中阳县| 耿马| 鲁甸县| 茶陵县| 通辽市| 教育| 永州市| 邯郸市| 九寨沟县| 光泽县| 唐海县| 平潭县| 镇坪县| 鹤岗市| 澄迈县| 西乡县| 望都县| 喀喇沁旗| 鄂伦春自治旗| 喀喇| 达孜县| 杭锦旗|