新聞中心

EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 51單片機(jī)識(shí)別四個(gè)獨(dú)立按鍵是短按還是長(zhǎng)按

51單片機(jī)識(shí)別四個(gè)獨(dú)立按鍵是短按還是長(zhǎng)按

作者: 時(shí)間:2014-01-13 來(lái)源:網(wǎng)絡(luò) 收藏
這是一個(gè)可以識(shí)別四個(gè)是短按還是長(zhǎng)按的參考程序,此程序已編譯通過(guò),初學(xué)者可以移植到上試試.
/********************************************/
//FileName:識(shí)別四個(gè)是短按還是長(zhǎng)按
//Function: 不同按鍵 短按或長(zhǎng)按分別顯示不同的LED
//author:liu yong
//QQ:545018331
//Date:2013/03/13
/********************************************/
#include PIC.H>
__CONFIG(0X3B31);
#define uint8 unsigned char
unsigned int time_10ms_ok=0;
uint8 KeyValue;
bit KeyShortpressFlag,KeyLongpressFlag;
//=========定義長(zhǎng)按鍵斷口的及連發(fā)間隔的=======//
#define KEY_LONG_PERIOD 200
//=========定義按鍵斷口=======//
#define io_key_1 RB0
#define io_key_2 RB1
#define io_key_3 RB2
#define io_key_4 RB3
//=========定義按鍵鍵值=======//
#define KEY_VALUE_1 0X0e
#define KEY_VALUE_2 0X0d
#define KEY_VALUE_3 0X0b
#define KEY_VALUE_4 0X07
#define KEY_NULL 0X0f

//=========定義按鍵返回值狀態(tài)(按下,長(zhǎng)按,連發(fā),釋放)=======//
#define KEY_SHORT 0X80
#define KEY_LONG 0X40

//=========定義按鍵狀態(tài)=======//
#define KEY_STATE_INIT 0
#define KEY_STATE_WOBBLE 1
#define KEY_STATE_PRESS 2
#define KEY_STATE_LONG 3
#define KEY_STATE_RELEASE 4

void initial(void)
{
TRISB=0xff;
TRISC=0;
PORTC=0XFF;
RBPU=0;
T1CON=0X01;//1:1
TMR1H=-(10000 >> 8);
TMR1L=-(10000 0XFF);
TMR1IF=0;
TMR1IE=1;
INTCON=0XC0;
}
void interrupt timer1_isr(void) // 定時(shí)器10ms中斷服務(wù)
{
if(TMR1IF)
{
TMR1H=-(10000 >> 8);
TMR1L=-(10000 0XFF);
time_10ms_ok = 1;
TMR1IF=0;
}
}

void KeyInit(void)
{
io_key_1 = 1;
io_key_2 = 1;
io_key_3 = 1;
io_key_4 = 1;
}
uint8 KeyScan(void)
{
if(io_key_1 == 0)return KEY_VALUE_1;
if(io_key_2 == 0)return KEY_VALUE_2;
if(io_key_3 == 0)return KEY_VALUE_3;
if(io_key_4 == 0)return KEY_VALUE_4;
return KEY_NULL;
}
uint8 GetKey(void)
{
static uint8 s_u8KeyState = KEY_STATE_INIT ;
static uint8 s_u8KeyTimeCount = 0;
uint8 i ;
uint8 KeyTemp=KEY_NULL;
KeyTemp = KeyScan();//0x0e 0f
switch(s_u8KeyState)
{
case KEY_STATE_INIT:
{
if(KEY_NULL != KeyTemp)
{
s_u8KeyState = KEY_STATE_WOBBLE ;
}
}
break;

case KEY_STATE_WOBBLE:
{
s_u8KeyState = KEY_STATE_PRESS ;
}
break;
case KEY_STATE_PRESS://識(shí)別哪個(gè)鍵
{
if(KEY_NULL != KeyTemp) // KeyTemp=0x0e short press
{
s_u8KeyState = KEY_STATE_LONG ;
i=KeyTemp;//0x0e
}
else
{
s_u8KeyState = KEY_STATE_INIT;
}
}
break;
case KEY_STATE_LONG: //判斷按鍵是短按還是長(zhǎng)按
{
if(KEY_NULL != KeyTemp)
{
if(++s_u8KeyTimeCount > KEY_LONG_PERIOD)
{
s_u8KeyTimeCount = 0;
KeyLongpressFlag=1;
KeyShortpressFlag=0;
s_u8KeyState = KEY_STATE_RELEASE;
}
}
else
{
s_u8KeyTimeCount = 0;
KeyShortpressFlag=1;
KeyLongpressFlag=0;
s_u8KeyState = KEY_STATE_RELEASE;
}
}
break;
case KEY_STATE_RELEASE://按鍵釋放去抖
{
if(KEY_NULL == KeyTemp) //此語(yǔ)句必須加上去不然程序不穩(wěn)定
{
if(KeyShortpressFlag)
{
KeyShortpressFlag=0;
i=i | KEY_SHORT;//0x0e | 0x80=0x8e
s_u8KeyState = KEY_STATE_INIT;
}
if(KeyLongpressFlag)
{
KeyLongpressFlag=0;
i=i | KEY_LONG;
s_u8KeyState = KEY_STATE_INIT;
}
}
}
break;
default:break;
}
return i;
}

void main(void)
{
initial();
KeyInit();
while(1)
{
if (time_10ms_ok) //每10ms執(zhí)行一次,
{
time_10ms_ok =0;
KeyValue=GetKey();
if(KeyValue == (KEY_VALUE_1 | KEY_SHORT)) PORTC = ~1;
if(KeyValue == (KEY_VALUE_1 | KEY_LONG)) PORTC = ~3;
if(KeyValue == (KEY_VALUE_2 | KEY_SHORT))PORTC = ~7;
if(KeyValue == (KEY_VALUE_2 | KEY_LONG)) PORTC = ~0X0F;
if(KeyValue == (KEY_VALUE_3 | KEY_SHORT))PORTC = ~0X1F;
if(KeyValue == (KEY_VALUE_3 | KEY_LONG)) PORTC = ~0X3F;
if(KeyValue == (KEY_VALUE_4 | KEY_SHORT)) PORTC = ~0X7F;
if(KeyValue == (KEY_VALUE_4 | KEY_LONG)) PORTC = ~0XFF;
}
}
}

51單片機(jī)相關(guān)文章:51單片機(jī)教程




評(píng)論


相關(guān)推薦

技術(shù)專(zhuān)區(qū)

關(guān)閉