單片機鍵盤(pán)掃描方法兩種
矩陣式鍵盤(pán)的結構與工作原理:
本文引用地址:http://dyxdggzs.com/article/201611/315921.htm在鍵盤(pán)中按鍵數量較多時(shí),為了減少I(mǎi)/O口的占用,通常將按鍵排列成矩陣形式,如圖1所示。在矩陣式鍵盤(pán)中,每條水平線(xiàn)和垂直線(xiàn)在交叉處不直接連通,而是通過(guò)一個(gè)按鍵加以連接。這樣,一個(gè)端口(如P1口)就可以構成4*4=16個(gè)按鍵,比之直接將端口線(xiàn)用于鍵盤(pán)多出了一倍,而且線(xiàn)數越多,區別越明顯,比如再多加一條線(xiàn)就可以構成20鍵的鍵盤(pán),而直接用端口線(xiàn)則只能多出一鍵(9鍵)。由此可見(jiàn),在需要的鍵數比較多時(shí),采用矩陣法來(lái)做鍵盤(pán)是合理的。
矩陣式結構的鍵盤(pán)顯然比直接法要復雜一些,識別也要復雜一些,上圖中,列線(xiàn)通過(guò)電阻接正電源,并將行線(xiàn)所接的單片機的I/O口作為輸出端,而列線(xiàn)所接的I/O口則作為輸入。這樣,當按鍵沒(méi)有按下時(shí),所有的輸出端都是高電平,代表無(wú)鍵按下。行線(xiàn)輸出是低電平,一旦有鍵按下,則輸入線(xiàn)就會(huì )被拉低,這樣,通過(guò)讀入輸入線(xiàn)的狀態(tài)就可得知是否有鍵按下了。具體的識別及編程方法如下所述。
矩陣式鍵盤(pán)的按鍵識別方法確定矩陣式鍵盤(pán)上何鍵被按下介紹一種“行掃描法”。
行掃描法行掃描法又稱(chēng)為逐行(或列)掃描查詢(xún)法,是一種最常用的按鍵識別方法,如上圖所示鍵盤(pán),介紹過(guò)程如下。
判斷鍵盤(pán)中有無(wú)鍵按下將全部行線(xiàn)Y0-Y3置低電平,然后檢測列線(xiàn)的狀態(tài)。只要有一列的電平為低,則表示鍵盤(pán)中有鍵被按下,而且閉合的鍵位于低電平線(xiàn)與4根行線(xiàn)相交叉的4個(gè)按鍵之中。若所有列線(xiàn)均為高電平,則鍵盤(pán)中無(wú)鍵按下。判斷閉合鍵所在的位置在確認有鍵按下后,即可進(jìn)入確定具體閉合鍵的過(guò)程。其方法是:依次將行線(xiàn)置為低電平,即在置某根行線(xiàn)為低電平時(shí),其它線(xiàn)為高電平。在確定某根行線(xiàn)位置為低電平后,再逐行檢測各列線(xiàn)的電平狀態(tài)。若某列為低,則該列線(xiàn)與置為低電平的行線(xiàn)交叉處的按鍵就是閉合的按鍵。下面給出一個(gè)具體的例子:
8031單片機的P1口用作鍵盤(pán)I/O口,鍵盤(pán)的列線(xiàn)接到P1口的低4位,鍵盤(pán)的行線(xiàn)接到P1口的高4位。列線(xiàn)P1.0-P1.3分別接有4個(gè)上拉電阻到正電源+5V,并把列線(xiàn)P1.0-P1.3設置為輸入線(xiàn),行線(xiàn)P1.4-P.17設置為輸出線(xiàn)。4根行線(xiàn)和4根列線(xiàn)形成16個(gè)相交點(diǎn)。
檢測當前是否有鍵被按下。檢測的方法是P1.4-P1.7輸出全“0”,讀取P1.0-P1.3的狀態(tài),若P1.0-P1.3為全“1”,則無(wú)鍵閉合,否則有鍵閉合。去除鍵抖動(dòng)。當檢測到有鍵按下后,延時(shí)一段時(shí)間再做下一步的檢測判斷。若有鍵被按下,應識別出是哪一個(gè)鍵閉合。方法是對鍵盤(pán)的行線(xiàn)進(jìn)行掃描。P1.4-P1.7按下述4種組合依次輸出:P1.7 1 1 1 0
P1.6 1 1 0 1
P1.5 1 0 1 1
P1.4 0 1 1 1
二、行列反轉法
了解行列鍵盤(pán)掃描得從硬件開(kāi)始學(xué)習,我們得知道行列掃描是什么意思。在 單片機系統中為了擴大同一個(gè) I/O 口的鍵盤(pán)個(gè)數,則采用了行列式鍵盤(pán)接法,就 是交叉相接。所謂的“行”、“列”是我們人為規定的,如果試著(zhù)把列看成行,將行看成列是一樣的。
這里我們規定 P1.0~P1.3為列,P1.7~P1.4 為行。 如圖所示:
1、51例子
舉一個(gè)例子吧。
第一步:行線(xiàn)IO P1.7~P1.4置低電平,列線(xiàn)IO P1.0~P1.3置高電平
假設K1按下,那么P1.0=0 讀P1口 P1=00001110
第二步:行線(xiàn)IO P1.7~P1.4置高電平,列線(xiàn)IO P1.0~P1.3置低電平
假設K1按下,那么P1.7=0 讀P1口 P1=01110000
兩個(gè)字節相加,得到新數據:01111110(第一行 第一列)
每按一個(gè)鍵我們都得到不同的字節,比對我們的字節是什么就可以知道鍵值是什么了。
/////////////////////////////////////////////////////////////////////
#include
#define uchar unsigned char
#define uint unsigned int
unsigned char const dofly[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
0x77,0x7c,0x39,0x5e,0x79,0x71};//0-F
/*------------------------------------------------
函數聲明
------------------------------------------------*/
uchar keyscan(void);//鍵盤(pán)掃描
void delay(uint i); //演示程序
/*------------------------------------------------
主函數
------------------------------------------------*/
void main()
{
uchar key;
P2=0x00; //1數碼管亮 按相應的按鍵,會(huì )顯示按鍵上的字符
while(1)
{
key=keyscan(); //調用鍵盤(pán)掃描,
switch(key)
{
case 0x7e:P0=dofly[0];break;//0 按下相應的鍵顯示相對應的碼值
case 0x7d:P0=dofly[1];break;//1
case 0x7b:P0=dofly[2];break;//2
case 0x77:P0=dofly[3];break;//3
case 0xbe:P0=dofly[4];break;//4
case 0xbd:P0=dofly[5];break;//5
case 0xbb:P0=dofly[6];break;//6
case 0xb7:P0=dofly[7];break;//7
case 0xde:P0=dofly[8];break;//8
case 0xdd:P0=dofly[9];break;//9
case 0xdb:P0=dofly[10];break;//a
case 0xd7:P0=dofly[11];break;//b
case 0xee:P0=dofly[12];break;//c
case 0xed:P0=dofly[13];break;//d
case 0xeb:P0=dofly[14];break;//e
case 0xe7:P0=dofly[15];break;//f
}
}
}
/*------------------------------------------------
鍵盤(pán)掃描程序
------------------------------------------------*/
一、行列掃描法
矩陣式鍵盤(pán)的結構與工作原理:
在鍵盤(pán)中按鍵數量較多時(shí),為了減少I(mǎi)/O口的占用,通常將按鍵排列成矩陣形式,如圖1所示。在矩陣式鍵盤(pán)中,每條水平線(xiàn)和垂直線(xiàn)在交叉處不直接連通,而是通過(guò)一個(gè)按鍵加以連接。這樣,一個(gè)端口(如P1口)就可以構成4*4=16個(gè)按鍵,比之直接將端口線(xiàn)用于鍵盤(pán)多出了一倍,而且線(xiàn)數越多,區別越明顯,比如再多加一條線(xiàn)就可以構成20鍵的鍵盤(pán),而直接用端口線(xiàn)則只能多出一鍵(9鍵)。由此可見(jiàn),在需要的鍵數比較多時(shí),采用矩陣法來(lái)做鍵盤(pán)是合理的。
矩陣式結構的鍵盤(pán)顯然比直接法要復雜一些,識別也要復雜一些,上圖中,列線(xiàn)通過(guò)電阻接正電源,并將行線(xiàn)所接的單片機的I/O口作為輸出端,而列線(xiàn)所接的I/O口則作為輸入。這樣,當按鍵沒(méi)有按下時(shí),所有的輸出端都是高電平,代表無(wú)鍵按下。行線(xiàn)輸出是低電平,一旦有鍵按下,則輸入線(xiàn)就會(huì )被拉低,這樣,通過(guò)讀入輸入線(xiàn)的狀態(tài)就可得知是否有鍵按下了。具體的識別及編程方法如下所述。
矩陣式鍵盤(pán)的按鍵識別方法確定矩陣式鍵盤(pán)上何鍵被按下介紹一種“行掃描法”。
行掃描法行掃描法又稱(chēng)為逐行(或列)掃描查詢(xún)法,是一種最常用的按鍵識別方法,如上圖所示鍵盤(pán),介紹過(guò)程如下。
判斷鍵盤(pán)中有無(wú)鍵按下將全部行線(xiàn)Y0-Y3置低電平,然后檢測列線(xiàn)的狀態(tài)。只要有一列的電平為低,則表示鍵盤(pán)中有鍵被按下,而且閉合的鍵位于低電平線(xiàn)與4根行線(xiàn)相交叉的4個(gè)按鍵之中。若所有列線(xiàn)均為高電平,則鍵盤(pán)中無(wú)鍵按下。判斷閉合鍵所在的位置在確認有鍵按下后,即可進(jìn)入確定具體閉合鍵的過(guò)程。其方法是:依次將行線(xiàn)置為低電平,即在置某根行線(xiàn)為低電平時(shí),其它線(xiàn)為高電平。在確定某根行線(xiàn)位置為低電平后,再逐行檢測各列線(xiàn)的電平狀態(tài)。若某列為低,則該列線(xiàn)與置為低電平的行線(xiàn)交叉處的按鍵就是閉合的按鍵。下面給出一個(gè)具體的例子:
8031單片機的P1口用作鍵盤(pán)I/O口,鍵盤(pán)的列線(xiàn)接到P1口的低4位,鍵盤(pán)的行線(xiàn)接到P1口的高4位。列線(xiàn)P1.0-P1.3分別接有4個(gè)上拉電阻到正電源+5V,并把列線(xiàn)P1.0-P1.3設置為輸入線(xiàn),行線(xiàn)P1.4-P.17設置為輸出線(xiàn)。4根行線(xiàn)和4根列線(xiàn)形成16個(gè)相交點(diǎn)。
檢測當前是否有鍵被按下。檢測的方法是P1.4-P1.7輸出全“0”,讀取P1.0-P1.3的狀態(tài),若P1.0-P1.3為全“1”,則無(wú)鍵閉合,否則有鍵閉合。去除鍵抖動(dòng)。當檢測到有鍵按下后,延時(shí)一段時(shí)間再做下一步的檢測判斷。若有鍵被按下,應識別出是哪一個(gè)鍵閉合。方法是對鍵盤(pán)的行線(xiàn)進(jìn)行掃描。P1.4-P1.7按下述4種組合依次輸出:P1.7 1 1 1 0
P1.6 1 1 0 1
P1.5 1 0 1 1
P1.4 0 1 1 1
二、行列反轉法
了解行列鍵盤(pán)掃描得從硬件開(kāi)始學(xué)習,我們得知道行列掃描是什么意思。在 單片機系統中為了擴大同一個(gè) I/O 口的鍵盤(pán)個(gè)數,則采用了行列式鍵盤(pán)接法,就 是交叉相接。所謂的“行”、“列”是我們人為規定的,如果試著(zhù)把列看成行,將行看成列是一樣的。
這里我們規定 P1.0~P1.3為列,P1.7~P1.4 為行。 如圖所示:
1、51例子
舉一個(gè)例子吧。
第一步:行線(xiàn)IO P1.7~P1.4置低電平,列線(xiàn)IO P1.0~P1.3置高電平
假設K1按下,那么P1.0=0 讀P1口 P1=00001110
第二步:行線(xiàn)IO P1.7~P1.4置高電平,列線(xiàn)IO P1.0~P1.3置低電平
假設K1按下,那么P1.7=0 讀P1口 P1=01110000
兩個(gè)字節相加,得到新數據:01111110(第一行 第一列)
每按一個(gè)鍵我們都得到不同的字節,比對我們的字節是什么就可以知道鍵值是什么了。
/////////////////////////////////////////////////////////////////////
#include
#define uchar unsigned char
#define uint unsigned int
unsigned char const dofly[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
0x77,0x7c,0x39,0x5e,0x79,0x71};//0-F
/*------------------------------------------------
函數聲明
------------------------------------------------*/
uchar keyscan(void);//鍵盤(pán)掃描
void delay(uint i); //演示程序
/*------------------------------------------------
主函數
------------------------------------------------*/
void main()
{
uchar key;
P2=0x00; //1數碼管亮 按相應的按鍵,會(huì )顯示按鍵上的字符
while(1)
{
key=keyscan(); //調用鍵盤(pán)掃描,
switch(key)
{
case 0x7e:P0=dofly[0];break;//0 按下相應的鍵顯示相對應的碼值
case 0x7d:P0=dofly[1];break;//1
case 0x7b:P0=dofly[2];break;//2
case 0x77:P0=dofly[3];break;//3
case 0xbe:P0=dofly[4];break;//4
case 0xbd:P0=dofly[5];break;//5
case 0xbb:P0=dofly[6];break;//6
case 0xb7:P0=dofly[7];break;//7
case 0xde:P0=dofly[8];break;//8
case 0xdd:P0=dofly[9];break;//9
case 0xdb:P0=dofly[10];break;//a
case 0xd7:P0=dofly[11];break;//b
case 0xee:P0=dofly[12];break;//c
case 0xed:P0=dofly[13];break;//d
case 0xeb:P0=dofly[14];break;//e
case 0xe7:P0=dofly[15];break;//f
}
}
}
/*------------------------------------------------
鍵盤(pán)掃描程序
------------------------------------------------*/
uchar keyscan(void) //鍵盤(pán)掃描函數,使用行列反轉掃描法
{
uchar cord_h,cord_l;//行列值中間變量
P3=0x0f; //行線(xiàn)輸出全為0
cord_h=P3&0x0f; //讀入列線(xiàn)值
if(cord_h!=0x0f) //先檢測有無(wú)按鍵按下
{
delay(100); //去抖
if(cord_h!=0x0f)
{
cord_h=P3&0x0f; //讀入列線(xiàn)值
P3=cord_h|0xf0; //輸出當前列線(xiàn)值
cord_l=P3&0xf0; //讀入行線(xiàn)值
return(cord_h+cord_l);//鍵盤(pán)最后組合碼值
}
}return(0xff); //返回該值
}
/*------------------------------------------------
延時(shí)程序
------------------------------------------------*/
void delay(uint i) //延時(shí)函數
{
while(i--);
}
P3=cord_h|0xf0; //輸出當前列線(xiàn)值
cord_l=P3&0xf0; //讀入行線(xiàn)值
return(cord_h+cord_l);//鍵盤(pán)最后組合碼值
}
}return(0xff); //返回該值
}
/*------------------------------------------------
延時(shí)程序
------------------------------------------------*/
void delay(uint i) //延時(shí)函數
{
while(i--);
}
評論