基于單片機接矩陣鍵盤原理
單片機與矩陣鍵盤連接如下圖:
此圖用P1口P1.0---P1.3接4行P1.4--P1.7接4列
矩陣鍵盤工作原理:由于按鍵沒有接地,4行4列正好占用8個I/O如果4行我們送P3.0到P3.3送入0111然后去讀取4列的值,如果P3.0的按鍵按下那么P3.4---P3.7的值等于0111,假如是第2個鍵按下的話那么讀回來的值是1011,如果第3個鍵按下去讀回來的值是1101,如果第4個鍵按下去讀回來的值是1110,如果沒有鍵按下去讀回來就是1111。所以我們就根據(jù)讀回來的值來判斷按下去的是那個鍵。當然這是對P3.0這一行,因為矩陣鍵盤是掃描的,所以下次把P3.0給1P3.1給0對第2行,陸續(xù)的第3行第4行,0111101111011110而每次都去從新掃描一遍列值列有4個值,以確定是那個鍵按下。無論何時任何一個時間有一個按鍵被按下就跳出循環(huán)。當然不可能有2個鍵剛好一起按下你的手沒有這么好的力度,就算有2個鍵一起按鍵,程序也有先后檢測的順序,只能檢測一個后面的檢測不到。
P3=0XFE;//第一行給0
temp;定義個變量
temp=P3;讀回來由于讀需要先寫1因為P3=FE已經(jīng)把高4位給1了所以能讀了
temp&oxf0如果沒有按鍵按下結(jié)果還是0xf0。如果有鍵按下結(jié)果就不是0xf0了。
num然后我們再定義一個變量讓它賦值給這個按下去的按鍵值。
一次類推把第一行賦值0掃描一遍然后把第2行賦值0掃描一遍。。。。。。。。。。。。。。共掃描16遍。
只要有鍵按下就會得到一個值num就從1排到16.共16個按鍵4*4的矩陣鍵盤。
我再總結(jié)下思路:
首先低4位是行共4行分別把每行給0低電平就4次0111、1011、1101、1110對吧
然后去檢測高4位4列啊先不考慮極端情況,4列就4個按鍵只要按下一個P3口的高4位就會有一個值。根據(jù)這個值就能判斷是那個鍵了。
如:P3=11111110低四位是行先把第一行給0
有按鍵下的話temp=P3讀回來11011110然后temp&0xf0與運算下就判斷下還等于oxf0嗎?如還等于就沒有按下,如果不等于就肯定有按鍵按下。定義個變量讓它等于這個不是0XF0的值,做個標記。依次類推。
單片機8x8矩陣鍵盤原理說明
小編使用proteus模擬了一個8x8的矩陣鍵盤。以下是原理圖:
啟動后的原來圖,還沒有按鍵按下:
再來一張,有按鍵按下的情況:
代碼如下:
#include《reg52.h》
#defineucharunsignedchar
#defineuintunsignedint
//共陰極數(shù)碼管0~9
ucharcodetable[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uchartmp;//暫存P2的值
ucharkeynum;//按鍵值
ucharshi,ge;//數(shù)碼管個位和十位顯示
sbitP36=P3^6;//數(shù)碼管時能端
sbitP37=P3^7;
//數(shù)碼管顯示聲明
voiddisplay();
//毫秒級延時
voiddelay(uintz)
{
uintx,y;
for(x=z;x》0;x--)
for(y=110;y》0;y--);
}
voidkeyscan()
{
P0=0xfe;//掃描第1行
if(P2!=0xff)//有按鍵按下
{
tmp=P2;
delay(5);
if(P2!=0xff)//延時后確定有按鍵按下
{
switch(tmp)
{
case0xfe:keynum=1;break;//第1行第1個按鍵按下
case0xfd:keynum=2;break;//第1行第2個按鍵按下
case0xfb:keynum=3;break;//第1行第3個按鍵按下
case0xf7:keynum=4;break;//第1行第4個按鍵按下
case0xef:keynum=5;break;//第1行第5個按鍵按下
case0xdf:keynum=6;break;//第1行第6個按鍵按下
case0xbf:keynum=7;break;//第1行第7個按鍵按下
case0x7f:keynum=8;break;//第1行第8個按鍵按下
}
while(tmp!=0xff)//等待按鍵松手
{
tmp=P2;
display();
}
}
}
delay(5);
P0=0xfd;//掃描第2行
if(P2!=0xff)//有按鍵按下
{
tmp=P2;
delay(5);
if(P2!=0xff)//延時后確定有按鍵按下
{
switch(tmp)
{
case0xfe:keynum=9;break;//第2行第1個按鍵按下
case0xfd:keynum=10;break;//第2行第2個按鍵按下
case0xfb:keynum=11;break;//第2行第3個按鍵按下
case0xf7:keynum=12;break;//第2行第4個按鍵按下
case0xef:keynum=13;break;//第2行第5個按鍵按下
case0xdf:keynum=14;break;//第2行第6個按鍵按下
case0xbf:keynum=15;break;//第2行第7個按鍵按下
case0x7f:keynum=16;break;//第2行第8個按鍵按下
}
while(tmp!=0xff)
{
tmp=P2;
display();
}
}
}
delay(5);
P0=0xfb;//掃描第3行
if(P2!=0xff)//有按鍵按下
{
tmp=P2;
delay(5);
if(P2!=0xff)//延時后確定有按鍵按下
{
switch(tmp)
{
case0xfe:keynum=17;break;//第3行第1個按鍵按下
case0xfd:keynum=18;break;//第3行第2個按鍵按下
case0xfb:keynum=19;break;//第3行第3個按鍵按下
case0xf7:keynum=20;break;//第3行第4個按鍵按下
case0xef:keynum=21;break;//第3行第5個按鍵按下
case0xdf:keynum=22;break;//第3行第6個按鍵按下
case0xbf:keynum=23;break;//第3行第7個按鍵按下
case0x7f:keynum=24;break;//第3行第8個按鍵按下
}
while(tmp!=0xff)
{
tmp=P2;
display();
}
}
}
delay(5);
P0=0xf7;//掃描第4行
if(P2!=0xff)//有按鍵按下
{
tmp=P2;
delay(5);
if(P2!=0xff)//延時后確定有按鍵按下
{
switch(tmp)
{
case0xfe:keynum=25;break;//第4行第1個按鍵按下
case0xfd:keynum=26;break;//第4行第2個按鍵按下
case0xfb:keynum=27;break;//第4行第3個按鍵按下
case0xf7:keynum=28;break;//第4行第4個按鍵按下
case0xef:keynum=29;break;//第4行第5個按鍵按下
case0xdf:keynum=30;break;//第4行第6個按鍵按下
case0xbf:keynum=31;break;//第4行第7個按鍵按下
case0x7f:keynum=32;break;//第4行第8個按鍵按下
}
while(tmp!=0xff)
{
tmp=P2;
display();
}
}
}
delay(5);
P0=0xef;//掃描第5行
if(P2!=0xff)//有按鍵按下
{
tmp=P2;
delay(5);
if(P2!=0xff)//延時后確定有按鍵按下
{
switch(tmp)
{
case0xfe:keynum=33;break;//第5行第1個按鍵按下
case0xfd:keynum=34;break;//第5行第2個按鍵按下
case0xfb:keynum=35;break;//第5行第3個按鍵按下
case0xf7:keynum=36;break;//第5行第4個按鍵按下
case0xef:keynum=37;break;//第5行第5個按鍵按下
case0xdf:keynum=38;break;//第5行第6個按鍵按下
case0xbf:keynum=39;break;//第5行第7個按鍵按下
case0x7f:keynum=40;break;//第5行第8個按鍵按下
}
while(tmp!=0xff)
{
tmp=P2;
display();
}
}
}
delay(5);
P0=0xdf;//掃描第6行
if(P2!=0xff)//有按鍵按下
{
tmp=P2;
delay(5);
if(P2!=0xff)//延時后確定有按鍵按下
{
switch(tmp)
{
case0xfe:keynum=41;break;//第6行第1個按鍵按下
case0xfd:keynum=42;break;//第6行第2個按鍵按下
case0xfb:keynum=43;break;//第6行第3個按鍵按下
case0xf7:keynum=44;break;//第6行第4個按鍵按下
case0xef:keynum=45;break;//第6行第5個按鍵按下
case0xdf:keynum=46;break;//第6行第6個按鍵按下
case0xbf:keynum=47;break;//第6行第7個按鍵按下
case0x7f:keynum=48;break;//第6行第8個按鍵按下
}
while(tmp!=0xff)
{
tmp=P2;
display();
}
}
}
delay(5);
P0=0xbf;//掃描第7行
if(P2!=0xff)//有按鍵按下
{
tmp=P2;
delay(5);
if(P2!=0xff)//延時后確定有按鍵按下
{
switch(tmp)
{
case0xfe:keynum=49;break;//第7行第1個按鍵按下
case0xfd:keynum=50;break;//第7行第2個按鍵按下
case0xfb:keynum=51;break;//第7行第3個按鍵按下
case0xf7:keynum=52;break;//第7行第4個按鍵按下
case0xef:keynum=53;break;//第7行第5個按鍵按下
case0xdf:keynum=54;break;//第7行第6個按鍵按下
case0xbf:keynum=55;break;//第7行第7個按鍵按下
case0x7f:keynum=56;break;//第7行第8個按鍵按下
}
while(tmp!=0xff)
{
tmp=P2;
display();
}
}
}
delay(5);
P0=0x7f;//掃描第8行
if(P2!=0xff)//有按鍵按下
{
tmp=P2;
delay(5);
if(P2!=0xff)//延時后確定有按鍵按下
{
switch(tmp)
{
case0xfe:keynum=57;break;//第8行第1個按鍵按下
case0xfd:keynum=58;break;//第8行第2個按鍵按下
case0xfb:keynum=59;break;//第8行第3個按鍵按下
case0xf7:keynum=60;break;//第8行第4個按鍵按下
case0xef:keynum=61;break;//第8行第5個按鍵按下
case0xdf:keynum=62;break;//第8行第6個按鍵按下
case0xbf:keynum=63;break;//第8行第7個按鍵按下
case0x7f:keynum=64;break;//第8行第8個按鍵按下
}
while(tmp!=0xff)
{
tmp=P2;
display();
}
}
}
delay(5);
}
voiddisplay()
{
//顯示個位
P37=0;
P1=table[ge];
delay(5);
P37=1;
//顯示十位
P36=0;
P1=table[shi];
delay(5);
P36=1;
}
voidmain()
{
while(1)
{
shi=keynum/10;
ge=keynum;
keyscan();
display();//這里的顯示是保存上一次的顯示值
}
}
-
單片機
+關(guān)注
關(guān)注
6030文章
44489瀏覽量
631958 -
矩陣鍵盤
+關(guān)注
關(guān)注
7文章
206瀏覽量
31410
發(fā)布評論請先 登錄
相關(guān)推薦
評論