新聞中心

        4x4鍵盤編程心得

        作者: 時(shí)間:2016-11-10 來(lái)源:網(wǎng)絡(luò) 收藏
        鍵盤在單片機(jī)系統(tǒng)中用得非常廣泛。當(dāng)按鍵多而且單片機(jī)的I/O口有限時(shí),往往要考慮的是矩陣式鍵盤。其中有兩種方式可以實(shí)現(xiàn)矩陣式鍵盤:一種是利用純硬件完成解碼的稱為“編碼鍵盤”;另外一種是利用軟件實(shí)現(xiàn)解碼的稱為“非編碼鍵盤”。

          在單片機(jī)系統(tǒng)中,只要單片機(jī)有空余的時(shí)間來(lái)解碼時(shí),我們往往利用的是軟件解碼的形式,即“非編碼鍵盤”來(lái)實(shí)現(xiàn)矩陣鍵盤。這樣可以節(jié)約成本。下面我就對(duì)矩陣鍵盤在51單片機(jī)中的軟件解碼方式應(yīng)用總結(jié)一下。

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

          原理圖:

        工作原理:

        掃描程序查詢的內(nèi)容如下:

        &129;查詢是否有鍵按下。首先單片機(jī)向行掃描口P1.0~P1.3輸出全為0的掃描碼F0H,然后從列檢測(cè)口P1.4~P1.7輸入列檢測(cè)信號(hào),只要有一列信號(hào)不為1,即P1口不為F0H,則表示有鍵按下。接著要查出按下鍵所在的行、列位置。

        &8218;查詢按下鍵所在的行、列位置。單片機(jī)將得到的信號(hào)取反,P1.4~P1.7口中為1的位置便是鍵所在位置。

        接下來(lái)要確定鍵所在的行,需進(jìn)行行逐行掃描。單片機(jī)首先使用P1.0口接地,P1.1~P1.7口為1,即向P1口發(fā)送掃描碼FEH,接著輸入列檢測(cè)信號(hào),若為全1,則表示不在第一行。然后使P1.1接地,其余為1,再讀入列信號(hào)……。這樣逐行發(fā)0掃描碼,直到找到按鍵所在的行,將該行掃描碼取反保留。若各行都掃描以后仍沒(méi)有找到,則放棄掃描,認(rèn)為是鍵的誤動(dòng)作。

        &402;對(duì)得到的行號(hào)和列號(hào)譯碼,得到鍵值。

        &8222;鍵的消抖處理。當(dāng)用手按下一個(gè)鍵時(shí),往往會(huì)出現(xiàn)所按鍵在閉合位置和斷開(kāi)位置之間跳幾下才穩(wěn)定到閉合狀態(tài)的情況;在釋放一個(gè)鍵時(shí),也會(huì)出現(xiàn)類似的情況。這就是鍵抖動(dòng)。抖動(dòng)的持續(xù)時(shí)間不一,通常不會(huì)大于10ms。若抖動(dòng)問(wèn)題不解決,就會(huì)引起對(duì)閉合鍵的多次讀入。解決鍵抖動(dòng)最方便的方法是:當(dāng)發(fā)現(xiàn)有鍵按下后,不要立即進(jìn)行逐行掃描,而是延時(shí)10ms后再進(jìn)行。由于鍵按下的時(shí)間會(huì)持續(xù)上百ms,延時(shí)后再掃描也不遲。

        程序如下:

        unsignedcharkey_scan(void)//按鍵掃描函數(shù)

        {

        unsignedcharsccode,recode;

        P1=0xf0;//發(fā)全0行掃描碼,列線輸入

        if((P1&0xf0)!=0xf0)//若有鍵按下

        {

        delay_ms(10);//延時(shí)去抖

        if((P1&0xf0)!=0xf0)

        {

        sccode=0xfe;//逐行掃描初值

        While((sccode&0x10)!=0)

        {

        P1=sccode;//輸出行掃描碼

        if((P1&0xf0)!=0xf0)//本行有鍵按下

        {

        recode=(P1&0xf0)|0xf0;

        return((~sccode)+(~recode));//返回特征字節(jié)碼

        }

        else

        sccode=(sccode<<1)|0x01;//行掃描碼左移一位

        }

        }

        }

        return(0);//無(wú)鍵按下,返回值為0

        }

        說(shuō)明:

        此按鍵掃描函數(shù)是很多書上介紹的按鍵掃描函數(shù),從原來(lái)的角度來(lái)說(shuō)是完全正確可行的。但是在我上次做《密碼鎖》時(shí),發(fā)現(xiàn)用此函數(shù)比較麻煩,且總是存在一些問(wèn)題。通過(guò)查閱大量書籍和實(shí)驗(yàn),我寫出了比較簡(jiǎn)單而且切實(shí)可行的按鍵掃描程序。

        程序如下:

        /*****************************************************

        函數(shù)名:ucharKey_scan(void)

        功能:4x4按鍵,按鍵掃描

        說(shuō)明:對(duì)按鍵進(jìn)行掃描,從而得到鍵編碼

        入口參數(shù):無(wú)

        返回值:有鍵按下返回:鍵編碼=行掃描值+列掃描值;無(wú)按鍵返回0

        *****************************************************/

        ucharKey_scan(void)

        {

        ucharkey;//存放鍵編碼

        P1=0xf0;//發(fā)全0行掃描碼,列線輸入

        if((P1&0xf0)!=0xf0)//若有鍵按下

        {

        delay_ms(10);//延時(shí)去抖

        P1=0xf0;//取高4位值.即:列掃描值

        key=P1&0xf0;//存放鍵編碼的高4位

        P1=0x0f;//取低4位值.即:行掃描值

        key=(P1&0x0f)|key;//低4位與高4位進(jìn)行合并

        if(key!=0xff)

        {

        return(key);//有鍵按下,返回鍵編碼

        }

        }

        return(0);//無(wú)鍵按下,返回0

        }

        /*****************************************************

        函數(shù)名:ucharKey_switch(void)

        功能:按鍵轉(zhuǎn)換程序

        說(shuō)明:對(duì)按鍵碼進(jìn)行轉(zhuǎn)換

        入口參數(shù):無(wú)

        返回值:ASCII碼

        *****************************************************/

        ucharKey_switch(void)

        {

        ucharkey;

        key=Key_scan();

        switch(key)

        {

        case0xee:return(49);break;/*"1"鍵*/

        case0xed:return(50);break;/*"2"鍵*/

        case0xeb:return(51);break;/*"3"鍵*/

        case0xe7:return(65);break;/*"A"鍵*/

        case0xde:return(52);break;/*"4"鍵*/

        case0xdd:return(53);break;/*"5"鍵*/

        case0xdb:return(54);break;/*"6"鍵*/

        case0xd7:return(66);break;/*"B"鍵*/

        case0xbe:return(55);break;/*"7"鍵*/

        case0xbd:return(56);break;/*"8"鍵*/

        case0xbb:return(57);break;/*"9"鍵*/

        case0xb7:return(67);break;/*"C"鍵*/

        case0x7e:return(42);break;/*"*"鍵*/

        case0x7d:return(48);break;/*"0"鍵*/

        case0x7b:return(35);break;/*"#"鍵*/

        case0x77:return(68);break;/*"D"鍵*/

        case0x00:return(00);break;/*"無(wú)"鍵*/

        }

        }

        /*接盤按鍵說(shuō)明:

        --------------------------------------------------

        |1|2|3|A|

        -------------

        |4|5|6|B|

        -------------

        |7|8|9|C|

        -------------

        |*|0|#|D|

        --------------------------------------------------

        說(shuō)明:

        如果需要更改按鍵值,只需改Key_switch()函數(shù)中對(duì)應(yīng)的返回值即可。對(duì)于延時(shí)函數(shù)比較簡(jiǎn)單只需一個(gè)for循環(huán)即可,所以在這里就沒(méi)寫出來(lái)。因每個(gè)單片機(jī)的I/O的應(yīng)用是不一樣的,所以本人寫的這個(gè)函數(shù)只能在51單片機(jī)系統(tǒng)下運(yùn)行。如果要在別的單片機(jī)系統(tǒng)下,可能需要用第一種進(jìn)行改進(jìn)。



        關(guān)鍵詞: 4x4鍵盤編程心

        評(píng)論


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

        關(guān)閉
        主站蜘蛛池模板: 城口县| 瑞昌市| 浪卡子县| 胶州市| 调兵山市| 巴林右旗| 昭觉县| 衡阳县| 噶尔县| 安顺市| 自治县| 金溪县| 通榆县| 丰县| 岳普湖县| 左贡县| 永川市| 哈巴河县| 桑植县| 霸州市| 玛纳斯县| 德化县| 宁城县| 东丽区| 赞皇县| 临猗县| 博白县| 陈巴尔虎旗| 福安市| 清镇市| 古蔺县| 武清区| 齐河县| 伽师县| 金溪县| 上思县| 全州县| 阿拉尔市| 连平县| 泊头市| 沁源县|