倚楼等红颜的个人空间 https://bbs.21ic.com/?1553790 [收藏] [复制] [RSS]

日志

按键原理

已有 182 次阅读2017-5-12 15:28 |系统分类:兴趣爱好

单片机书本上对于键盘处理往往都给出了几种不同的方案,但是在一个实际的系统应用中,往往用起来感觉不是很好。主要的弊端就是实时性不好。无论是采用中断方式还是采用扫描方式,实行性都不能很好的达到要求。
    对于键盘,大家都知道有抖动,最最常用的消除抖动的方法就是用软件消抖。但是书本上的软件消抖基本都是用一个Delay函数来实现10-20ms的延时。
而一个前后台的系统,也许一个程序运行下来也就20ms,而由于有键盘延时判断的存在,将导致整个系统运行都慢了下来。
   对此,实际应用中有一种处理方法。该方法有三条主线来处理。
    第一条线:
    采用外部中断方式(或者扫描方式)检查是否有键被按下。如果有,仅仅将一个标志位置位,表示有键按下了。姑且定义这个标志位为key.flag。如果进入中断,则 key.flag = 1;
    第二条线:
    系统应该提供一个10ms的定时器,作为系统的时间片。在定时中断内检测是否key.flag==1,如果该标志位为1,则表示已经检测到有键按下,则启动计时,计时变量定义为key.times。可以用代码if( key.flag==1) {key.times++}来统计检测到按键以后进入10ms系统定时中断的次数。
    第三条线:
    键扫描处理,主程序则主要判断是否有键被按下,按下以后是否计时变量大于某个值(该值决定你想定义的消抖时间)。比如如下处理:
    (键对应引脚没有按下时为高电平,按下则变低电平,采用下降沿中断方式检测按键)
    void    key_scan(void)
    {
        if(key.flag==1)         //先判断是否有键按下
        {
            if( key.times >2 )  //再判断是否离检测到按键有超过20ms
            {
                if( KEYPIN == 0  )  //对应引脚是否还为0
                {
                     key.value = 0xxx;   //获取键值
                     
                 }
             }
        }
    }
    对于
采用扫描方式的,只需要将中断内 key.flag = 1;的语句放到键扫描程序内就可以了。

    可以看到,对于这样的三线处理键盘的方式,外部中断内和时间中断内都只有几条语句就可以处理
    时,抖动延时的过程由于放到了定时中断内,这个时间可以用来做其他的任务,大大的提高了系统的实时性能。
   对于语音多段播放的程序处理,显示闪烁的处理等需要大量延时的程序,都可以采用这样的结构,可以大大的提高系统的实时性,若各位对于语音多段播放的处理方式希望了解如何实现,过段时间在写这个。

路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)