/*----------------------------------------------- 名称:按键 ------------------------------------------------*/ #include"key.h" extern unsigned char keyvalue; unsigned char keyscan() { unsigned char keynumber; if(!KEY1) keynumber = 1; //!!!修改此处,可以增加/减少按键数量 else if(!KEY2) keynumber = 2; //!!!修改此处,可以增加/减少按键数量 else if(!KEY3) keynumber = 3; //!!!修改此处,可以增加/减少按键数量 else if(!KEY4) keynumber = 4; //!!!修改此处,可以增加/减少按键数量 else keynumber = 0; return keynumber; } unsigned char key_multi(void) { static uchar key_state; //按键状态变量 static uint key_time; //按键计时变量 static uchar key_press_nums; //按键次数变量 static uint key_time_double; //按键双击时间 static uchar keynum; //键值 static uchar new_keynum; //新的键值 uchar key_press, key_return; //键值和返回值 key_return = None_click; //清除返回按键值 switch(keyscan()) { case 1:key_press = KEY1;new_keynum = 1;break; //!!!修改此处,可以增加/减少按键数量 case 2:key_press = KEY2;new_keynum = 2;break; //!!!修改此处,可以增加/减少按键数量 case 3:key_press = KEY3;new_keynum = 3;break; //!!!修改此处,可以增加/减少按键数量 case 4:key_press = KEY4;new_keynum = 4;break; //!!!修改此处,可以增加/减少按键数量 default:key_press = 1;break; } if(key_press_nums > 0) //按键次数大于0,说明有按键 { key_time_double++; //是否开始双击计 if(key_time_double >= DOUBLE_KEY_TIME && key_time_double < LONG_KEY_TIME) key_state = KEY_STATE_2;//如果时间到了在双击和长按之间,切换到状态2 } switch (key_state) { case KEY_STATE_0: //按键状态0:判断有无按键按下 { if (!key_press) //是否有按键按下,没有按下就退出 { key_time = 0; //清零时间间隔计数 key_state = KEY_STATE_1; //然后进入 按键状态1 } }break; case KEY_STATE_1: //按键状态1:软件消抖(确定按键是否有效,而不是误触)。按键有效的定义:按键持续按下超过设定的消抖时间。 { if (!key_press) { key_time++; //一次10ms if(key_time>=SINGLE_KEY_TIME) //消抖时间为:SINGLE_KEY_TIME*10ms = 10ms; { key_state = KEY_STATE_2; //如果按键时间超过 消抖时间,即判定为按下的按键有效。进入按键状态2,继续判定到底是单击、双击还是长按 key_press_nums++; //按键次数+1 } } else key_state = KEY_STATE_0; //如果按键时间没有超过,判定为误触,按键无效,返回 按键状态0,继续等待按键 }break; case KEY_STATE_2: //按键状态2:判定按键有效的种类:是单击,双击,还是长按 { if(key_press) //如果按键在 设定的双击时间内释放,则判定为单击/双击 { if(key_time_double < DOUBLE_KEY_TIME ) key_state = KEY_STATE_0; //双击时间达到前,再次扫描按键,看还有没有按键按下 if(key_time_double >= DOUBLE_KEY_TIME && key_time_double < LONG_KEY_TIME) //达到双击设定时间后,如果时间超过双击的时间则判断按键按下的次数 { if(key_press_nums == 1) key_return = Single_click + new_keynum*10; //判断只按了1次,返回有效按键值:单击,通过不同的值判断是哪个按键按下的单击 else if(key_press_nums ==2 && new_keynum == keynum) key_return = Double_click + new_keynum*10; //判断按了2次和两次按键按的一样,返回有效按键值:双击,通过不同的值判断是哪个按键按下的双击 key_state = KEY_STATE_0; //返回 按键状态0,继续等待按键 key_press_nums = 0; //清空按键次数 key_time_double = 0; //清空双击计时 } if(key_time_double >LONG_KEY_TIME ) key_state = KEY_STATE_3; //如果长按之后才松开的,则切换到状态3清0 } else { key_time++; //按键一直按着的话,长按计时 if(key_time >= LONG_KEY_TIME) //如果按键时间超过 设定的长按时间(LONG_KEY_TIME*10ms=80*10ms=800ms), 则判定为 长按 { key_return = Long_click + new_keynum*10; //返回有效键值值:长按,通过不同的值判断是哪个按键按下的长按了 //key_state = KEY_STATE_3; //去状态3,等待按键释放 } } }break; case KEY_STATE_3: //等待按键释放 { if (key_press) { key_state = KEY_STATE_0; //按键释放后,进入 按键状态0 ,进行下一次按键的判定 key_press_nums = 0; //清空按键次数 key_time_double = 0; //清空双击计时 } }break; default:key_state = KEY_STATE_0;break; //特殊情况:key_state是其他值得情况,清零key_state。这种情况一般出现在 没有初始化key_state,第一次执行这个函数的时候 } keynum = new_keynum; //将新获取的键值赋值给键值 return key_return; //返回 按键值 }
举报
本版积分规则 发表回复 回帖并转播 回帖后跳转到最后一页
45
2825
2
扫码关注 21ic 官方微信
扫码关注嵌入式微处理器
扫码关注电源系统设计
扫码关注21ic项目外包
扫码浏览21ic手机版
本站介绍 | 申请友情链接 | 欢迎投稿 | 隐私声明 | 广告业务 | 网站地图 | 联系我们 | 诚聘英才
京公网安备 11010802024343号