1獨(dú)立按鍵
獨(dú)立按鍵模塊位置示意圖
硬件連接原理:
圖1.2獨(dú)立按鍵原理圖
把對(duì)應(yīng)的端口賦值高電平,即“1”,按鍵按下,端口被拉低至低電平,即“0”,通過(guò)檢測(cè)該端口的電平即可判斷按鍵是否按下。
去抖分析:
按鍵是機(jī)械器件,按下或者松開(kāi)時(shí)有固定的機(jī)械抖動(dòng),抖動(dòng)圖如下:
圖1.3按鍵抖動(dòng)示意圖
上圖看出按鍵按下和松開(kāi)的瞬間出現(xiàn)機(jī)械抖動(dòng),這個(gè)抖動(dòng)時(shí)間雖然很短,一般10~15ms,不同按鍵抖動(dòng)不同,但對(duì)應(yīng)單片機(jī)來(lái)說(shuō),很輕松就能檢測(cè)到,單片機(jī)是uS 級(jí)別。
但這個(gè)結(jié)果并不是我們需要的,實(shí)際上只進(jìn)行一次按鍵操作,但有可能執(zhí)行了多次按鍵結(jié)果,這就是抖動(dòng)造成的,所以大多數(shù)產(chǎn)品實(shí)際使用中都使用了按鍵去抖功能。
按鍵去抖分為硬件去抖和軟件去抖,硬件去抖最簡(jiǎn)單的就是按鍵2端并聯(lián)電容,容量根據(jù)實(shí)驗(yàn)而定。軟件去抖使用方便不增加硬件成本,容易調(diào)試,所以現(xiàn)在大都使用軟件去抖。
軟件去抖原理:
1、檢測(cè)到按鍵按下后進(jìn)行10~15ms 延時(shí),用于跳過(guò)這個(gè)抖動(dòng)區(qū)域;
2、延時(shí)后再檢測(cè)按鍵狀態(tài),如果沒(méi)有按下表明是抖動(dòng)或者干擾造成,如果仍舊按下,可以
認(rèn)為是真正的按下。并進(jìn)行對(duì)應(yīng)的操作。
3、同樣按鍵釋放后也要進(jìn)行去抖延時(shí),延時(shí)后檢測(cè)按鍵是否真正松開(kāi)。
程序樣例中沒(méi)有使用按鍵釋放去抖程序,用戶可以自行添加。
多數(shù)時(shí)候按鍵需要在釋放時(shí)才起作用,像電腦鼠標(biāo)一樣,這個(gè)時(shí)候需要檢測(cè)按鍵是否釋放,如果沒(méi)有釋放則一直等待。
獨(dú)立按鍵控制LED
程序如下圖:
/*-----------------------------------------------
名稱:獨(dú)立按鍵控制led
內(nèi)容:按一次按鍵,led點(diǎn)亮,再按一次熄滅,以此循環(huán)
------------------------------------------------*/
#include< reg52.h > //包含頭文件,一般情況不需要改動(dòng),頭文件包含特殊功能寄存器的定義
sbit KEY=P1^1; //定義按鍵輸入端口
sbit LED=P1^2; //定義led輸出端口
void DelayUs2x(unsigned char t);//函數(shù)聲明
void DelayMs(unsigned char t);
/*------------------------------------------------
主函數(shù)
------------------------------------------------*/
void main (void)
{
KEY=1; //按鍵輸入端口電平置高
while (1) //主循環(huán)
{
if(!KEY) //如果檢測(cè)到低電平,說(shuō)明按鍵按下
{
DelayMs(10); //延時(shí)去抖,一般10-20ms
if(!KEY) //再次確認(rèn)按鍵是否按下,沒(méi)有按下則退出
{
while(!KEY);//如果確認(rèn)按下按鍵等待按鍵釋放,沒(méi)有釋放則一直等待
{
LED=!LED;//釋放則執(zhí)行需要的程序
}
}
}
//主循環(huán)中添加其他需要一直工作的程序
}
}
/*------------------------------------------------
uS延時(shí)函數(shù),含有輸入參數(shù) unsigned char t,無(wú)返回值
unsigned char 是定義無(wú)符號(hào)字符變量,其值的范圍是
0~255 這里使用晶振12M,精確延時(shí)請(qǐng)使用匯編,大致延時(shí)
長(zhǎng)度如下 T=tx2+5 uS
------------------------------------------------*/
void DelayUs2x(unsigned char t)
{
while(--t);
}
/*------------------------------------------------
mS延時(shí)函數(shù),含有輸入?yún)?shù) unsigned char t,無(wú)返回值
unsigned char 是定義無(wú)符號(hào)字符變量,其值的范圍是
0~255 這里使用晶振12M,精確延時(shí)請(qǐng)使用匯編
------------------------------------------------*/
void DelayMs(unsigned char t)
{
while(t--)
{ //大致延時(shí)1mS
DelayUs2x(245);
DelayUs2x(245);
}
}
圖1.4獨(dú)立按鍵程序
接線方式:
實(shí)驗(yàn)現(xiàn)象:按一次按鍵,led點(diǎn)亮,再按一次熄滅,以此循環(huán)。
2矩陣鍵盤
圖2.1矩陣鍵盤模塊示意圖
矩陣鍵盤反轉(zhuǎn)掃描:
圖2.2矩陣鍵盤硬件原理圖
通過(guò)八個(gè)IO口控制16個(gè)按鍵,節(jié)省IO口。
重點(diǎn)是弄清基本原理,結(jié)合鍵盤掃描程序代碼分析、理解。
1.矩陣鍵盤逐行掃描(逐行掃描思路簡(jiǎn)單,但程序較長(zhǎng))
2.矩陣鍵盤反轉(zhuǎn)掃描(反轉(zhuǎn)掃描程序簡(jiǎn)短,思路巧妙)
本節(jié)著重講矩陣鍵盤的反轉(zhuǎn)掃描,逐行掃描將在外部中斷部分
程序如下:
/*-----------------------------------------------
名稱:矩陣鍵盤反轉(zhuǎn)掃描
------------------------------------------------*/
#include< reg52.h > //包含頭文件,一般情況不需要改動(dòng),頭文件包含特殊功能寄存器的定義
#define KeyPort P3
sbit dula=P2^1;
sbit wela=P2^0;
unsigned char code DuanMa[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
void DelayUs2x(unsigned char t);//us級(jí)延時(shí)函數(shù)聲明
void DelayMs(unsigned char t); //ms級(jí)延時(shí)
unsigned char KeyScan(void);//鍵盤掃描
unsigned char KeyPro(void);
void display(unsigned char aa);
/*------------------------------------------------
主函數(shù)
------------------------------------------------*/
void main (void)
{
unsigned char num;
dula=1;
P1=0x00;
dula=0;
wela=1;
P1=0x00;
wela=0;
while (1) //主循環(huán)
{
num=KeyPro();
if(num!=0xff)
{
display(num);
}
}
}
void display(unsigned char aa)
{
dula=1;
P1=DuanMa[aa];
dula=0;
}
/*------------------------------------------------
按鍵掃描函數(shù),返回掃描鍵值
------------------------------------------------*/
unsigned char KeyScan(void) //鍵盤掃描函數(shù),使用行列反轉(zhuǎn)掃描法
{
unsigned char cord_h,cord_l;//行列值中間變量
KeyPort=0x0f; //列線輸出全為0
cord_h=KeyPort&0x0f; //讀入行線值
if(cord_h!=0x0f) //先檢測(cè)有無(wú)按鍵按下
{
DelayMs(10); //去抖
if((KeyPort&0x0f)!=0x0f)
{
cord_h=KeyPort&0x0f; //讀入行線值
KeyPort=cord_h|0xf0; //輸出當(dāng)前列線值
cord_l=KeyPort&0xf0; //讀入列線值
while((KeyPort&0xf0)!=0xf0);//等待松開(kāi)并輸出
return(cord_h+cord_l);//鍵盤最后組合碼值
}
}return(0xff); //返回該值
}
/*------------------------------------------------
按鍵值處理函數(shù),返回掃鍵值
------------------------------------------------*/
unsigned char KeyPro(void)
{
switch(KeyScan())
{
case 0x7e:return 0;break;//0 按下相應(yīng)的鍵顯示相對(duì)應(yīng)的碼值
case 0x7d:return 1;break;//1
case 0x7b:return 2;break;//2
case 0x77:return 3;break;//3
case 0xbe:return 4;break;//4
case 0xbd:return 5;break;//5
case 0xbb:return 6;break;//6
case 0xb7:return 7;break;//7
case 0xde:return 8;break;//8
case 0xdd:return 9;break;//9
case 0xdb:return 10;break;//a
case 0xd7:return 11;break;//b
case 0xee:return 12;break;//c
case 0xed:return 13;break;//d
case 0xeb:return 14;break;//e
case 0xe7:return 15;break;//f
default:return 0xff;break;
}
}
/*------------------------------------------------
uS延時(shí)函數(shù),含有輸入?yún)?shù) unsigned char t,無(wú)返回值
unsigned char 是定義無(wú)符號(hào)字符變量,其值的范圍是
0~255 這里使用晶振12M,精確延時(shí)請(qǐng)使用匯編,大致延時(shí)
長(zhǎng)度如下 T=tx2+5 uS
------------------------------------------------*/
void DelayUs2x(unsigned char t)
{
while(--t);
}
/*------------------------------------------------
mS延時(shí)函數(shù),含有輸入?yún)?shù) unsigned char t,無(wú)返回值
unsigned char 是定義無(wú)符號(hào)字符變量,其值的范圍是
0~255 這里使用晶振12M,精確延時(shí)請(qǐng)使用匯編
------------------------------------------------*/
void DelayMs(unsigned char t)
{
while(t--)
{
//大致延時(shí)1mS
DelayUs2x(245);
DelayUs2x(245);
}
}
矩陣鍵盤反轉(zhuǎn)掃描程序
接線方式:
-
原理圖
+關(guān)注
關(guān)注
1299文章
6354瀏覽量
234692 -
單片機(jī)
+關(guān)注
關(guān)注
6040文章
44594瀏覽量
636963 -
矩陣鍵盤
+關(guān)注
關(guān)注
7文章
207瀏覽量
31510 -
獨(dú)立按鍵
+關(guān)注
關(guān)注
1文章
45瀏覽量
11588
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論