初學(xué)者肯定要經(jīng)歷的一個(gè)實(shí)驗(yàn)就是4*4矩陣鍵盤的代碼編寫,大部分都是在學(xué)校里面,有現(xiàn)成的實(shí)驗(yàn)箱,基本不需要自己動(dòng)腦子。上次遇到一個(gè)哥們,他說他用的是8031的實(shí)驗(yàn)箱,我當(dāng)時(shí)就暈了。8031是8051的前身,那個(gè)芯片連ROM都沒有,可以想象我們的學(xué)校都在拿什么教育祖國的花朵。廢話少說,先上圖:
對初學(xué)者來說這篇文章會有點(diǎn)難,可以先研究一下如何用51單片機(jī)點(diǎn)亮一個(gè)發(fā)光二極管和基于CPLD-EPF10K10LC84-4(84)的交通燈設(shè)計(jì)。首先要說明的一點(diǎn),矩陣鍵盤的動(dòng)態(tài)掃描確實(shí)略顯復(fù)雜,不可能就是讀一個(gè)端口數(shù)據(jù),然后馬上就出來結(jié)果。這需要對依次每一行的按鍵進(jìn)行掃描、判斷,然后得出結(jié)果。如上圖所示,先掃描第一行,也就是S1,S2,S3,S4四個(gè)按鍵的狀態(tài)。在PA口輸入0XFE。
0XFE變成二進(jìn)制是1111 1110,為了方便使用,記得每四個(gè)數(shù)之間加一個(gè)空格。1111 1110這個(gè)數(shù)據(jù)放到PA口上,假設(shè)這個(gè)時(shí)候S1被按下了,會出現(xiàn)什么情況?因?yàn)镻A0是低電平,S1被按下之后S1導(dǎo)通,導(dǎo)致PA4的電平從1降到0,于是PA端口的數(shù)據(jù)就變成了1110 1110,換算成16進(jìn)制就是0XEE。于是我們知道S1被按下了。
假設(shè)是S3被按下,會出現(xiàn)什么情況?沒錯(cuò),PA6的電平被拉低,PA的端口數(shù)據(jù)變成了1011 1110,也就是0XBE。這樣,我們就知道了,每一行的每一個(gè)按鍵被按下的時(shí)候,都會有一個(gè)對應(yīng)的獨(dú)一無二的值。這就是矩陣鍵盤的掃描原理!送上一段源碼,大家看著玩吧:
void matrixkeyscan()
{
uchar temp,key;
P3=0xfe;
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
delayms(10);
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xee:
key=0;
break;
case 0xde:
key=1;
break;
case 0xbe:
key=2;
break;
case 0x7e:
key=3;
break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
display(key);
}
}
P3=0xfd;
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
delayms(10);
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xed:
key=4;
break;
case 0xdd:
key=5;
break;
case 0xbd:
key=6;
break;
case 0x7d:
key=7;
break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
display(key);
}
}
P3=0xfb;
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
delayms(10);
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xeb:
key=8;
break;
case 0xdb:
key=9;
break;
case 0xbb:
key=10;
break;
case 0x7b:
key=11;
break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
display(key);
}
}
P3=0xf7;
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
delayms(10);
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xe7:
key=12;
break;
case 0xd7:
key=13;
break;
case 0xb7:
key=14;
break;
case 0x77:
key=15;
break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
display(key);
}
}
}