zoukankan      html  css  js  c++  java
  • 关于按键扫描程序的终极讨论

    一、思路

    基于STM8,按键处理,思路是这样的:

    每20ms左右一次去扫描按键,用一个key_now记录当前值,用key_last记录上次的值,如果key_now和key_last同时有效,则开始进行cnt++。
    我设定两个阈值,LONG_PRESS为100(100*20ms=2s),SHORT_PRESS为4(4*20ms=80ms,去抖)。
    cnt大于LONG_PRESS,表示是长按,反之再判断cnt是不是大于SHORT_PRESS,表示是短按,否则把cnt清零。

    另外一种情况,我们在设置参数的时候,要不停加1或者减1,我长按,希望数值连续增减,怎么实现?

    接上面的cnt值,再设置一个连按的阈值,MID_PRESS=50(50*20ms=1s)。
    当cnt大于MID_PRESS时,我认为触发了短按,但此时不清空cnt,只是将cnt减去SHORT_PRESS的值。
    如此下去,如果按键一直不松开,则一直连线触发短按。

     

    二、实现

    硬件上有三个按键,分别是set,up,down。

    // 控制按键时长 
    #define LONG_PRESS 100 // 20ms*100=2s,长按 
    #define SHORT_PRESS 5 // 20ms*5=100ms,短按 
    #define MID_PRESS 50 // 20ms*50=1s,连按 
    #define REPEAT_PRESS 5 // 200ms*5=100ms,连按灵敏参数 
    
    #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
    
    uchar 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键短按 
    bool up_short = FALSE; // up键短按 
    bool down_short = FALSE; // down键短按
    
    // 初始化 
    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; 
    }
    
    // 按键处理 
    void key_scan(void) 
    { 
        //按键端口上拉了,默认是高电平,有按键时变低。这里取反,有按键时变高。 
        pinNow = 0xFF - GPIO_ReadInputData(KEY_PORT); 
        pinSet_now = pinNow & KEY_SET; 
        pinUp_now = pinNow & KEY_UP; 
        pinDown_now = pinNow & KEY_DOWN;
    
        // set键只分长按和短按,没有连按 
        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; 
            } 
        } 
    
        // up和down键有连按和短按,没有长按 
        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; 
            } 
        }
    
        // 添加自己对于set_long,set_short,up_short,down_short的处理代码 
        // 处理完了不要忘记把相应的值置为FALSE
    
        pinSet_last = pinSet_now; 
        pinUp_last = pinUp_now; 
        pinDown_last = pinDown_now; 
    }

    然后用定时器中断,每20ms去执行一个key_scan()函数。

  • 相关阅读:
    Linux文本检索命令grep笔记
    Python中字典的相关操作
    Go 语言函数闭包
    Go 语言多维数组
    Go 错误处理
    Go 语言接口
    Go 语言类型转换
    Go 语言递归函数
    Go 语言Map(集合)
    Go 语言范围(Range)
  • 原文地址:https://www.cnblogs.com/craftor/p/3811748.html
Copyright © 2011-2022 走看看