Google
载入中...




站长个人入口
载入中...


公告
载入中...


我的分类(专题)
载入中...


日志更新
载入中...


最新评论
载入中...


留言板
载入中...


链接
 
 

说说按键处理
手心 发表于 2006-11-13 18:34:00
    单片机书本上对于键盘处理往往都给出了几种不同的方案,但是在一个实际的系统应用中,往往用起来感觉不是很好。主要的弊端就是实时性不好。无论是采用中断方式还是采用扫描方式,实行性都不能很好的达到要求。
    对于键盘,大家都知道有抖动,最最常用的消除抖动的方法就是用软件消抖。但是书本上的软件消抖基本都是用一个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;的语句放到键扫描程序内就可以了。
    可以看到,对于这样的三线处理键盘的方式,外部中断内和时间中断内都只有几条语句就可以处理
    时,抖动延时的过程由于放到了定时中断内,这个时间可以用来做其他的任务,大大的提高了系统的实时性能。
   对于语音多段播放的程序处理,显示闪烁的处理等需要大量延时的程序,都可以采用这样的结构,可以大大的提高系统的实时性,若各位对于语音多段播放的处理方式希望了解如何实现,过段时间在写这个。

阅读全文 | 回复(10) | 引用通告 | 编辑
 


Re:
xdly1986发表评论于2008-1-4 20:24:00
xdly1986感觉很不错
早看到这个的话说不定工作就定下来了

个人主页 | 引用 | 返回 | 删除 | 回复
 


Re:说说按键处理
新手求教(游客)发表评论于2007-5-26 9:34:00
新手求教(游客)之前一直为书上的按键程序困惑,用DELAY 其不是浪费好多时间
看了您的这篇文章 真的很好 想了想 根据您的思路 按键触发中断 可以这样写。可是进了中断后,按键不松手 怎么再次触发进入中断???? 否则 就只能扫描了,如果用扫描,就不需要定时器了,只要每扫一次,time++,大于60是常按键,大于10是短按键就行
您能否 再指点下出发中断的情况 谢谢
void key_scan(void) interrupt 0
{
if(key.flag==1) //先判断是否有键按下
{
if(time > 60) //常按键则
{

}
else //短按键 则
{

}
}
ekse
{
key.flag=1; //有按键引发中断,则置位标志位
TR0 = 1; //T0运行,定时中断内 有一常按键
} // 标志 time++
}
以下为blog主人的回复:
注意:key_scan函数不是中断处理函数!
key_scan函数是主程序中一个处理扫描的函数而已。
中断函数很简单。他仅仅是将key.flag=1处理。

仔细看三条线处理流程。

个人主页 | 引用 | 返回 | 删除 | 回复
 


Re:说说按键处理
maxing(游客)发表评论于2007-3-22 11:13:00
maxing(游客)手心前辈这篇文章很好呀!简洁易明又好实施!
希望前辈有时间补充上语音多段播放的处理方法!

个人主页 | 引用 | 返回 | 删除 | 回复
 


Re:说说按键处理
yjrshhic发表评论于2006-12-11 16:35:00
yjrshhic直接用周立功的ZLG7290芯片,7块钱,与8279功能差不多,I2C接口的,很好用,我刚用过!
以下为blog主人的回复:
用周立功的芯片。我也用过啊。
但是用这个芯片也会有几个问题需要注意解决。
由于7290的封装决定了该芯片易受干扰,在电磁干扰比较强的场合不好用,需要加一些处理措施。
第二,该芯片存在交货周期,当你公司的订单很急的时候,你确不能从周立功那里及时的拿到足够的芯片,也够你受的了。
第三,用周立功的芯片,无论你的价钱怎么样,比起用通用芯片还是要贵一些的。成本要高一些。

个人主页 | 引用 | 返回 | 删除 | 回复
 


Re:说说按键处理
零零碎碎(游客)发表评论于2006-12-6 19:36:00
零零碎碎(游客)你的方法也好,这是业界不成文的规定了,交个朋友,QQ48392599

个人主页 | 引用 | 返回 | 删除 | 回复
 


Re:说说按键处理
art6158(游客)发表评论于2006-11-29 15:58:00
art6158(游客)看你用在什么方面,如果控制比较严格的如医疗等,还是加个按键消抖动芯片,一般的场合还是中断内延时20ms后再次判断一下是否有按键按下较多吧。

个人主页 | 引用 | 返回 | 删除 | 回复
 


Re:说说按键处理
emailli发表评论于2006-11-28 9:55:00
emailli对于长按,怎么会有问题呢?
你想将长按做成连击或者是纯粹的长按都可以啊。
做成连击,只要在按键时间超过一定时间就清除标志位就可以实现第二次检测了啊。
做成纯粹的按键,可以添加一个按键释放判断解决啊。
还有,关于键值的判断是通过另外一个函数处理的,这里只是判断键是否可靠按下。
但是又不占用系统太多的时间的方法。无论你是多少个按键怎么做分支处理都不是该函数的功能。
用硬件消抖好像没有人这么做哦。成本是一个大问题。

个人主页 | 引用 | 返回 | 删除 | 回复
 


Re:说说按键处理
hnclcj(游客)发表评论于2006-11-25 11:53:00
hnclcj(游客)我决定你的方法 还有待改进的地方,
你这样的做法 如果是要实行 按下 连续 长按 送开 等识别的话 程序也不是很好做 如果每个开发项目的键盘数量和结构不一样的话 KEY相关的部分修改也大, 弄不好 上面的应用程序也得该动.

个人主页 | 引用 | 返回 | 删除 | 回复
 


Re:说说按键处理
lzh08发表评论于2006-11-16 11:08:00
lzh08直接加一个芯片处理算了,芯片在里面就去抖了,直接读输出结果,就是成本高了点,但是稳定得多。

个人主页 | 引用 | 返回 | 删除 | 回复
 


Re:说说按键处理
野渡横舟发表评论于2006-11-13 23:49:00
野渡横舟但硬件开销挺大的
以下为blog主人的回复:
想知道为什么硬件开销大?

个人主页 | 引用 | 返回 | 删除 | 回复
 


发表评论:
载入中...