两个触摸按键组合的多种状态
如标题,这个是自己根据需要写的识别两个触摸按键的多种组合(最多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;
} 长按和连发好像无法共存 搞那么多按键把客户和自己都绕晕了,没什么卵 用 lnso 发表于 2016-6-9 12:32
搞那么多按键把客户和自己都绕晕了,没什么卵 用
确实,太多组合记不住操作,也是然并卵. 理论上来讲,只要按的次数足够多,可按的时间足够长,一个按键就可以按出任意值来,二进制嘛{:lol:} 本帖最后由 xiao_he 于 2016-6-9 15:52 编辑
lnso 发表于 2016-6-9 12:32
搞那么多按键把客户和自己都绕晕了,没什么卵 用
这仅仅是功能实现的导论,我做出来的原本目的是想用在一个简单密码(两个按键组合出8状态的输入)的电控锁上。 两个按键可以用01组合密码就好了 其实按键就三种功能足够了,短按,长按,连续按,基本够用了,多了客户会搞不明白的。 实际中不用到这么多的 本帖最后由 xiao_he 于 2016-6-12 11:13 编辑
补充说明一下:这仅仅是按操作习惯的功能实现的导论(因为理论上每按1次键就是一个新值,8bit按255次就有255个值,按住1秒一个值的话,1分钟就有60个值等等),
就如Delay()在很多教科书上出现,却不会出现在产品上一样。
目的是想做一个简洁又不过于简单的密码锁的。 两个按键,搞这么多路组合,代码写起来已经很混乱了,都能把自己搞晕,用户就更晕菜。 好东西,谢谢楼主!!!!!!
页:
[1]