c语言按键处理程序,精准控制

今天总结一下IO口接地的按键处理程序,我觉得这种处理方式,很方便实现短按,长按,按键抬起,连续按2次或者多次的判断,精准无误。

首先上原理图:

img

程序如下:

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天,您在需要使用的时候【私信】联系我,我会为您补发。