xiao_he 发表于 2016-6-9 12:14:35

两个触摸按键组合的多种状态

如标题,这个是自己根据需要写的识别两个触摸按键的多种组合(最多16种,可以用较少的按键完成较多功能) ,这里用触摸按键1是因为操作方便,2是主流。
贴出的目的:
1:在本坛得到不少前辈的热心帮助和指教,贴出给有需要者提供借鉴参考以感恩前辈们的帮助。
2:恳请前辈、高手们能对此算法进行修改、精简,以帮助我等小辈进步。
3:若各位有更好的思路或算法能分享的欢迎分享。

注:本人只用到前面8种功能(已上机验证),后面带*号的功能未写出。
/**************************************************
        函数:unsigned char Read_Key(void)
        描述:同时判断A(上键)、B(下键)两个按键的多种状态
        参数:
        返回:key_return(按键键值,两个按键最多16种状态)
                        1:A单击;        5:A长按;                *9:A连发;                *13:A+B单击再单击A;
                        2:B单击;        6:B长按;                *10:B连发;                *14:A+B单击再单击B;
                        3:A双击;        7:A向B滑动;        *11:A+B单击;        *15:A单击后再按A+B;
                        4:B双击;        8:B向A滑动;        *12:A+B双击;        *16:B单击后再按A+B;
       
        备注:每10ms调用一次
       
        ========小河2016.3.10========
**************************************************/

unsigned char        key_timer,key_state;        /* 按键计时器、状态 */
unsigned char key_t;

unsigned char Read_Key(void)
{
        static unsigned char count,key_data;
        unsigned char key_return = 0;        //按键返回值

        bit Key_up;        /* 上键 */
        bit Key_dw;        /* 下键 */

        Key_up = ch_up;         //读取ADC通道2/4“上”键的值
        Key_dw = ch_dw;         //读取ADC通道3/5“下”键的值       

//        if(++key_t > 50)        // 双击、滑动计时(值越大,调整的幅度要求越小)
//                key_t = 50;
        switch(key_state)
        {
                case 0:
                        if(Key_up == key_on && Key_dw == key_on)                // 两键同时按下不处理
                                key_state = 0;
                        else if(Key_up == key_on || Key_dw == key_on)        // 任意键按下转入状态1;
                                key_state = 1;
                        break;

                case 1:                // 消抖/确认
                        if(Key_up == key_on)                // 确认“上”键按下
                                key_state = 2;                // 转入“上”键短/长按判断       
                        else if(Key_dw == key_on)                                // 确认“下”键按下
                                key_state = 3;                // 转入“下”键短/长按判断
                        else
                                key_state = 0;                // 干扰
//                        key_t = 0;                // 按键计时器复位
                        break;

                case 2:                // “上”键短/长按判断
                        if(Key_up == key_off)                // 按键释放已完成第一次“上”键单击
                        {
                                count = 0;
                                key_state = 4;                // 转入“上”键双击/“下滑”判断
                        }

                        else if(++count >= 100)        // 按下“上”键 > 1000ms
                        {                                                       
                                key_data = up_L_key;        // 返回“上”键长按
                                key_state = 6;                        // 等待按键释放
                        }
                        break;

                case 3:                // “下”键短/长按判断
                        if(Key_dw == key_off)                // 按键释放已完成第一次“下”键单击
                        {
                                count = 0;
//                                        // 如果连发后松开按键,key_state = 0;
//                                        // 否则key_state = 5;
                                key_state = 5;                        // 转入“下”双击/“上滑”判断
                        }
//                        else if(++count >= 130)        // 按下“下”键 > 1000ms后,每300ms连发一次******
                        else if(++count >= 100)        // 按下“下”键 > 1000ms
                        {
//                                count = 100;                // 按下“下”键 > 1000ms后,每300ms连发一次******
//                                key_return = dw_L_key;        // 按下“下”键 > 1000ms后,每300ms连发一次******
                                key_data = dw_L_key;        // 返回“下”键长按
                                key_state = 6;                        // 等待按键释放
                        }
                        break;

                case 4:                // “上”键双击/“下滑”判断
                        if(Key_up == key_on)                // 再次按下“上”键
                        {
                                key_data = up_D_key;        // 返回“上”键双击
                                key_state = 6;                        // 等待按键释放
                        }
                        else if(Key_dw == key_on)        // 再次按下“下”键
                        {
                                key_data = dw_M_key;                // 返回“下滑”
                                key_state = 6;                        // 等待按键释放
                        }
                        else if(++count >= 50)        // 500ms内再无按键按下
                        {
                                key_data = up_S_key;                // 返回“上”键单击
                                key_state = 6;                        // 等待按键释放
                        }
                        break;

                case 5:                // “下”键双击/“上滑”判断
                        if(Key_dw == key_on)                // 再次按下“下”键
                        {
                                key_data = dw_D_key;        // 返回“下”键双击
                                key_state = 6;                        // 等待按键释放
                        }
                        else if(Key_up == key_on)        // 再次按下“上”键
                        {
                                key_data = up_M_key;        // 返回“上滑”
                                key_state = 6;                        // 等待按键释放
                        }
                        else if(++count >= 50)        // 500ms内无按键再按下
                        {
                                key_data = dw_S_key;        // 返回“下”键单击
                                key_state = 6;                        // 等待按键释放
                        }
                        break;

                case 6:                // 等待按键释放
                        if(Key_up == key_off && Key_dw == key_off)        // “上/下”键均已释放
                        {
                                key_return = key_data;        //返回按键值
//                                key_timer = 50 - key_t;                // 记录按键时长
                                key_data = 0;
                                key_state = 0;                // 状态复位
                                count = 0;                // 计数器复位
                        }
                        break;

                default:
                        break;               
        }
        return key_return;       
}

