今天总结一下IO口接地的按键处理程序,我觉得这种处理方式,很方便实现短按,长按,按键抬起,连续按2次或者多次的判断,精准无误。
首先上原理图:
程序如下:
u8 ap_get_sys(void)
{
static u32 key_press_counter;
static u8 key_last = KEY_NULL;
static u8 key_value = KEY_NULL;
u8 key = KEY_NULL;
u8 key_tmp = KEY_NULL;
if(clock_time_exceed(key_press_counter, 500)) // just check for long cancel_key
{
key_press_counter = clock_time();
u8 key_tmp_pwr = (!gpio_read(key_pwr))?KEY_POWER:0 ;
u8 key_tmp_pho = (!gpio_read(key1_pho))?KEY_PHO:0 ;
u8 key_tmp_p = (!gpio_read(key2_p))?KEY_P:0 ;
u8 key_tmp_n = (!gpio_read(key3_n))?KEY_N:0 ;
if(key_last == KEY_NULL){
if(key_tmp_pwr) key_tmp = key_tmp_pwr;
else if(key_tmp_pho) key_tmp = key_tmp_pho;
else if(key_tmp_p) key_tmp = key_tmp_p;
else if(key_tmp_n) key_tmp = key_tmp_n;
}else{
if(key_last & KEY_POWER) key_tmp = key_tmp_pwr;
else if(key_last & KEY_PHO) key_tmp = key_tmp_pho;
else if(key_last & KEY_P) key_tmp = key_tmp_p;
else if(key_last & KEY_N) key_tmp = key_tmp_n;
}
if(key_tmp == KEY_POWER || key_tmp == KEY_PHO || key_tmp == KEY_P || key_tmp == KEY_N)
{
key_not_release = 1;
}
if(key_tmp == key_last) //go key shark
{
key_value = key_tmp;
}
else if((key_value != KEY_NULL) && (key_tmp == KEY_NULL)) //new key up
{
key_value = KEY_UP;
}
else
{
key_value = KEY_NULL;
}
key = key_value;
key_last = key_tmp;
}
return key;
}
u8 ap_get_message(void)
{
static u8 key_mesg_last=KEY_NULL;
static u8 key_count=0;
u8 key_mesg;
key_mesg = ap_get_sys(); // key and other message can send to here
if(key_mesg == KEY_NULL)
{
return KEY_NULL;
}
else if(key_mesg == key_mesg_last) //for log key press, the same as last key , must be not null
{
if(key_tick == 0) key_tick = clock_time()|1;
if(clock_time_exceed(key_tick,3000*1000) && ((key_mesg & KEY_POWER) == KEY_POWER))
{
key_count = 0;
key_mesg |= KEY_LONG3;
}
else if(clock_time_exceed(key_tick,2000*1000) && ((key_mesg & KEY_POWER) == KEY_POWER))
{
bls_ll_setScanRspData( (u8 *)tbl_scanRsp_cancel, sizeof(tbl_scanRsp_cancel));
}
#if BQB_TEST_OPEN
else if(clock_time_exceed(key_tick,3000*1000) && ((key_mesg & KEY_N) == KEY_N))
{
key_count = 0;
key_tick = clock_time()|1;
key_mesg |= KEY_LONG5;
printf("bqb enter \r\n");
}
#endif
else
{
key_mesg = KEY_NULL; //is NULL when waiting for long key
}
#if 0
key_count++;
if(key_count == 60 && ((key_mesg & KEY_POWER) == KEY_POWER)) //150 * 20ms == about 3s
{
key_count = 0;
key_mesg |= KEY_LONG3;
}
#if COMBINATION_KEY_ENABLE //Warning: combination key function must be deprecated!!!
else if(key_count == 100 && ((key_mesg & (KEY_P|KEY_N)) == (KEY_P|KEY_N))) //5s
{
key_count = 0;
key_mesg |= KEY_LONG5;
}
#endif
else
{
key_mesg = KEY_NULL; //is NULL when waiting for long key
}
#endif
}
else if(key_mesg == KEY_UP)
{
key_tick = 0;
key_not_release = 0;
key_count = 0;
key_mesg = key_mesg_last | KEY_UP;
key_mesg_last = key_mesg;
}
else //new key here
{
key_count = 1;
key_mesg_last = key_mesg;
latest_user_event_tick = clock_time();
//advertise_begin_tick = clock_time();
}
return key_mesg;
}
u8 key_event_handle()
{
u8 key_value = KEY_NULL;
u8 ret = 0;
key_value = ap_get_message();
switch(key_value)
{
case KEY_NULL:
{
break;
}
case KEY_POWER:
{
if(kpwr_start_flag == 0) //for detect two click
{
kpwr_start_flag = 1;
last_singleKey_press_tick = clock_time()|1;
}
else
{
if(!clock_time_exceed(last_singleKey_press_tick, 400*1000))
{
kpwr_start_flag = 0;
if(blc_ll_getCurrentState() == BLS_LINK_STATE_CONN)
{
consumer_key = MKEY_AC_WAKE;
ret = bls_att_pushNotifyData (HID_CONSUME_REPORT_INPUT_DP_H, (u8 *)&consumer_key, 2);
#if FLASH_PRINTF_ENABLE
tmp[0] = 0x00;
tmp[1] = EVE_KEY_PRESS_PWR;
tmp[2] = 0x00;
tmp[3] = ret;
rec_single_evt(tmp);
#endif
consumer_key = 0;
ret = bls_att_pushNotifyData (HID_CONSUME_REPORT_INPUT_DP_H, (u8 *)&consumer_key, 2);
#if FLASH_PRINTF_ENABLE
tmp[0] = 0x00;
tmp[1] = EVE_PUSH_NOTIFY_UP;
tmp[2] = 0x00;
tmp[3] = ret;
rec_single_evt(tmp);
#endif
}
}
}
break;
}
case KEY_PHO:
{
if(blc_ll_getCurrentState() == BLS_LINK_STATE_CONN)
{
if(pho_press_down)
{
pho_press_down = false;
consumer_key = MKEY_VOL_UP;
ret = bls_att_pushNotifyData (HID_CONSUME_REPORT_INPUT_DP_H, (u8 *)&consumer_key, 2);
}
else
{
pho_press_down = true;
consumer_key = MKEY_VOL_DN;
ret = bls_att_pushNotifyData (HID_CONSUME_REPORT_INPUT_DP_H, (u8 *)&consumer_key, 2);
}
#if FLASH_PRINTF_ENABLE
tmp[0] = 0x00;
tmp[1] = EVE_KEY_PRESS_PHO;
tmp[2] = 0x00;
tmp[3] = ret;
rec_single_evt(tmp);
#endif
//device_led_setup(led_cfg[LED_PHO_ON]);
gpio_write(LED1_GREEN, 1);
gpio_set_output_en(LED1_GREEN, 1);
pho_press_tick = clock_time()|1;
}
break;
}
case KEY_P:
{
if(blc_ll_getCurrentState() == BLS_LINK_STATE_CONN)
{
consumer_key = MKEY_AC_ZOOM_OUT;
ret = bls_att_pushNotifyData (HID_CONSUME_REPORT_INPUT_DP_H, (u8 *)&consumer_key, 2);
#if FLASH_PRINTF_ENABLE
tmp[0] = 0x00;
tmp[1] = EVE_KEY_PRESS_P;
tmp[2] = 0x00;
tmp[3] = ret;
rec_single_evt(tmp);
#endif
}
break;
}
case KEY_N:
{
if(blc_ll_getCurrentState() == BLS_LINK_STATE_CONN)
{
consumer_key = MKEY_AC_ZOOM_IN;
ret = bls_att_pushNotifyData (HID_CONSUME_REPORT_INPUT_DP_H, (u8 *)&consumer_key, 2);
#if FLASH_PRINTF_ENABLE
tmp[0] = 0x00;
tmp[1] = EVE_KEY_PRESS_N;
tmp[2] = 0x00;
tmp[3] = ret;
rec_single_evt(tmp);
#endif
}
break;
}
case KEY_POWER |KEY_UP:
{
break;
}
case KEY_PHO |KEY_UP:
{
if(blc_ll_getCurrentState() == BLS_LINK_STATE_CONN)
{
consumer_key = 0;
ret = bls_att_pushNotifyData (HID_CONSUME_REPORT_INPUT_DP_H, (u8 *)&consumer_key, 2);
#if FLASH_PRINTF_ENABLE
tmp[0] = 0x00;
tmp[1] = EVE_PUSH_NOTIFY_UP;
tmp[2] = 0x00;
tmp[3] = ret;
rec_single_evt(tmp);
#endif
pho_press_tick = clock_time()|1;
}
break;
}
case KEY_P |KEY_UP:
{
if(blc_ll_getCurrentState() == BLS_LINK_STATE_CONN)
{
consumer_key = 0;
ret = bls_att_pushNotifyData (HID_CONSUME_REPORT_INPUT_DP_H, (u8 *)&consumer_key, 2);
#if FLASH_PRINTF_ENABLE
tmp[0] = 0x00;
tmp[1] = EVE_PUSH_NOTIFY_UP;
tmp[2] = 0x00;
tmp[3] = ret;
rec_single_evt(tmp);
#endif
}
break;
}
case KEY_N |KEY_UP:
{
if(blc_ll_getCurrentState() == BLS_LINK_STATE_CONN)
{
consumer_key = 0;
ret = bls_att_pushNotifyData (HID_CONSUME_REPORT_INPUT_DP_H, (u8 *)&consumer_key, 2);
#if FLASH_PRINTF_ENABLE
tmp[0] = 0x00;
tmp[1] = EVE_PUSH_NOTIFY_UP;
tmp[2] = 0x00;
tmp[3] = ret;
rec_single_evt(tmp);
#endif
}
break;
}
case KEY_POWER | KEY_LONG3: // power off by
{
//gpio_write(LED2_BLUE, 1);
//if(blc_ll_getCurrentState() == BLS_LINK_STATE_CONN)
if(connect_flag == 1)
{
bls_ll_terminateConnection(HCI_ERR_REMOTE_USER_TERM_CONN); //push terminate cmd into ble TX buffer
//bls_ll_setAdvEnable(0); //disable adv
sendTerminate_before_enterDeep = 1;
pwr_key_off_flag =1;
sys_boot_flag =1;
}
else
{
#if FLASH_PRINTF_ENABLE
tmp[0] = 0x00;
tmp[1] = EVE_TURN_OFF;
tmp[2] = 0x00;
tmp[3] = 0x02;
rec_single_evt(tmp);
#endif
printf("key power long3 system power off \r\n");
system_power_off();
}
break;
}
#if BQB_TEST_OPEN //Warning: combination key function must be deprecated!!!
case KEY_N | KEY_LONG5: //A+B key for 3s
{
if(blc_ll_getCurrentState() == BLS_LINK_STATE_ADV)
{
printf("bqb init \r\n");
//BQB_Test_Function();
//analog_write(DEEP_ANA_REG1, BQB_TEST_FLG);
//start_reboot();
}
break;
}
#endif
default:
{
break;
}
}
return ret;
}
你好,我是有问必答小助手,非常抱歉,本次您提出的有问必答问题,技术专家团超时未为您做出解答
本次提问扣除的有问必答次数,将会以问答VIP体验卡(1次有问必答机会、商城购买实体图书享受95折优惠)的形式为您补发到账户。
因为有问必答VIP体验卡有效期仅有1天,您在需要使用的时候【私信】联系我,我会为您补发。