复杂按键事件识别程序(链接层)
复杂按键包括多个按键的单按事件、长按事件、连按事件、组合按键事件等
本程序为链接层程序,处理和识别按键驱动层扫描到的按键信息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