打印
[应用方案]

如何设计按键检测的松手检测

[复制链接]
1925|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Thethree|  楼主 | 2016-8-9 08:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
说到按键,我还是有不少研究的,其实按键没我们想的那么简单,要把按键程序写好也不是一件容易的事,功能要求:单击、双击、长按及组合,按下不动,返回有效值速度越来越快,多用在参数调节,这些都是值得大家去研究的,还有8个IO口,让16个独立按键与8个独立按键共同使用这是没有问题的。
        扯远了,今天只讨论如何做松手检测,松手检测意义,很简单,就是按下按键只对应一次操作,不会因为按着不动就不停的返回按键值,我们大多时候见到的松手检测程序就是 “while(!k1)”,一种等待式写法,打个比方,这就如同你插上热得快烧水,你坐在旁边看着,等着水热,拜拜浪费时间。这种写法根本不适应实际应用,拜拜浪费CPU时间。看一下代码:
       功能:按键检测子函数,四个独立按键接在P2口高四位,调用时返回按键值1,2,3,4,没有按键按下返回0.
char ReadKey(void)
{
         static Key_on_off = 0;
         unsigned char num,temp = 0;
        num = P2;                                 //  读取P2口状态
         num&= 0xf0;                         //  屏蔽第四位
         if(num != 0xf0)             //  判断是否有按键按下
          {
            if(Key_on_off == 0)         //  自锁变量
                 {
                         /***********  相对高级的松手检测          ****************/
                 Key_on_off = 1;   // 如果屏蔽这句话,将没有松手检测,数字将加的很快
                          switch(num)                          //  读取按键信息
                                 {
                                   case 0xe0: temp=1;break;
                                   case 0xd0: temp=2;break;
                                   case 0xb0: temp=3;break;
                                   case 0x70: temp=4;break;
                                 }
                /***********  最笨的松手检测          ****************/
                /*                while(num != 0xf0)             //  判断是否有按键按下
                                 {
                                    num = P2;                         //  读取P2口状态
                                    num&= 0xf0;                         //  屏蔽第四位

                                 }          */
                  }
          }
         else
          {
            Key_on_off = 0;    //  当没有任何按键按下时  解锁
          }
                return temp;
}


沙发
Thethree|  楼主 | 2016-8-9 08:59 | 只看该作者
利用一个静态变量Key_on_off,记住一定要是静态的或者全局的,初始化为零,当检测到按键按下的时候,同时要满足Key_on_off等于0,才进入里面判断是哪个按键,同时将Key_on_off置1,那么当按键还没有松开,函数又被第二次及以上调用时,由于Key_on_off等于1,就不按键值解析里面去,按键值返回的是默认的0,属于无效值,着就相当于上了一把锁,那么什么时候解锁了,看下面当检测到没有按键按下的时候,Key_on_off = 0 , 一担松手就解锁,当再次按下的时候出一次有效按键值,再次上锁。如此往返。。。
今天有人提到了我的程序中没有去抖动检测,关于按键的抖动,别人教你的一半都是延时5~10MS再次检测, 想说的是,延时去抖动会拖慢的系统,5MS在我看着这么多么的奢侈,5MS可以执行完成太多的任务,就这么浪费了, 痛心、痛心。
    本函数调用要求为:20~50ms调用一次,就能得到很好的消抖动效果,你可以想象一下,在时间轴上,0时刻检测到按键按下,到10ms时刻再次检测到按键按下,就确定按键按下。首先大家要明白一点,只有按键按下的时候才有电平抖动,没有按按键是没有按键抖动的,去按键抖动是为了防止一次按下按键而而检测到几次按下。在看看我的设计,0时刻检测到按键按下,那么按键肯定按下了,我已经返回了有效值,20MS后抖动已经过去,低电平已经稳定,不会再返回按键有效值,达到去抖动目的。。。
[url=][/url]

使用特权

评论回复
板凳
落叶行健ywm| | 2016-8-9 09:04 | 只看该作者
利用有限状态量就解决了,延时都是学习时使用的。实际根本不会考虑的。

使用特权

评论回复
地板
598330983| | 2016-8-9 11:25 | 只看该作者
松手检测意义,很简单,就是按下按键只对应一次操作,不会因为按着不动就不停的返回按键值

使用特权

评论回复
5
598330983| | 2016-8-9 11:26 | 只看该作者
画了一下波形图,发现也可以通过边沿检测中断实现,比如上升沿中断

使用特权

评论回复
6
bblb| | 2016-8-9 14:51 | 只看该作者
分享,谢了

使用特权

评论回复
7
天灵灵地灵灵| | 2016-8-9 21:59 | 只看该作者
中断的效果应该是最好的,不会影响别的。

使用特权

评论回复
8
天灵灵地灵灵| | 2016-8-9 22:00 | 只看该作者
但是如果在主函数体里面,那就中断用不得了,反过来,如果按着不丢,系统会不会看门狗复位

使用特权

评论回复
9
bobde163| | 2016-8-9 23:32 | 只看该作者
学习一下,希望楼主能再对另外几种情况的分析一下,比如长按有效、放开才有效的情况

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

21

主题

236

帖子

4

粉丝