搜索
bottom↓
回复: 4

按键检测的细节分析

[复制链接]

出0入0汤圆

发表于 2012-5-11 10:24:36 | 显示全部楼层 |阅读模式
下面是我写的一个键盘检测程序。键盘的底层是用状态机写的,这里没10毫秒扫描一次。
问题是: 键盘只能检测到key_long_set这里,进去后,key_lshort_left,key_short_up都检测不到这是什么问题啊?
         是不是在我按下key_long_set之后的10毫秒里没有按下其他键,他就不检测了?
        还有就是if(keyValue == key_long_set)条件成立的情况下,它里面的内容只执行一次还是一直停在里面了?(这个问题一直困扰我好久)
        
请大家斑斑我分析下,谢谢。




        if(Time10Ms)
        {
                Time10Ms = 0;
                keyValue = read_key_n();       
        }

        if(keyValue == key_long_set)
        {
                InputCode();
                if(keyValue == key_short_left )       
                        {
                                codeWei++;
                                if(codeWei > 5)
                                        {
                                                codeWei = 0;
                                        }       
                        }
                switch(codeWei)
                {
                        case 0:
                                {
                                        if(keyValue == key_short_up)
                                                code5++;
                                        if(code5 > 9)
                                                code5 = 0;
                                } break;
                        case 1:
                                {
                                        if(keyValue == key_short_up)
                                                code4++;
                                        if(code4 > 9)
                                                code4 = 0;       
                                }break;
                        case 2:
                                {
                                        if(keyValue == key_short_up)
                                                code3++;
                                        if(code3 > 9)
                                                code3 = 0;       
                                }break;
                        case 3:
                                {
                                        if(keyValue == key_short_up)
                                                code2++;
                                        if(code2 > 9)
                                                code2 = 0;       
                                }break;
                        case 4:
                                {
                                        if(keyValue == key_short_up)
                                                code1++;
                                        if(code1 > 9)
                                                code1 = 0;       
                                }break;
                        default:break;
                }

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2012-5-11 11:20:25 | 显示全部楼层
本帖最后由 锦瑟华年 于 2012-5-11 11:34 编辑

keyvalue第一次结果为long_set,然后执行inputData()函数,然后下一个if判定不成立,检测退出,10 ms后状态机返回什么呢?是什么状态?还有按键检测有优先级吗?
楼主还是把状态机和底层按键扫描代码也贴下吧。。。。

出0入0汤圆

 楼主| 发表于 2012-5-11 13:40:11 | 显示全部楼层
本帖最后由 3lvictor 于 2012-5-11 13:57 编辑

uchar read_key_n(void)
{
      static uchar key_state = 0, key_time = 0, key_old;  //保存按键的状态值,该变量的值在函数调用结束后不能消失
      uchar key_press,  key_return = 0;

            key_press = key_input & key_mask;                     //读按键I/O电平,每一个10MS都要读IO电平是什么电平

       switch (key_state)
      {
              case key_state_0:                                // 按键初始态
                     if (key_press != key_mask)
                     {
                             key_old = key_press;        // 记录原电平状态 主要是把刚才按下的键值存到变量key_old中
                             key_state = key_state_1;   // 键被按下,状态转换到键确认态
                       }
       // 键被按下,状态转换到键确认态
                     break;
            case key_state_1:                                // 按键确认态
                    if (key_press == key_old)
                     {
                            key_state = key_state_2;        // 按键仍按下,状态转换到计时1
                            key_time = 0;                                // 清零按键时间计数器   开始计数
                     }
                    else
                           key_state = key_state_0;        // 按键已抬起,转换到按键初始态,这说明刚才那是抖动。
                        break;
             case key_state_2:
                    if (key_press == key_mask)     // 按键已经抬起,利用key_old记录了IO电平的状态          这句非常关键

                          {
                                     key_state = key_state_0;        // 按键已释放,转换到按键初始态   这里判断的是单击
              
                                   if     (key_old == 0x0e)  {key_return = key_short_mode;}
                                   else if(key_old == 0x0d)  {key_return = key_short_left;}
                                        else if(key_old == 0x0b)  {key_return = key_short_clr;}
                                        else if(key_old == 0x07)  {key_return = key_short_del;}
                                        else if(key_old == 0x2f)  {key_return = key_short_up; }
                                        else if(key_old == 0x1f)  {key_return = key_short_set;}
   
                    }
                     else if (++key_time >= 100)                // 按键时间计数         说明还是有键按下的
                     {
                         key_state = key_state_3;        // 按下时间>1s,状态转换到计时2
                         key_time = 0;                                // 清按键计数器  
                           
                        if (key_old == 0x0e)  {key_return = key_long_mode;}
                                   else if(key_old == 0x0d)  {key_return = key_long_left;}
                                        else if(key_old == 0x0b)  {key_return = key_long_clr;}
                                        else if(key_old == 0x07)  {key_return = key_long_del;}
                                        else if(key_old == 0x2f)  {key_return = key_long_up; }
                                        else if(key_old == 0x1f)  {key_return = key_long_set;}
            
                       }
                      break;
              case key_state_3:
                        if (key_press==key_mask)        //这里说明长按键也松手了
                           key_state = key_state_0; //按键已释放,转换到按键初始态
                       break;       
       }        
  return key_return;
}


这就是底层的状态机代码。我想问的是:
是不是永远都不可能检测到第二个键按下啊(因为人的反应好慢,根本不可能在10毫秒内再按下第二个键啊?)
我想实现在在某个键按下的情况下,再去检测其他的键,当其他键按下后执行功能函数。这个带吗该如何组织?

出0入0汤圆

发表于 2012-5-11 14:10:52 | 显示全部楼层
3lvictor 发表于 2012-5-11 13:40
uchar read_key_n(void)
{
      static uchar key_state = 0, key_time = 0, key_old;  //保存按键的状态 ...

可以设按键按下标志位啊,有第一个按键按下的标志时候按其他按键才有效

出0入0汤圆

 楼主| 发表于 2012-5-11 14:15:14 | 显示全部楼层
raxb 发表于 2012-5-11 14:10
可以设按键按下标志位啊,有第一个按键按下的标志时候按其他按键才有效

谢谢您的指导
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-27 01:18

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表