xiao_he 发表于 2016-6-9 12:19:50

长按和连发好像无法共存

lnso 发表于 2016-6-9 12:32:35

搞那么多按键把客户和自己都绕晕了,没什么卵 用

liufabing 发表于 2016-6-9 15:20:26

lnso 发表于 2016-6-9 12:32
搞那么多按键把客户和自己都绕晕了,没什么卵 用

确实,太多组合记不住操作,也是然并卵.

bangbangji 发表于 2016-6-9 15:35:04

理论上来讲,只要按的次数足够多,可按的时间足够长,一个按键就可以按出任意值来,二进制嘛{:lol:}

xiao_he 发表于 2016-6-9 15:50:15

本帖最后由 xiao_he 于 2016-6-9 15:52 编辑

lnso 发表于 2016-6-9 12:32
搞那么多按键把客户和自己都绕晕了,没什么卵 用

这仅仅是功能实现的导论,我做出来的原本目的是想用在一个简单密码(两个按键组合出8状态的输入)的电控锁上。

lnso 发表于 2016-6-9 16:11:45

两个按键可以用01组合密码就好了

bs1234 发表于 2016-6-10 10:34:51

其实按键就三种功能足够了,短按,长按,连续按,基本够用了,多了客户会搞不明白的。

闪耀的空白 发表于 2016-6-10 21:37:02

实际中不用到这么多的

xiao_he 发表于 2016-6-12 11:06:59

本帖最后由 xiao_he 于 2016-6-12 11:13 编辑

补充说明一下:这仅仅是按操作习惯的功能实现的导论(因为理论上每按1次键就是一个新值,8bit按255次就有255个值,按住1秒一个值的话,1分钟就有60个值等等),
就如Delay()在很多教科书上出现,却不会出现在产品上一样。
目的是想做一个简洁又不过于简单的密码锁的。

cary.luo 发表于 2016-7-6 16:26:08

两个按键,搞这么多路组合,代码写起来已经很混乱了,都能把自己搞晕,用户就更晕菜。

tangly2017 发表于 2017-11-29 17:12:29

好东西,谢谢楼主!!!!!!
页: [1]
查看完整版本: 两个触摸按键组合的多种状态