由于按鍵沒有接地,4行 4列正好占用8個I/O 如果4行我們送 P3.0到P3.3送入0 1 1 1 然后去讀取 4列的值,如果P3.0的按鍵按下那么P3.4---P3.7的值等于 0 1 1 1,假如是第2個鍵按下的話那么讀回來的值是 1 0 1 1 ,如果第3個鍵按下去讀回來的值是 1 1 0 1 ,如果第4個鍵按下去讀回來的值是 1 1 1 0 ,如果沒有鍵按下去讀回來就是1 1 1 1。 所以我們就根據(jù)讀回來的值來判斷按下去的是那個鍵。當然這是對P3.0這一行,因為矩陣鍵盤是掃描的,所以下次把P3.0 給1 P3.1 給0對第2行,陸續(xù)的第3 行第4行, 0111 1011 1101 1110 而每次都去從新掃描一遍列值列有4個值,以確定是那個鍵按下。無論何時任何一個時間有一個按鍵被按下就跳出循環(huán)。當然不可能有2個鍵剛好一起按下你的手沒有這么好的力度,就算有2個鍵一起按鍵,程序也有先后檢測的順序,只能檢測一個后面的檢測不到。
用P1 口 P1.0---P1.3 接4行 P1.4--P1.7 接4列
P3 = 0XFE; //第一行給0
temp ;定義個變量
temp = P3 ;讀回來 由于讀需要先寫1 因為P3= FE 已經(jīng)把高4位給1了 所以能讀了
temp & oxf0 如果沒有按鍵按下結果還是0xf0 .如果有鍵按下結果就不是0xf0了。
num 然后我們再定義一個變量 讓它賦值給這個按下去的按鍵值。
一次類推把第一行賦值0 掃描一遍 然后把第2行賦值0掃描一遍..............共掃描16遍。
只要有鍵按下 就會得到一個值 num 就從1排到16. 共16個按鍵 4*4 的矩陣鍵盤。
我再總結下思路:
首先 低4位是行 共4行 分別把每行給0 低電平 就4次 0 1 1 1 、1 0 1 1 、 1 1 0 1 、1 1 1 0 對吧
然后去檢測高4位 4列啊 先不考慮極端情況,4列就4個按鍵只要按下一個 P3口的高4位就會有一個值。根據(jù)這個值就能判斷是那個鍵了。
如:P3= 1111 1110 低四位是行先把第一行給0
有按鍵下的話 temp = P3 讀回來 1101 1110 然后temp & 0xf0 與運算下就判斷下還等于oxf0嗎?如還等于就沒有按下,如果不等于就肯定有按鍵按下。定義個變量讓它等于這個不是0XF0的值,做個標記。依次類推。
然后用這個思路寫個程序吧!寫的不太好看的不是很清楚只是做個參考吧,只要把思路理清楚就行了。
是這樣我們分別按這16個按鍵讓它分別顯示是第幾個 比如 按下第一個數(shù)碼管就顯示1 第2個數(shù)碼管就顯示2,依次類推。一直到 F (為了方便讓所有的數(shù)碼管顯示同一個數(shù)0---F)
#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit dula = P2^6;
sbit wela = P2^7;
sbit key1= P3^4;
uchar code table []={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,
0//加這個0就是什么都不顯示
};
uchar num,temp,num1;
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
uchar keyscan();//聲明一下
//void display(uchar num1);//這里可以做個顯示函數(shù),但是我沒做。
void main(){
num = 17;//讓它顯示0 什么都不顯示。 因為函數(shù)返回num值
dula =1 ;
P0= 0;
dula =0;
wela = 1;
P0= 0xc0;
wela = 0;
//以上P0口控制數(shù)碼管的一上電什么都不顯示
while(1){
num1 = keyscan();//沒按下返回17
dula =1;
P0= table[num1-1];//17-1 =16
dula = 0;
}
}
//用uchar keyscan() 帶返回值的函數(shù) 代替整個矩陣鍵盤 當然顯示就不要了 dula 那3行我注釋掉了
uchar keyscan(){
P3= 0xfe; //高4位是f 等于寫了1 1 1 1 也滿足了先寫1的要求
temp =P3;//讀回來了
temp &= 0xf0;//因為我們只是讀回來高4位
while (temp != 0xf0){ //下面的幾個while循環(huán)判斷可以用if好理解。只看到第一行就行了。
//這幾個while 都是做判斷用的
delay(5);//消除抖動的
temp=P3;
temp &= 0xf0;
while(temp != 0xf0){ //確實不等于0xf0有按鍵按下
temp = P3;//我們這個時候只是把P3口的值賦給了temp
switch (temp){ //檢測P3口。
case 0xee:
num = 1;
break;
case 0xde:
num=2;
break;
case 0xbe:
num=3;
break;
case 0x7e:
num=4;
break;
}
while(temp != 0xf0)//有按鍵按下可能是不等于的 循環(huán)在這里面 松手檢測
{
temp = P3;
temp = temp & 0xf0; //這個是松手檢測 松手這里就等于了0xf0
}//下面就顯示一下 退出整個一行的循環(huán),不加松手檢測會退不出去循環(huán)
//到這里是把第一行檢測了。
}
}
//////以下下是其他幾行檢測的代碼
P3= 0xfd; //高4位是f 等于寫了1 1 1 1 也滿足了先寫1的要求
temp =P3;//讀回來了
temp &= 0xf0;//因為我們只是讀回來高4位
while (temp != 0xf0){
delay(5);//消除抖動的
temp=P3;
temp &= 0xf0;
while(temp != 0xf0){ //確實不等于0xf0有按鍵按下
temp = P3;//我們這個時候只是把P3口的值賦給了temp
switch (temp){ //檢測P3口。
case 0xed:
num = 5;
break;
case 0xdd:
num=6;
break;
case 0xbd:
num=7;
break;
case 0x7d:
num=8;
break;
}
while(temp != 0xf0)//有按鍵按下可能是不等于的 循環(huán)在這里面 松手檢測
{
temp = P3;
temp = temp & 0xf0; //這個是松手檢測 松手這里就等于了0xf0
}//下面就顯示一下 退出整個2行的循環(huán)。不加松手檢測會退不出去循環(huán)
//到這里是把第2行檢測了。
}
}
P3= 0xfb; //高4位是f 等于寫了1 1 1 1 也滿足了先寫1的要求
temp =P3;//讀回來了
temp &= 0xf0;//因為我們只是讀回來高4位
while (temp != 0xf0){
delay(5);//消除抖動的
temp=P3;
temp &= 0xf0;
while(temp != 0xf0){ //確實不等于0xf0有按鍵按下
temp = P3;//我們這個時候只是把P3口的值賦給了temp
switch (temp){ //檢測P3口。
case 0xeb:
num =9;
break;
case 0xdb:
num=10;
break;
case 0xbb:
num=11;
break;
case 0x7b:
num=12;
break;
}
while(temp != 0xf0)//有按鍵按下可能是不等于的 循環(huán)在這里面 松手檢測
{
temp = P3;
temp = temp & 0xf0; //這個是松手檢測 松手這里就等于了0xf0
}//下面就顯示一下 退出整個3行的循環(huán)。 不加松手檢測會退不出去循環(huán)
//到這里是把第3行檢測了。
}
}
P3= 0xf7; //高4位是f 等于寫了1 1 1 1 也滿足了先寫1的要求
temp =P3;//讀回來了
temp &= 0xf0;//因為我們只是讀回來高4位
while (temp != 0xf0){
delay(5);//消除抖動的
temp=P3;
temp &= 0xf0;
while(temp != 0xf0){ //確實不等于0xf0有按鍵按下
temp = P3;//我們這個時候只是把P3口的值賦給了temp
switch (temp){ //檢測P3口。
case 0xe7:
num =13 ;
break;
case 0xd7:
num=14;
break;
case 0xb7:
num=15;
break;
case 0x77:
num=16;
break;
}
while(temp != 0xf0)//有按鍵按下可能是不等于的 循環(huán)在這里面 松手檢測
{
temp = P3;
temp = temp & 0xf0; //這個是松手檢測 松手這里就等于了0xf0
}//下面就顯示一下 退出整個4行循環(huán)。不加松手檢測會退不出去循環(huán)
//到這里是把第4行檢測了。
}
}
return num; //其實鍵盤掃描就需要一個值。
}
|