由于按键检测有中断、和轮询两种方式,默认采用轮询方式,对于轮询方式的长按处理比较简单,利用松开的时间点和松下的时间点之间的时间差即可实现。对于中断的方式可以采用定时器方式,当中断触发的时候,开一个定时器,如果定时器到期了,按钮还是按下状态,就认为是长按。
void InitBoard( uint8 level )
{
if ( level == OB_COLD )
{
// Interrupts off
osal_int_disable( INTS_ALL );
// Turn all LEDs off
//HalLedSet( HAL_LED_ALL, HAL_LED_MODE_OFF );
// Check for Brown-Out reset
ChkReset();
}
else // !OB_COLD
{
/* Initialize Key stuff */
// OnboardKeyIntEnable = HAL_KEY_INTERRUPT_DISABLE;//配置成轮
OnboardKeyIntEnable = HAL_KEY_INTERRUPT_ENABLE;//配置成中断
HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);
}
}
核心代码:
#define KEY_HOLD_LONG_INTERVAL 3
static uint32 keyPressTime = 0;
#define KEY_LONG_PRESS_TIME 1500 //3s
#define KEY_LONG_PRESS_MSG_EVT 0x005F
void SampleApp_HandleKeys( uint8 shift, uint8 keys )
{
(void)shift; // Intentionally unreferenced parameter
if (!Hal_KeyIntEnable)//轮询处理
{
if ( keys & HAL_KEY_SW_1 )//p0_1
{
if (keys == 0x01)//press down
{
keyPressTime = osal_getClock();
}else //press up
{
if (keyPressTime)
{
keyPressTime = (osal_getClock() - keyPressTime);
if (keyPressTime >= KEY_HOLD_LONG_INTERVAL )//长按
{
printf("long press... \r\n");
}
else
{
printf("short press... \r\n");
HalLedSet(HAL_LED_G, HAL_LED_MODE_FLASH);
}
keyPressTime = 0;
}
}
}else if ( keys & HAL_KEY_SW_2 )//p2_0
{
}
}else{//中断处理
if ( keys & HAL_KEY_SW_1 )//p0_1
{
//.....
osal_stop_timerEx(SampleApp_TaskID,KEY_LONG_PRESS_MSG_EVT);
osal_start_timerEx( SampleApp_TaskID, KEY_LONG_PRESS_MSG_EVT,
(KEY_LONG_PRESS_TIME));
//.....
}
}
}
//定时器事件处理
uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events )
{
afIncomingMSGPacket_t *MSGpkt;
(void)task_id;
//.....
if ( events & KEY_LONG_PRESS_MSG_EVT ){
printf("p1_0:%d ===\r\n",P0_1);
if(P0_1 == 0){
printf("p0_1 long press... \rn");
}else{
}
}
//....
// Discard unknown events
return 0;
}