The Ultimate Key Scanner Discussion

Publisher:创新火箭Latest update time:2020-09-22 Source: eefocus Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

1. Idea


Based on STM8, the idea of ​​key processing is as follows:


Scan the keys every 20ms or so, use key_now to record the current value, and use key_last to record the last value. If key_now and key_last are valid at the same time, start cnt++.

I set two thresholds, LONG_PRESS is 100 (100*20ms=2s) and SHORT_PRESS is 4 (4*20ms=80ms, debounce).

If cnt is greater than LONG_PRESS, it means it is a long press. Otherwise, check whether cnt is greater than SHORT_PRESS, which means it is a short press. Otherwise, clear cnt.


In another case, when we are setting parameters, we need to keep adding or subtracting 1. I press and hold, hoping that the value will increase or decrease continuously. How can I achieve this?


Connect to the above cnt value and set a continuous press threshold, MID_PRESS=50 (50*20ms=1s).

When cnt is greater than MID_PRESS, I think the short press is triggered, but at this time cnt is not cleared, but cnt is subtracted from the value of SHORT_PRESS.

In this way, if the button is not released, the short press will be triggered continuously.



2. Implementation


There are three buttons on the hardware: set, up, and down.


//Control key duration 

#define LONG_PRESS 100 // 20ms*100=2s, long press 

#define SHORT_PRESS 5 // 20ms*5=100ms, short press 

#define MID_PRESS 50 // 20ms*50=1s,连按 

#define REPEAT_PRESS 5 // 200ms*5=100ms, press sensitivity parameter 


#define KEY_PORT (GPIOC) 

#define KEY_SET (GPIO_PIN_5) // set键接PC5 

#define KEY_UP (GPIO_PIN_6) // up键接PC6 

#define KEY_DOWN (GPIO_PIN_7) // down键接PC7


float pinNow; 

bool pinSet_now, pinUp_now, pinDown_now; 

bool pinSet_last, pinUp_last, pinDown_last; 

bool set_long = FALSE; // set键长按 

bool set_short = FALSE; // set key short press 

bool up_short = FALSE; // up key short press 

bool down_short = FALSE; // down key short press


// Initialization 

void key_proc_init(void) 

    GPIO_Init(KEY_PORT, KEY_SET|KEY_UP|KEY_DOWN, GPIO_MODE_IN_FL_IT); 

    EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOC, EXTI_SENSITIVITY_FALL_ONLY);


    pinNow = 0; 

    set_cnt = 0; 

    up_cnt = 0; 

    down_cnt = 0;


    set_long = FALSE; 

    set_short = FALSE; 

    up_short = FALSE; 

    down_short = FALSE; 

}


//Key processing 

void key_scan(void) 

    //The button port is pulled up, the default is high level, and it becomes low when a button is pressed. Here it is inverted, and it becomes high when a button is pressed. 

    pinNow = 0xFF - GPIO_ReadInputData(KEY_PORT); 

    pinSet_now = pinNow & KEY_SET; 

    pinUp_now = pinNow & KEY_UP; 

    pinDown_now = pinNow & KEY_DOWN;


    // The set key can only be pressed long or short, not continuously. 

    if (pinSet_now & pinSet_last) { 

        set_cnt++; 

        if (set_cnt>LONG_PRESS) { 

            set_long = TRUE; 

            set_cnt = 0; 

        } 

    }else { 

        if (set_cnt>SHORT_PRESS) { 

            set_short = TRUE; 

            set_cnt = 0; 

        }else{ 

            set_cnt = 0; 

        } 

    } 


    // The up and down keys have continuous press and short press, but no long press 

    if (pinUp_now & pinUp_last) { 

        up_cnt++; 

        if (up_cnt>MID_PRESS) { 

            up_short = TRUE; 

            up_cnt = up_cnt - REPEAT_PRESS; 

        } 

    }else{ 

        if (up_cnt>SHORT_PRESS) { 

            up_short = TRUE; 

            up_cnt = 0; 

        } 

    }


    if (pinDown_now & pinDown_last) { 

        down_cnt++; 

        if (down_cnt>MID_PRESS) { 

            down_short = TRUE; 

            down_cnt = down_cnt - REPEAT_PRESS; 

        } 

    }else{ 

        if (down_cnt>SHORT_PRESS) { 

            down_short = TRUE; 

            down_cnt = 0; 

        } 

    }


    // Add your own processing code for set_long, set_short, up_short, down_short 

    // Don't forget to set the corresponding value to FALSE after processing


    pinSet_last = pinSet_now; 

    pinUp_last = pinUp_now; 

    pinDown_last = pinDown_now; 

}


Then use the timer interrupt to execute a key_scan() function every 20ms.

Reference address:The Ultimate Key Scanner Discussion

Previous article:Standard bit operation method
Next article:About the user data space reading and writing problem of STM8

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号