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

2020-01-14 18:59发布

如标题,这个是自己根据需要写的识别两个触摸按键的多种组合(最多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;       
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
11条回答
bs1234
1楼-- · 2020-01-15 17:03
其实按键就三种功能足够了,短按,长按,连续按,基本够用了,多了客户会搞不明白的。
闪耀的空白
2楼-- · 2020-01-15 20:53
实际中不用到这么多的
xiao_he
3楼-- · 2020-01-16 01:58
本帖最后由 xiao_he 于 2016-6-12 11:13 编辑

补充说明一下:这仅仅是按操作习惯的功能实现的导论(因为理论上每按1次键就是一个新值,8bit按255次就有255个值,按住1秒一个值的话,1分钟就有60个值等等),
就如Delay()在很多教科书上出现,却不会出现在产品上一样。
目的是想做一个简洁又不过于简单的密码锁的。
cary.luo
4楼-- · 2020-01-16 07:15
两个按键,搞这么多路组合,代码写起来已经很混乱了,都能把自己搞晕,用户就更晕菜。
tangly2017
5楼-- · 2020-01-16 10:11
 精彩回答 2  元偷偷看……

一周热门 更多>