复杂按键事件识别程序(链接层)
复杂按键包括多个按键的单按事件、长按事件、连按事件、组合按键事件等
本程序为链接层程序,处理和识别按键驱动层扫描到的按键信息g_u8KeyValue。(g_u8KeyValue的每一位表示一个按键)
单按事件在按下键松开时判定,其它按键情况在达到规定的时间后触发相应按键事件。
宏定义:
//宏定义各按键按下时的bit值 #define KEY_EVENT_NULL_CLICK 0x00 #define KEY_EVENT_CLOCK_CLICK 0x01 #define KEY_EVENT_DOWN_CLICK 0x02 #define KEY_EVENT_MODE_CLICK 0x04 #define KEY_EVENT_LOCK_CLICK 0x08 #define KEY_EVENT_ONOFF_CLICK 0x10 #define KEY_EVENT_SETTING_CLICK 0x20 #define KEY_EVENT_UP_CLICK 0x40 #define KEY_EVENT_TIMING_CLICK 0x80 #define KEY_EVENT_LONG_KEY_CLICK 0xff //长按标志 //组合键 #define KEY_EVENT_SETTING_UP_CLICK 0x60 #define KEY_EVENT_SETTING_ONOFF_CLICK 0x30 #define Key_EVENT_MODE_UP_DOWN_CLICK 0x46 #define KEY_PRESS_TIME 80 //单按按键事件按下的时间 #define KEY_SINGLE_TIME 1000 u8 g_u8KeyValue;
/*******************************************************************************
#Function : Link_KeyTrans
#Description : 按键转换 g_u8KeyValue 为 按键扫描出来的键值 即标志该时刻对应按键是否按下
#Parameter : NULL
#Return : NULL
#AuthorAndData : huangzhigang 20140716
*******************************************************************************/
void Link_KeyTrans(void)
{
static uint8_t KeyBackUp = KEY_EVENT_NULL_CLICK; //键值备份
static TIMER_T KeyDelayTime;
App_TimeBase(MS_BASE, &KeyDelayTime);
if(g_u8KeyValue == KEY_EVENT_SETTING_UP_CLICK) //设置+上 组合键3s
{
if((KeyBackUp == KEY_EVENT_SETTING_CLICK || KeyBackUp == KEY_EVENT_UP_CLICK) && KeyDelayTime.DelayTime <= 500)
{
KeyBackUp = KEY_EVENT_SETTING_UP_CLICK;
KeyDelayTime.DelayTime = 0;
}
else if(KeyDelayTime.DelayTime>=3000 && KeyBackUp==KEY_EVENT_SETTING_UP_CLICK)
{
KeyDelayTime.DelayTime = 0;
g_KeyEvent = KeyValueSettingUp3s;
KeyBackUp = KEY_EVENT_LONG_KEY_CLICK;
}
}
else if(g_u8KeyValue == KEY_EVENT_SETTING_ONOFF_CLICK) //设置+开关 组合键5s
{
if((KeyBackUp == KEY_EVENT_SETTING_CLICK || KeyBackUp == KEY_EVENT_ONOFF_CLICK) && KeyDelayTime.DelayTime <= 500)
{
KeyBackUp = KEY_EVENT_SETTING_ONOFF_CLICK;
KeyDelayTime.DelayTime = 0;
}
else if(KeyDelayTime.DelayTime>=5000 && KeyBackUp == KEY_EVENT_SETTING_ONOFF_CLICK)
{
KeyDelayTime.DelayTime = 0;
g_KeyEvent = KeyValueSettingOnOff5s;
KeyBackUp = KEY_EVENT_LONG_KEY_CLICK;
}
}
else if(g_u8KeyValue == Key_EVENT_MODE_UP_DOWN_CLICK) //MODE+UP+DOWN 组合键3s
{
if((KeyBackUp == KEY_EVENT_MODE_CLICK || KeyBackUp == KEY_EVENT_UP_CLICK || KeyBackUp == KEY_EVENT_DOWN_CLICK) && KeyDelayTime.DelayTime <= 500)
{
KeyBackUp = Key_EVENT_MODE_UP_DOWN_CLICK;
KeyDelayTime.DelayTime = 0;
}
else if(KeyDelayTime.DelayTime>=3000 && KeyBackUp == Key_EVENT_MODE_UP_DOWN_CLICK)
{
KeyDelayTime.DelayTime = 0;
g_KeyEvent = KeyValueModeUpDown3s;
KeyBackUp = KEY_EVENT_LONG_KEY_CLICK;
}
}
else if(g_u8KeyValue == KEY_EVENT_ONOFF_CLICK && (!KeyBackUp|| KeyBackUp == KEY_EVENT_ONOFF_CLICK)) //长按OnOff键 1s
{
KeyBackUp = KEY_EVENT_ONOFF_CLICK;
if(KeyDelayTime.DelayTime >= 1000)
{
//OnOff键 长按1S条件成立
g_KeyEvent = KeyValueOnOff1s;
KeyBackUp = KEY_EVENT_LONG_KEY_CLICK;
}
}
else if(g_u8KeyValue == KEY_EVENT_LOCK_CLICK && (!KeyBackUp|| KeyBackUp == KEY_EVENT_LOCK_CLICK)) //长按LOCK键 1s
{
KeyBackUp = KEY_EVENT_LOCK_CLICK;
if(KeyDelayTime.DelayTime >= 1000)
{
//LOCK键 长按1S条件成立
g_KeyEvent = KeyValueLock1s;
KeyBackUp = KEY_EVENT_LONG_KEY_CLICK;
}
}
else if(g_u8KeyValue == KEY_EVENT_UP_CLICK &&(!KeyBackUp || KeyBackUp == KEY_EVENT_UP_CLICK)) //UP 长按
{
KeyBackUp = KEY_EVENT_UP_CLICK;
if(g_SystemDisplayStatus != MainInterface) //不在主界面下可以连按
{
if(KeyDelayTime.DelayTime >= 1000)
{
g_b1UpDownLongPressFlag = 1;
g_KeyEvent = KeyValueUp;
KeyDelayTime.DelayTime = 0;
}
else if(KeyDelayTime.DelayTime >= 250 && g_b1UpDownLongPressFlag) //1秒长按等于单按4次
{
g_KeyEvent = KeyValueUp;
KeyDelayTime.DelayTime = 0;
}
}
else if(g_SystemDisplayStatus == MainInterface) //在主界面下可以设置模式状态
{
if(g_b1OnOffStatusFlag)
{
if(KeyDelayTime.DelayTime >= 3000) //开机状态下长按3s
{
g_KeyEvent = KeyValueUp3s;
KeyBackUp = KEY_EVENT_LONG_KEY_CLICK;
}
}
else
{
if(KeyDelayTime.DelayTime >= 10000) //关机状态下长按10s
{
g_KeyEvent = KeyValueUp10s;
KeyBackUp = KEY_EVENT_LONG_KEY_CLICK;
}
}
}
}
else if(g_u8KeyValue == KEY_EVENT_DOWN_CLICK && (!KeyBackUp ||KeyBackUp == KEY_EVENT_DOWN_CLICK)) //DOWN 连按
{
KeyBackUp = KEY_EVENT_DOWN_CLICK;
if(g_SystemDisplayStatus != MainInterface)
{
if(KeyDelayTime.DelayTime >= 1000)
{
g_b1UpDownLongPressFlag = 1;
g_KeyEvent = KeyValueDown;
KeyDelayTime.DelayTime = 0;
}
else if(KeyDelayTime.DelayTime >= 250 && g_b1UpDownLongPressFlag) //1秒长按等于单按4次
{
g_KeyEvent = KeyValueDown;
KeyDelayTime.DelayTime = 0;
}
}
}
else if(g_u8KeyValue == KEY_EVENT_MODE_CLICK &&
(!KeyBackUp|| KeyBackUp == KEY_EVENT_MODE_CLICK)) //MODE 长按3s
{
KeyBackUp = KEY_EVENT_MODE_CLICK;
if(KeyDelayTime.DelayTime >= 3000)
{
g_KeyEvent = KeyValueMode3s;
KeyBackUp = KEY_EVENT_LONG_KEY_CLICK;
}
}
else if(g_u8KeyValue == KEY_EVENT_CLOCK_CLICK &&
(!KeyBackUp|| KeyBackUp == KEY_EVENT_CLOCK_CLICK)) //CLOCK 长按3s
{
KeyBackUp = KEY_EVENT_CLOCK_CLICK;
if(KeyDelayTime.DelayTime >= 3000)
{
g_KeyEvent = KeyValueClock3s;
KeyBackUp = KEY_EVENT_LONG_KEY_CLICK;
}
}
else if(g_u8KeyValue == KEY_EVENT_SETTING_CLICK &&
(!KeyBackUp|| KeyBackUp == KEY_EVENT_SETTING_CLICK)) //SETTING 长按3s
{
KeyBackUp = KEY_EVENT_SETTING_CLICK;
if(KeyDelayTime.DelayTime >= 3000)
{
g_KeyEvent = KeyValueSetting3s;
KeyBackUp = KEY_EVENT_LONG_KEY_CLICK;
}
}
else if(g_u8KeyValue == KEY_EVENT_TIMING_CLICK && (!KeyBackUp)) //TIMING 单键
{
KeyBackUp = KEY_EVENT_TIMING_CLICK;
}
else if(g_u8KeyValue == KEY_EVENT_NULL_CLICK) //无键按下是判断上一次按键
{
switch(KeyBackUp)
{
case KEY_EVENT_UP_CLICK:
if(g_b1UpDownLongPressFlag == 1)
{
g_b1UpDownLongPressFlag = 0;
g_b1BuzzerOnFlag = 1;
}
else if(KeyDelayTime.DelayTime > KEY_PRESS_TIME && KeyDelayTime.DelayTime < KEY_SINGLE_TIME) //^单键按下
{
//单键按下条件成立
g_KeyEvent = KeyValueUp;
}
KeyBackUp = KEY_EVENT_NULL_CLICK;
KeyDelayTime.DelayTime = 0;
break;
case KEY_EVENT_DOWN_CLICK:
if(g_b1UpDownLongPressFlag == 1)
{
g_b1UpDownLongPressFlag = 0;
g_b1BuzzerOnFlag = 1;
}
else if(KeyDelayTime.DelayTime > KEY_PRESS_TIME && KeyDelayTime.DelayTime < KEY_SINGLE_TIME) // DOWN单键按下
{
// 单键按下条件成立
g_KeyEvent = KeyValueDown;
}
KeyBackUp = KEY_EVENT_NULL_CLICK ;
KeyDelayTime.DelayTime = 0;
break;
case KEY_EVENT_ONOFF_CLICK:
if(KeyDelayTime.DelayTime > KEY_PRESS_TIME && KeyDelayTime.DelayTime < KEY_SINGLE_TIME) //ONOFF 单按键
{
g_KeyEvent = KeyValueOnOff ;
}
KeyBackUp = KEY_EVENT_NULL_CLICK ;
KeyDelayTime.DelayTime = 0;
break;
case KEY_EVENT_MODE_CLICK:
if(KeyDelayTime.DelayTime > KEY_PRESS_TIME && KeyDelayTime.DelayTime < KEY_SINGLE_TIME) // MODE 单键按下
{
//单键按下条件成立
g_KeyEvent = KeyValueMode;
}
KeyBackUp = KEY_EVENT_NULL_CLICK ;
KeyDelayTime.DelayTime = 0;
break;
case KEY_EVENT_CLOCK_CLICK:
if(KeyDelayTime.DelayTime > KEY_PRESS_TIME && KeyDelayTime.DelayTime < KEY_SINGLE_TIME) // CLOCK 单键按下
{
//单键按下条件成立
g_KeyEvent = KeyValueClock;
}
KeyBackUp = KEY_EVENT_NULL_CLICK ;
KeyDelayTime.DelayTime = 0;
break;
case KEY_EVENT_SETTING_CLICK:
if(KeyDelayTime.DelayTime > KEY_PRESS_TIME && KeyDelayTime.DelayTime < KEY_SINGLE_TIME) // SETTING 单键按下
{
//单键按下条件成立
g_KeyEvent = KeyValueSetting;
}
KeyBackUp = KEY_EVENT_NULL_CLICK ;
KeyDelayTime.DelayTime = 0;
break;
case KEY_EVENT_LOCK_CLICK:
if(KeyDelayTime.DelayTime > KEY_PRESS_TIME && KeyDelayTime.DelayTime < KEY_SINGLE_TIME) // LOCK 单键按下
{
//单键按下条件成立
g_KeyEvent = KeyValueLock;
}
KeyBackUp = KEY_EVENT_NULL_CLICK ;
KeyDelayTime.DelayTime = 0;
break;
case KEY_EVENT_TIMING_CLICK:
if(KeyDelayTime.DelayTime > KEY_PRESS_TIME && KeyDelayTime.DelayTime < KEY_SINGLE_TIME) //TIMING 单键按下
{
//单键按下条件成立
g_KeyEvent = KeyValueTiming;
}
KeyDelayTime.DelayTime = 0;
KeyBackUp = KEY_EVENT_NULL_CLICK ;
break;
case KEY_EVENT_LONG_KEY_CLICK: //所有长按的键以此状态为出口
KeyBackUp = KEY_EVENT_NULL_CLICK ;
break;
default:
KeyBackUp = KEY_EVENT_NULL_CLICK;
KeyDelayTime.DelayTime = 0;
g_KeyEvent = KeyValueNull;
break;
}
}
}
原文:http://blog.csdn.net/a656343072/article/details/39394177