|
大家好,這段時(shí)間又重新在學(xué)習(xí)51單片機(jī),單片機(jī)這東東真的是要一直學(xué),一直做項(xiàng)目才行,之前做按鍵和數(shù)碼管顯示的時(shí)候,實(shí)際也只是了解了一點(diǎn)皮毛,再次深入學(xué)習(xí)后才體會(huì)到,要搞好這東東,真的要不同的思路去擴(kuò)展。先簡(jiǎn)單說(shuō)一下我的開發(fā)板硬件,數(shù)碼管采用兩片74HC573 來(lái)實(shí)現(xiàn),段選P26,位選P27,采用共陽(yáng)數(shù)碼管,在P0口送對(duì)應(yīng)數(shù)來(lái)實(shí)現(xiàn)數(shù)碼管的顯示;
四個(gè)獨(dú)立按鍵P32,P33,P34,P35,LED發(fā)光管有八個(gè),P10--P17,發(fā)光管在輸出低電平時(shí)點(diǎn)亮,
那么關(guān)于按鍵和數(shù)碼管的顯示,網(wǎng)上也有很多例子了。
第一類:關(guān)于延時(shí)的程序,如果采用延時(shí)消抖動(dòng),那么有可能按下后顯示不靈等,那么我建議用LED的顯示來(lái)抵消這個(gè)延時(shí)的做法,但一般項(xiàng)目的開法都不會(huì)用延時(shí)來(lái)消抖,在這里只是提供一個(gè)思路。
sbit KEY1 = P3^2; //假定P3^2代表KEY1鍵,按下為0
if(!KEY1 ) //表明有鍵按下
{
// Delayms(10); 一般情況下我們都用Delay 10ms 來(lái)消抖
為了程序的效率,和顯示等,我們這里可以用數(shù)碼管顯示的時(shí)間來(lái)抵消,
ledscan(); //數(shù)碼管一般也以10MS 100HZ無(wú)閃爍設(shè)計(jì)的。
if(!KEY1 )
{
while(!KEY1) //釋放消抖
{
KEY1 = 1; //先輸出高電平
ledscan(); //在等待的這個(gè)時(shí)間來(lái)顯示
}
// fun1(); 這里是我們按鍵按下的功能程序
}
}
第二類,我們直接以10MS定時(shí)器查詢來(lái)實(shí)現(xiàn),也可以采用定時(shí)器2MS,多讀數(shù)幾次,比如8次以上都是,則實(shí)現(xiàn)按鍵確認(rèn)
unsigned char KeySta[1] = //該定義屬于全局變量
{
0xff
};
//下面定義在定時(shí)器查詢程序里面
static unsigned char Keybuf[1] = //按鍵掃描緩沖區(qū),保存一段時(shí)間內(nèi)的掃描值
{
0xFF
};
Keybuf[0] = (Keybuf[0]<< 1) | KEY1; //KEY1 循環(huán)8次
if( Keybuf[0] ==0) //連續(xù)8次都是0
{
KeySta[0] = 0 ; //0表示有按下
}
else if( Keybuf[0] ==1) ///連續(xù)8次都是1
{
KeySta[0] = 1 ;
}
else //未穩(wěn)定狀態(tài),則不管他,這里是為了程序的完整性
{
}
}
第三類:采用狀態(tài)機(jī)的寫法
狀態(tài)機(jī)也是按10MS定時(shí)中斷去確認(rèn)按鍵狀態(tài),以使程序簡(jiǎn)化
unsigned char keycode = 0; //這個(gè)是全局變量,表示按鍵代碼
//下面在定時(shí)中斷10MS到的函數(shù)中實(shí)現(xiàn)
static unsigned char Key_state = 0;
unsigned char Keypress = 0xff; //未按下為0xff;
P3 = 0xff;
Keypress &= P3
switch(Key_state )
{
case 0:
if(Keypress!=0xff)//表示有鍵按下
{
Key_state = 1;//進(jìn)入S1
}
break;
case 1:
if(Keypress!=0xff) //表示確認(rèn)有鍵按下
{
Key_state = 2;//進(jìn)入S1
if( !KEY )
{
keycode = 0x01; //假如說(shuō)我們KEY1按下的代碼是0x01
}
}
else
{
Key_state = 0; //誤動(dòng)作,返回0
}
break;
case 2:
if(Keypress==0xff) //釋放
{
switch(keycode)
{
case 0x01: //按鍵KEY1的功能函數(shù)
break;
default:
break;
}
Key_state = 0; //如果有長(zhǎng)按,則可以進(jìn)入長(zhǎng)按的狀態(tài)等等。
}
else //等待釋放
{
Key_state = 2;
}
default:
break;
}
當(dāng)然為了減輕定時(shí)中斷的負(fù)擔(dān),關(guān)于按鍵功能的程序可在主程序中去執(zhí)行,在此不再詳述。
第四次:新型的TRG的寫法
核心算法如下: unsigned char Trg;
unsigned char Cont;
void KeyRead( void )
{
unsigned char ReadData =P3^0xff; // 1
Trg = ReadData & (ReadData ^Cont); // 2
Cont = ReadData; // 3
}
在定時(shí)中斷函數(shù)里每10MS去檢測(cè)一次按鍵情況,并執(zhí)行。
|
評(píng)分
-
查看全部評(píng)分
|