|
由于按鍵沒(méi)有接地,4行 4列正好占用8個(gè)I/O 如果4行我們送 P3.0到P3.3送入0 1 1 1 然后去讀取 4列的值,如果P3.0的按鍵按下那么P3.4---P3.7的值等于 0 1 1 1,假如是第2個(gè)鍵按下的話那么讀回來(lái)的值是 1 0 1 1 ,如果第3個(gè)鍵按下去讀回來(lái)的值是 1 1 0 1 ,如果第4個(gè)鍵按下去讀回來(lái)的值是 1 1 1 0 ,如果沒(méi)有鍵按下去讀回來(lái)就是1 1 1 1。 所以我們就根據(jù)讀回來(lái)的值來(lái)判斷按下去的是那個(gè)鍵。當(dāng)然這是對(duì)P3.0這一行,因?yàn)榫仃囨I盤是掃描的,所以下次把P3.0 給1 P3.1 給0對(duì)第2行,陸續(xù)的第3 行第4行, 0111 1011 1101 1110 而每次都去從新掃描一遍列值列有4個(gè)值,以確定是那個(gè)鍵按下。無(wú)論何時(shí)任何一個(gè)時(shí)間有一個(gè)按鍵被按下就跳出循環(huán)。當(dāng)然不可能有2個(gè)鍵剛好一起按下你的手沒(méi)有這么好的力度,就算有2個(gè)鍵一起按鍵,程序也有先后檢測(cè)的順序,只能檢測(cè)一個(gè)后面的檢測(cè)不到。
用P1 口 P1.0---P1.3 接4行 P1.4--P1.7 接4列
P3 = 0XFE; //第一行給0
temp ;定義個(gè)變量
temp = P3 ;讀回來(lái) 由于讀需要先寫1 因?yàn)镻3= FE 已經(jīng)把高4位給1了 所以能讀了
temp & oxf0 如果沒(méi)有按鍵按下結(jié)果還是0xf0 .如果有鍵按下結(jié)果就不是0xf0了。
num 然后我們?cè)俣x一個(gè)變量 讓它賦值給這個(gè)按下去的按鍵值。
一次類推把第一行賦值0 掃描一遍 然后把第2行賦值0掃描一遍..............共掃描16遍。
只要有鍵按下 就會(huì)得到一個(gè)值 num 就從1排到16. 共16個(gè)按鍵 4*4 的矩陣鍵盤。
我再總結(jié)下思路:
首先 低4位是行 共4行 分別把每行給0 低電平 就4次 0 1 1 1 、1 0 1 1 、 1 1 0 1 、1 1 1 0 對(duì)吧
然后去檢測(cè)高4位 4列啊 先不考慮極端情況,4列就4個(gè)按鍵只要按下一個(gè) P3口的高4位就會(huì)有一個(gè)值。根據(jù)這個(gè)值就能判斷是那個(gè)鍵了。
如:P3= 1111 1110 低四位是行先把第一行給0
有按鍵下的話 temp = P3 讀回來(lái) 1101 1110 然后temp & 0xf0 與運(yùn)算下就判斷下還等于oxf0嗎?如還等于就沒(méi)有按下,如果不等于就肯定有按鍵按下。定義個(gè)變量讓它等于這個(gè)不是0XF0的值,做個(gè)標(biāo)記。依次類推。
然后用這個(gè)思路寫個(gè)程序吧!寫的不太好看的不是很清楚只是做個(gè)參考吧,只要把思路理清楚就行了。
是這樣我們分別按這16個(gè)按鍵讓它分別顯示是第幾個(gè) 比如 按下第一個(gè)數(shù)碼管就顯示1 第2個(gè)數(shù)碼管就顯示2,依次類推。一直到 F (為了方便讓所有的數(shù)碼管顯示同一個(gè)數(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//加這個(gè)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);//這里可以做個(gè)顯示函數(shù),但是我沒(méi)做。
void main(){
num = 17;//讓它顯示0 什么都不顯示。 因?yàn)楹瘮?shù)返回num值
dula =1 ;
P0= 0;
dula =0;
wela = 1;
P0= 0xc0;
wela = 0;
//以上P0口控制數(shù)碼管的一上電什么都不顯示
while(1){
num1 = keyscan();//沒(méi)按下返回17
dula =1;
P0= table[num1-1];//17-1 =16
dula = 0;
}
}
//用uchar keyscan() 帶返回值的函數(shù) 代替整個(gè)矩陣鍵盤 當(dāng)然顯示就不要了 dula 那3行我注釋掉了
uchar keyscan(){
P3= 0xfe; //高4位是f 等于寫了1 1 1 1 也滿足了先寫1的要求
temp =P3;//讀回來(lái)了
temp &= 0xf0;//因?yàn)槲覀冎皇亲x回來(lái)高4位
while (temp != 0xf0){ //下面的幾個(gè)while循環(huán)判斷可以用if好理解。只看到第一行就行了。
//這幾個(gè)while 都是做判斷用的
delay(5);//消除抖動(dòng)的
temp=P3;
temp &= 0xf0;
while(temp != 0xf0){ //確實(shí)不等于0xf0有按鍵按下
temp = P3;//我們這個(gè)時(shí)候只是把P3口的值賦給了temp
switch (temp){ //檢測(cè)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)在這里面 松手檢測(cè)
{
temp = P3;
temp = temp & 0xf0; //這個(gè)是松手檢測(cè) 松手這里就等于了0xf0
}//下面就顯示一下 退出整個(gè)一行的循環(huán),不加松手檢測(cè)會(huì)退不出去循環(huán)
//到這里是把第一行檢測(cè)了。
}
}
//////以下下是其他幾行檢測(cè)的代碼
P3= 0xfd; //高4位是f 等于寫了1 1 1 1 也滿足了先寫1的要求
temp =P3;//讀回來(lái)了
temp &= 0xf0;//因?yàn)槲覀冎皇亲x回來(lái)高4位
while (temp != 0xf0){
delay(5);//消除抖動(dòng)的
temp=P3;
temp &= 0xf0;
while(temp != 0xf0){ //確實(shí)不等于0xf0有按鍵按下
temp = P3;//我們這個(gè)時(shí)候只是把P3口的值賦給了temp
switch (temp){ //檢測(cè)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)在這里面 松手檢測(cè)
{
temp = P3;
temp = temp & 0xf0; //這個(gè)是松手檢測(cè) 松手這里就等于了0xf0
}//下面就顯示一下 退出整個(gè)2行的循環(huán)。不加松手檢測(cè)會(huì)退不出去循環(huán)
//到這里是把第2行檢測(cè)了。
}
}
P3= 0xfb; //高4位是f 等于寫了1 1 1 1 也滿足了先寫1的要求
temp =P3;//讀回來(lái)了
temp &= 0xf0;//因?yàn)槲覀冎皇亲x回來(lái)高4位
while (temp != 0xf0){
delay(5);//消除抖動(dòng)的
temp=P3;
temp &= 0xf0;
while(temp != 0xf0){ //確實(shí)不等于0xf0有按鍵按下
temp = P3;//我們這個(gè)時(shí)候只是把P3口的值賦給了temp
switch (temp){ //檢測(cè)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)在這里面 松手檢測(cè)
{
temp = P3;
temp = temp & 0xf0; //這個(gè)是松手檢測(cè) 松手這里就等于了0xf0
}//下面就顯示一下 退出整個(gè)3行的循環(huán)。 不加松手檢測(cè)會(huì)退不出去循環(huán)
//到這里是把第3行檢測(cè)了。
}
}
P3= 0xf7; //高4位是f 等于寫了1 1 1 1 也滿足了先寫1的要求
temp =P3;//讀回來(lái)了
temp &= 0xf0;//因?yàn)槲覀冎皇亲x回來(lái)高4位
while (temp != 0xf0){
delay(5);//消除抖動(dòng)的
temp=P3;
temp &= 0xf0;
while(temp != 0xf0){ //確實(shí)不等于0xf0有按鍵按下
temp = P3;//我們這個(gè)時(shí)候只是把P3口的值賦給了temp
switch (temp){ //檢測(cè)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)在這里面 松手檢測(cè)
{
temp = P3;
temp = temp & 0xf0; //這個(gè)是松手檢測(cè) 松手這里就等于了0xf0
}//下面就顯示一下 退出整個(gè)4行循環(huán)。不加松手檢測(cè)會(huì)退不出去循環(huán)
//到這里是把第4行檢測(cè)了。
}
}
return num; //其實(shí)鍵盤掃描就需要一個(gè)值。
}
|
|