- 1、本文档共5页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
一个即简单经济又稳定可靠的独立按键检测设计方案
一个即简单经济又稳定可靠的独立按键检测设计方案 【摘要】本文首先简要介绍了独立按键检测主动查询与中断查询这两种方式的优缺点。根据这两种方式的优缺点,本文着重讨论了具有跟大优势的中断查询方式的按键检测方案的实现原理和过程。并且,针对按键普遍存在的抖动问题,本文由简单到复杂的过渡方式,详细深入地介绍进行方案的优化和改良的目的以及方法
【关键词】按键延时抖动扫描
1主动查询方式的优缺点
对于主动循环查询方式,最大的优点在于原理简单,比较适合于MCU处理的任务不是特别多的情况。如果MCU大循环的轮询周期较长,很有可能在按键按下的瞬间错过了。这是主动查询方式的最大缺点。另外,该方式比较浪费CPU的时间资源。检测按键的处理程序需要有个延迟消抖的过程。对于机械弹性开关,一般需要的的延迟消抖时间为10ms。很多程序都是使用一般的延时函数来实现消抖的目的。然而对于很多复杂的产品,CPU需要执行繁重的任务。在10ms时间里,CPU可以执行上千上万条其他任务的汇编指令
2中断查询的方式的优缺点
中断查询方式主要缺点在于,该方式需要占用MCU一个外部中断功能(有些功能简单、价钱低廉的MCU,其IO引脚复用功能资源有限),以及处理程序稍微复杂一下。与主动查询相比,中断查询方式则有响应时间短、稳定可靠等优点。一旦有中断响应,CPU一定立即响应中断请求。因此,中断查询方式不存在“错过”、“漏检”的情况。按键检测的原理图设计图1所示:
图1 按键检测的原理图设计图
在原理图1设计中,为了检验按键被按下,MCU在中断服务程序里,通过程序翻转LED亮灭状态,以便读者更容易理解其中的原理机制
经过测试,每按一下按键,LDE灯都实现了翻转的动作。该函数基本实现了预期的功能。在中断函数里,笔者使用了简单的的概率统计方法,提高准确性。这个中断服务程序运行的时间大概为5us*20=0.1ms,远远少于相对通常的软件延时方式所用的10ms,因此提高了CPU对资源的使用效率。但是,以上的中断服务程序尚未彻底解决处理机械弹性按键本质上所具有的脉冲抖动的问题。首先,笔者在此描述以上程序运行起来后有何不良症状。有些情况下,按下一次按键,LED灯会翻转2遍。有极少数情况下,LED甚至连续翻转3到4次。这种现象不是用户所期望的。这说明以上程序设计仍达不到稳定的要求,很有必要进行再深入的代码优化
结合以上给出的中断服务程序,我们就很容易理解LED连续翻转的现象了。不论图中提到的前沿抖动还是后沿抖动,均可能导致CPU再次、多次进入中断处理程序。因此,问题的重点在于,如何通过优化算法和代码,在按键抖动期间,避免多次进入中断,或者避免进入中断后重复执行相同的任务。本文从实现的难易程度这个角度考虑,选择了后者,即结合MCU定时器的功能,达到了“避免进入中断后重复执行相同的任务”的目的
以下笔者讲解了在原有程序的基础上,如何结合MCU定时器的功能,进一步彻底解决按键抖动带来的不稳定问题。考虑到有部分读者的基础可能不是太好,为了降低本文设计思路的理解难度,笔者认为很有必要先给读者简要介绍一下有关定时器几个非常经典的函数及其功能意义。关于定时器,有以下5个相关的函数:
函数1:void clock_init(void)
对于函数1,顾名思义,该函数就是要对定时器temer进行初始化,否则函数2~5无效
函数2:void timer_set(struct timer *t, clock_time_t interval)
该函数用于设置某定时器timer需要的时间间隔interval大小(以ms为单位)。这就好比如有个漏水的水龙头。水龙头间隔恒定时间里每一滴的滴水大小,相当于函数里定时器的最小计数单位。水龙头下面有个刻有刻度的水杯。而这里的interval,则相当于水杯的容量
函数3:int timer_expired(struct timer *t)//判断定时器timer是否时间满了,为真返回1,否则返回0。这就好比如,某人外出走开了,在她回来之前看到水杯的前一刻,她不知道水杯是否满了,因为她不知道自己离开了多长时间。而水杯里的水从完全没水到刚好积满这个时间差,永远都是固定的。如果一直没人将水杯倒掉,超过这个时间差,则水杯将一直处于溢出的状态。当她回来查看水杯到底满了还是没满的这个动作,相当于程序执行了该函数。她只有两个可能的结果,要么水杯满了,要么还没满
函数4:void timer_reset(struct timer *t)//复位定时器timer。该函数相当于水杯汇聚的滴水,不论水杯里的水有多满,一律将水全倒掉,在将水杯放回水龙头下面重新积水
函数5:void timer_restart(struct ti
文档评论(0)