/* * 多个按键检测短按和长按事件 * 短按:时间 10ms < T < 1 s, 长按:时间 T >1 s * 功能:使用状态机方式,扫描单个按键;扫描周期为10ms,10ms刚好跳过抖动; * 状态机使用switch case语句实现状态之间的跳转 * lock变量用于判断是否是第一次进行按键确认状态 * :按键释放后才执行按键事件 */ #include "bsp_btn.h" #include "bsp_config.h" #include "../msp/UART0.h" extern KEY_STATE KeyState = KEY_CHECK; // 初始化按键状态为检测状态 KEY_TYPE g_KeyActionFlag = NULL_KEY; // 用于区别长按和短按 KEY_VALUE g_Key = KEY_NULL; u8 g_KeyFlag = 0; // 按键有效标志,0 无效 1 有效 static u8 TimeCnt = 0; //10ms为颗粒 static u8 lock = 0; //lock变量用于判断是否是第一次进行按键确认状态 void Key_Scan(void) { static u8 TimeCnt = 0; //10ms为颗粒 static u8 lock = 0; switch (KeyState) { //按键未按下状态,此时判断Key的值 case KEY_CHECK: if(!Key) //如果按键Key值为0,说明按键开始按下,进入下一个状态 { KeyState = KEY_COMFIRM; } TimeCnt = 0; //计数复位 lock = 0; break; //按键按下状态确认: case KEY_COMFIRM: if(!Key) //查看当前Key是否还是0,再次确认是否按下 { if(!lock) lock = 1; //第一次进来置1 TimeCnt ++; // 多按键判断 if(0 == key1) g_Key = KEY_UP; else if(0 == key2) g_Key = KEY_DOWN; else if(0 == key3) g_Key = KEY_PWR; if(TimeCnt > 200) // 长按 2 s { L0_uart0_uc('#'); g_KeyActionFlag = LONG_KEY; TimeCnt = 0; lock = 0; //重新检查 KeyState = KEY_RELEASE; // 需要进入按键释放状态 } // ??????????????????????? } else { if(lock) //不是第一次进入,释放按键才执行 { g_KeyActionFlag = SHORT_KEY; // 短按 KeyState = KEY_RELEASE; // 需要进入按键释放状态 } else // 当前Key值为1,确认为抖动,则返回上一个状态 { KeyState = KEY_CHECK; // 返回上一个状态 } } break; //按键释放状态 case KEY_RELEASE: if(Key) //当前Key值为1,说明按键已经释放,返回开始状态 { KeyState = KEY_CHECK; } break; default: break; } }