在公司看到一段关于按键去抖动方面的程序感觉设计比较好,贴出来分享一下。
废话少说上代码:按键处理要求,处理函数在10ms的timer 中断内运行 ,连续三次(10ms*3)检测到按键按下状态,判断按键为短按,按键按下持续10ms*200判断为长按(包括防反跳时间),连续三次(10ms*3)检测到按键松开状态,判断按键为抬起。
#define KEY_DEBOUNCE_NUM 3
#define KEY_LONG_PRESS_NUM (200 - KEY_DEBOUNCE_NUM)
#define KEY_SW_NUM 2
/* SW State Define */
typedef enum
{
KEY_SW_OFF=0,
KEY_SW_ON,
KEY_SW_ON_2_SEC
}SW_State_t;
SW_State_t KeySW6;
SW_State_t KeySW5;
typedef struct
{
unsigned char SWStatus[KEY_SW_NUM];
unsigned char LongSWStatus[KEY_SW_NUM];
unsigned char* SwitchProcess[KEY_SW_NUM];
}Switch_Status_t;
static Switch_Status_t SwitchStatus;
typedef struct
{
unsigned char* Port ;
unsigned char Pin;
}Switch_Input_t;
static Switch_Input_t SwitchInput[KEY_SW_NUM] =
{
//pin的第6位 pin的第7位
{(unsigned char*)&P2IN,6}, {(unsigned char*)&P2IN,7}
};
#pragma vector=TIMER0_B0_VECTOR
__interrupt void TIMER1_B0_ISR(void) //10timer interrupt
{
KeyHandle(0);
}
void KeyInit()
{
int temp;
PortInit();
KeySW6 = KEY_SW_OFF;
KeySW5 = KEY_SW_OFF;
SwitchStatus.SwitchProcess[0] = (unsigned char*)&KeySW6;
SwitchStatus.SwitchProcess[1] = (unsigned char*)&KeySW5;
}
void KeyHandle(void *UserParameter)
{
int temp;
for(temp = 0;temp < KEY_SW_NUM;temp++){
if(!((*SwitvhInput[temp].Port >> SwitvhInput[temp].Pin) & 0x01)){
if(SwitchStatus.SWStatus[temp] < KEY_DEBOUNCE_NUM){
SwitchStatus.SWStatus[temp]++;
}else{
SwitchStatus.SWStatus[temp] = 0xff;
SwitchStatus.SwitchProcess[temp]= KEY_SW_ON;
if(SwitchStatus.LongSWStatus[temp] < KEY_LONG_PRESS_NUM){
SwitchStatus.LongSWStatus[temp]++;
}else{
SwitchStatus.SwitchProcess[temp]= KEY_SW_ON_2_SEC;
}
}
}else{
if(SwitchStatus.SWStatus[temp] > (0xff - KEY_DEBOUNCE_NUM)){
SwitchStatus.SWStatus[temp]--;
}else{
SwitchStatus.SWStatus[temp] = 0x00;
SwitchStatus.LongSWStatus[temp] = 0x00;
}
}
}
}