單片機(jī)鍵盤(pán)的操作
鍵盤(pán)的應(yīng)用和分類(lèi):
鍵盤(pán)分為編碼鍵盤(pán)和非編碼鍵盤(pán),鍵盤(pán)上閉合鍵的識(shí)別是由專(zhuān)門(mén)的硬件編碼器實(shí)現(xiàn),并產(chǎn)生鍵編碼號(hào)或者是鍵值的成為編碼鍵盤(pán),如計(jì)算機(jī)的鍵盤(pán)
靠軟件編程來(lái)識(shí)別的稱(chēng)為非編碼鍵盤(pán);
在單片機(jī)組成的各種系統(tǒng)中,用的最多的是非編碼鍵盤(pán),也有用到編碼鍵盤(pán)的
非編碼鍵盤(pán)又有獨(dú)立鍵盤(pán)和矩陣鍵盤(pán)。
要先像鍵盤(pán)里面先寫(xiě)1;在讀取操作
示例代碼:
#include
#define uint unsigned int
#define uchar unsigned char
sbit ld1 = P1^0;
sbit key1 = P3^4;
sbit dula = P2^6;
sbit wela = P2^7;
uchar num;
uchar code table[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
void display(num);
main()
{
P3 = 0xff;
while(1)
{
display(num);
if(key1==0)
{
ld1 = 0;
num++;
if(num==10)
num = 0;
while(key1!=1);//松手檢測(cè)
}
else
ld1 = 1;
}
}
void display(num)
{
wela = 1;
P0 = 0xfe;
wela = 0;
P0 = 0x0;
dula = 1;
P0 = table[num];
dula = 0;
dula = 1;//關(guān)燈操作
P0 = 0x0;
dula = 0;
}
View Code
這個(gè)程序看上去無(wú)懈可擊,但是在實(shí)際過(guò)程中,有一個(gè)相當(dāng)大打bug,那就是,你按住鍵盤(pán)的時(shí)候,數(shù)碼管不顯示數(shù)字,這不是很坑爹,所以,位選信號(hào)是開(kāi)始就要打開(kāi)的正確的代碼是
#include
#define uint unsigned int
#define uchar unsigned char
sbit ld1 = P1^0;
sbit key1 = P3^4;
sbit dula = P2^6;
sbit wela = P2^7;
uchar num;
uchar code table[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
void display(num);
main()
{
P3 = 0xff;
wela = 1;
P0 = 0xfe;//打開(kāi)位選線
wela = 0;
while(1)
{
if(key1==0)
{
ld1 = 0;
num++;
if(num==10)
num = 0;
while(key1!=1);//松手檢測(cè)
}
else
ld1 = 1;
dula = 1;
P0 = table[num];//在循環(huán)中不斷送入段選
dula = 0;
}
}
去抖:由于按鍵接觸的時(shí)候會(huì)出現(xiàn)抖動(dòng),所以,要進(jìn)行去抖操作
去抖有硬件消抖和軟件消抖
硬件消抖要用專(zhuān)門(mén)的硬件消抖電路,導(dǎo)致外部電路復(fù)雜,在單片機(jī)中用不著
軟件消抖,一般是延時(shí)5毫秒檢測(cè)
#include
#define uint unsigned int
#define uchar unsigned char
sbit ld1 = P1^0;
sbit key1 = P3^4;
sbit dula = P2^6;
sbit wela = P2^7;
uchar num;
uchar code table[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
void delay(uint x);
main()
{
P3 = 0xff;
wela = 1;
P0 = 0xfe;//打開(kāi)位選線
wela = 0;
while(1)
{
if(key1==0)
{
delay(10);//延時(shí)十毫秒
if(key1 == 0)//確實(shí)按下去了
{
ld1 = 0;
num++;
if(num==10)
num = 0;
while(key1!=1);//松手檢測(cè)
delay(10); //檢測(cè)是否松手
while(!key1);
}
}
else
ld1 = 1;
dula = 1;
P0 = table[num];//在循環(huán)中不斷送入段選
dula = 0;
}
}
void delay(uint x)
{
uint y,z;
for(y=x;y>0;y--)
for(z=110;z>0;z--);
}
矩陣鍵盤(pán):無(wú)論是矩陣鍵盤(pán)還是獨(dú)立鍵盤(pán),單片機(jī)檢測(cè)其是否被按下去的依據(jù)都是一樣的,也就是檢測(cè)該鍵盤(pán)對(duì)應(yīng)的I/O口是否為低電平,獨(dú)立鍵盤(pán)有一段固定是低電平,單片機(jī)寫(xiě)程序時(shí)檢測(cè)比較方便,電路時(shí)矩陣鍵盤(pán)的兩端都與單片機(jī)deI/O口相連,因此在檢測(cè)時(shí),先送入一列為低電平,其余的全部為高電平,此時(shí)我們確定了列數(shù),然后立即輪流檢測(cè)一次各行是否有低電平,檢測(cè)到某一行為低電平(這是我們有確定了行數(shù)),著我們便可確定是哪一行哪一列的按鍵被按下去。
示例代碼:
#include
sbit wela =P2^6;
sbit dula = P2^7;
#define uchar unsigned char
#define uint unsigned int
void delay(uint z);
uchar num,num1,temp;
uchar keyscan();
uchar code table[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,0x0};
main()
{
wela = 1;
P0 = 0x0;
wela = 0;
while(1)
{
num1 = keyscan();
dula =1;
P0 = table[num1];
dula = 0;
}
}
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
uchar keyscan()
{
P3 = 0xfe;//1111 1110
temp = P3;
temp = temp&0xf0;//11110000
while(temp!=0xf0)//如果有鍵摁下
{
delay(5);//再次檢測(cè)P3口
temp = P3;
temp = temp&0xf0;
while(temp!=0xf0)
{
temp = P3;
switch(temp)
{
case 0x7e:num = 1;
break;
case 0xbe:num = 2;
break;
case 0xde:num = 3;
break;
case 0xee:num = 4;
break;
}
while(temp!=0xf0)//松手檢測(cè)
{
temp = P3;
temp = temp&0xf0;
}
}
}
P3 = 0xfd;//1111 1101
temp = P3;
temp = temp&0xf0;//11110000
while(temp!=0xf0)//如果有鍵摁下