實驗目的:理解並掌握矩陣鍵盤的工作原理;
實驗模塊:核心板+矩陣鍵盤+數碼管模塊;
實驗內容:數碼管與矩陣鍵盤對應顯示,即將鍵盤從左到右,從上到下依次命名
為“0--F”;
拓展任務:數碼管與按鍵對應顯示,做乘法顯示;
模塊連接圖:
電路原理圖:
矩陣鍵盤工作原理:在矩陣式鍵盤中,每條水平線和垂直線在交叉處不直
接連通,而是通過一個按鍵加以連接。這樣,一個端口(如 P3 口)就可以構成
4*4=16 個按鍵,比之直接將端口線用於鍵盤多出了一倍,而且線數越多,區別
越明顯,比如再多加一條線就可以構成 20 鍵的鍵盤,而直接用端口線則只能多
出一鍵(9 鍵)。由此可見,在需要的鍵數比較多時,采用矩陣法來做鍵盤是合理
的。矩陣鍵盤通常通過以下來確定被按下按鍵的位置。
第一種方法為行掃描法:
首先判斷鍵盤中有無鍵按下 將全部行線 H0-H3 置低電平,然后檢測列線
L0-L3 的狀態。只要有一列的電平為低,則表示鍵盤中有鍵被按下,而且閉合的
鍵位於低電平線與 4 根行線相交叉的 4 個按鍵之中。若所有列線均為高電平,則
鍵盤中無鍵按下;接着,判斷閉合鍵所在的位置 在確認有鍵按下后,即可進入
確定具體閉合鍵的過程。其方法是:依次將行線置為低電平,即在置某根行線為
低電平時,其它線為高電平。在確定某根行線位置為低電平后,再逐行檢測各列
線的電平狀態。若某列為低,則該列線與置為低電平的行線交叉處的按鍵就是閉
合的按鍵。
第二種方法為高低電平翻轉法:
首先讓 P1 口高四位為 1,低四位為 0,。若有按鍵按下,則高四位中會有一
個 1 翻轉為 0,低四位不會變,此時即可確定被按下的鍵的行位置;然后讓 P1
口高四位為 0,低四位為 1,。若有按鍵按下,則低四位中會有一個 1 翻轉為 0,
高四位不會變,此時即可確定被按下的鍵的列位置。
功能描述: 用反轉法實現矩陣鍵盤掃描,數碼管顯示4x4鍵盤掃描的結果
硬件連接: 用8位杜邦線將J8與J12連接,用2位杜邦線分別將J11_0與J15_DS1及J11_1與J15_DS2連接,用8位杜邦線將J9與J6連接
sbit LE2=P2^1; //段選573鎖存器使能
#define uint unsigned int
uchar code dis[16]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,
// 0 1 2 3 4 5 6 7
0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71}; //0~F的段碼
// 8 9 A B C D E F
uchar temp;
//**************************************************************************************************
//延時函數
//**************************************************************************************************
delay(uint time) //int型數據為16位,所以最大值為65535
{
uint i,j; //定義變量i,j,用於循環語句
for(i=0;i<time;i++) //for循環,循環50*time次
for(j=0;j<50;j++); //for循環,循環50次
}
//**************************************************************************************************
//矩陣鍵盤掃描函數
//**************************************************************************************************
keyScan()
{
uchar x,y;
P3=0xf0; //P3賦值0xf0
if((P3&0xf0)!=0xf0) //判斷高4位是否為全1(高4位全1代表沒按鍵按下)
delay(20); //延時去抖動,一般為5ms~10ms(由於機械觸點的彈性作用,按鍵在閉合時不會馬上穩定地接通,
//而在閉合瞬間伴隨有一連串的抖動,鍵抖動會引起一次按鍵被誤讀多次)
if((P3&0xf0)!=0xf0) //如果還能檢測到有鍵盤按下去
{
x=P3&0xf0; //讀取P3口數據
P3=0x0f; //反轉,P3賦值0x0f
y=P3&0x0f; //讀取P3口數據
keyValue=x|y; //得到掃描結果
}
}
}
//**************************************************************************************************
//矩陣鍵盤掃描結果處理函數
//**************************************************************************************************
uchar keyHandle(uchar value)
{
switch(value)
{
case 0xee:{return(0);break;} //對應按鍵S1
case 0xde:{return(1);break;} //對應按鍵S2
case 0xbe:{return(2);break;} //對應按鍵S3
case 0x7e:{return(3);break;} //對應按鍵S4
case 0xed:{return(4);break;} //對應按鍵S5
case 0xdd:{return(5);break;} //對應按鍵S6
case 0xbd:{return(6);break;} //對應按鍵S7
case 0x7d:{return(7);break;} //對應按鍵S8
case 0xeb:{return(8);break;} //對應按鍵S9
case 0xdb:{return(9);break;} //對應按鍵S10
case 0xbb:{return(10);break;} //對應按鍵S11
case 0x7b:{return(11);break;} //對應按鍵S12
case 0xe7:{return(12);break;} //對應按鍵S13
case 0xd7:{return(13);break;} //對應按鍵S14
case 0xb7:{return(14);break;} //對應按鍵S15
case 0x77:{return(15);break;} //對應按鍵S16
default:{break;}
}
}
//**************************************************************************************************
//顯示掃描結果函數
//**************************************************************************************************
show()
{
P1=0x00; //0x00=0000 0000,即選通數碼全8位
LE1=1; //鎖存位
LE1=0; //斷開鎖存,位選573的Q7~Q0仍為0x00
P1=dis[temp]; //0~F的編碼
LE2=1; //鎖存段碼
LE2=0; //斷開鎖存,段選573的Q7~Q0仍為dis[temp]
}
//主函數
//**************************************************************************************************
void main() //主函數
{
while(1) //進入while死循環
{
keyScan(); //按鍵掃描
temp=keyHandle(keyValue); //處理掃描結果
show(); //8位數碼管顯示按鍵值
}
}