OpenEdv-开源电子网

标题: 有没有哪位大佬写过一个按键有短按,长按,连按多次功能的程序 [打印本页]

作者: 东方三毒    时间: 2018-1-27 17:27
标题: 有没有哪位大佬写过一个按键有短按,长按,连按多次功能的程序
如题,如果哪位大佬写过类似的程序,可否指点小弟一下,给小弟一点思路。程序最好有一定的实用性

作者: a496298685    时间: 2018-1-27 17:27
思路,定时器中断测定按压时长,从而执行特定动作。
作者: l6931639    时间: 2018-1-29 05:25
你看看这个方案,说得很详细
作者: 东方三毒    时间: 2018-1-29 08:14
a496298685 发表于 2018-1-27 17:27
思路,定时器中断测定按压时长,从而执行特定动作。

这个我知道,我主要想知道连按是怎么实现的
作者: Sun_Fly    时间: 2018-1-29 09:45
东方三毒 发表于 2018-1-29 08:14
这个我知道,我主要想知道连按是怎么实现的

1S内检测到两次低电平
作者: feilusia    时间: 2018-1-29 11:03
《STM8L之自定义长短按键》:http://blog.csdn.net/feilusia/article/details/53154346

作者: TinyBoy    时间: 2018-1-30 10:27
给你一个模板,可以实现你要的功能
void scan_key( u8 *key_val)
{
    static u8                   keyValue;
    static u8                   tmp_keyValue;
    static u8                   keyTrigger;
    static u8                   keyKeep;
    static u16                     keyDelayNum;
    static u16                     keyDelayNumValue;
    u8 x;
    keyValue = getKeyState(); // 得到按键的物理状态
    while(1)
    {
        if(keyValue != tmp_keyValue)
        {
            tmp_keyValue = keyValue;
            keyDelayNumValue = 10; //设置去抖节拍数
            keyDelayNum = 0;
            keyTrigger = 0;
            keyKeep = 0;
            break;
        }
        else
        {
            if(keyDelayNum < keyDelayNumValue)
            {
                keyDelayNum++;
                break;
            }

        }
        keyTrigger = keyValue & (keyValue ^ keyKeep);
        keyKeep = keyValue;
               
        if(keyValue)
        {

                                                    if(keyTrigger)
                                                    {

                                                            keyDelayNum = 0;
                                                            keyDelayNumValue = 400;//设置长按键节拍数

                                                            //处理短按,得到键值*key_val = x;


                                                            



                                                    }
                                                    else
                                                    {
                                                               //处理长按键和连按键,如果不需要,这里不添加代码
                                                            
                                                    }


        }
        else
        {
            //处理释放后要的键值,如同鼠标单击功能,多击也在这里处理,不需要,直接清键值
             *key_val = NULL;


        }

        break;
    }

}
作者: 东方三毒    时间: 2018-1-31 14:53
TinyBoy 发表于 2018-1-30 10:27
给你一个模板,可以实现你要的功能
void scan_key( u8 *key_val)
{

谢谢大佬分享,不过小弟现在能力有限,暂时还没看懂
作者: 东方三毒    时间: 2018-1-31 15:02
Sun_Fly 发表于 2018-1-29 09:45
1S内检测到两次低电平

这个可以考虑,不过感觉好像比较复杂
作者: 东方三毒    时间: 2018-1-31 15:03
feilusia 发表于 2018-1-29 11:03
《STM8L之自定义长短按键》:http://blog.csdn.net/feilusia/article/details/53154346

谢谢分享
作者: TinyBoy    时间: 2018-1-31 15:42
东方三毒 发表于 2018-1-31 14:53
谢谢大佬分享,不过小弟现在能力有限,暂时还没看懂

假设5MS扫描此函数一次

                      void scan_key( u8 *key_val)
{
    static uchar                   keyValue;
    static uchar                   tmp_keyValue;
    static uchar                   keyTrigger;
    static uchar                   keyKeep;
    static u16                     keyDelayNum;
    static u16                     keyDelayNumValue;
    keyValue = ((GPIO_ReadInputData(GPIOC) >> 1) & 0x01) ^ 0x01; //只有一个按键,得到按键状态
    while(1)
    {
        if(keyValue != tmp_keyValue)
        {
            tmp_keyValue = keyValue;
            keyDelayNumValue = 10; //去抖50MS
            keyDelayNum = 0;
            keyTrigger = 0;
            keyKeep = 0;
            break;
        }
        else
        {
            if(keyDelayNum < keyDelayNumValue)
            {
                keyDelayNum++;
                break;
            }

        }
        keyTrigger = keyValue & (keyValue ^ keyKeep);
        keyKeep = keyValue;
        if(keyValue)
        {

            if(keyTrigger)
            {

                keyDelayNum = 0;
                keyDelayNumValue = 200; //设置得到长按键的时间,1S
                *key_val = 0x01 ;   //这里得到短按键值



            }
            else
            {

                keyDelayNum = 0;
                keyDelayNumValue = 40; //如果需要连按,不要释放按键
                //这里200MS就得到一次键值,实现连按,连按键是周期性的得到长按键
                *key_val = 0x02; //如果5MS节拍,1S后得到长按键
            }


        }
        else
        {

             *key_val = NULL;

        }

        break;
    }

}
作者: 东方三毒    时间: 2018-1-31 17:28
TinyBoy 发表于 2018-1-31 15:42
假设5MS扫描此函数一次

                      void scan_key( u8 *key_val)

static uchar                   keyValue;
    static uchar                   tmp_keyValue;
    static uchar                   keyTrigger;
    static uchar                   keyKeep;
    static u16                     keyDelayNum;
    static u16                     keyDelayNumValue;
主要是这些函数的定义
作者: HXYDJ    时间: 2018-2-7 15:27
//mode: 0 不支持连续按 1:支持连续按
//0 没有任何按键按下  1 KEY1按下 2 KEY2按下
u8 KEY_Scan(u8 mode)
{
        static u8 key_up = 1; //按键松开标志
        if(mode) key_up = 1;  //支持连按
        if(key_up && (KEY1 == RESET || KEY2 == RESET))
        {
                delay_ms(10);   //去抖
                key_up = 0;
                if(KEY1 == RESET)
                        return 1;
                if(KEY2 == RESET)
                        return 2;
        }
        if(KEY1 != RESET && KEY2 != RESET)
        {
                key_up = 1;
        }
        return 0;
}
作者: 东方三毒    时间: 2018-2-24 14:33
HXYDJ 发表于 2018-2-7 15:27
//mode: 0 不支持连续按 1:支持连续按
//0 没有任何按键按下  1 KEY1按下 2 KEY2按下
u8 KEY_Scan(u8 mod ...

谢谢
作者: 无痕幽雨    时间: 2018-2-26 06:39
http://blog.csdn.net/wuhenyouyuyouyu/article/details/77622340




欢迎光临 OpenEdv-开源电子网 (http://47.111.11.73/) Powered by Discuz! X3.4