怎么样按键去抖对CPU使用小啊

[复制链接]
 楼主| dsoyy 发表于 2007-12-14 13:23 | 显示全部楼层 |阅读模式
不用延时函数,怎么样按键去抖对CPU使用小啊
ztzer 发表于 2007-12-15 20:11 | 显示全部楼层

我只是菜鸟

采用键盘专用芯片。
平常人 发表于 2007-12-17 21:26 | 显示全部楼层

加一个硬件去抖电路,可以最大程度节省CPU开销

而且程序绝对简单,当然硬件成本不低。这个方案把LZ的要求做到了极致。<br /><br />[这年月错别字满天飞,自己也跟自己过意不去,晕~~~]
21ic管理员 发表于 2007-12-17 21:54 | 显示全部楼层

定时器加状态机……

没有什么开销的,就是每次中断读一次而已,绝对没有“delay_ms(10);”这种代码出现
kunliu 发表于 2007-12-20 19:09 | 显示全部楼层

这个问题很简单

这个问题很简单,下面给出两种解决方案<br />方案一:用硬件去抖,如用一个触发器解决,具体电路网上多得是,这里就不哆嗦了。<br />方案二:用定时器,如果你的MCU里的定时器IDLE的话,不如叫它WORK。
computer00 发表于 2007-12-22 12:23 | 显示全部楼层

俺直接给代码……

/******************************************************************<br />&nbsp;&nbsp;&nbsp;本程序只供学习使用,未经作者许可,不得用于其它任何用途<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;欢迎访问我的USB专区:http://group.**/93/<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;欢迎访问我的blog:&nbsp;&nbsp;&nbsp;http://www.**/blog/computer00<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;http://computer00.21ic.org<br /><br />KEY.C&nbsp;&nbsp;file<br /><br />作者:Computer-lov<br />建立日期:&nbsp;2007.03.20<br />修改日期:&nbsp;2007.11.18<br />版本:V1.2<br />版权所有,盗版必究。<br />Copyright(C)&nbsp;Computer-lov&nbsp;2007-2017<br />All&nbsp;rights&nbsp;reserved&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />*******************************************************************/<br /><br /><br /><br /><br />#include&nbsp;&quot;Key.h&quot;<br />#include&nbsp;&quot;my_type.h&quot;<br />#include&nbsp;&quot;config.h&quot;<br /><br />volatile&nbsp;uint8&nbsp;idata&nbsp;KeyCurrent,KeyOld,KeyNoChangedTime;<br />volatile&nbsp;uint8&nbsp;idata&nbsp;KeyPress;<br />volatile&nbsp;uint8&nbsp;idata&nbsp;KeyDown,KeyUp,KeyLast;<br /><br />volatile&nbsp;uint8&nbsp;KeyCanChange;<br /><br />/********************************************************************<br />函数功能:定时器0初始化,用来做键盘扫描,定时时间大约为5ms。<br />入口参数:无。<br />返&nbsp;&nbsp;&nbsp;&nbsp;回:无。<br />备&nbsp;&nbsp;&nbsp;&nbsp;注:无。<br />********************************************************************/<br />void&nbsp;InitTimer0(void)<br />{<br />&nbsp;TMOD&=0xF0;<br />&nbsp;TMOD|=0x01;<br />&nbsp;TH0=0xDC;<br />&nbsp;ET0=1;<br />&nbsp;TR0=1;<br />}<br />/*******************************************************************/<br /><br /><br />/********************************************************************<br />函数功能:键盘初始化<br />入口参数:无。<br />返&nbsp;&nbsp;&nbsp;&nbsp;回:无。<br />备&nbsp;&nbsp;&nbsp;&nbsp;注:无。<br />********************************************************************/<br />void&nbsp;InitKeyboard(void)<br />{<br />&nbsp;KeyIO=0xFF;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//键盘对应的口设置为输入状态<br />&nbsp;KeyPress=0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//无按键按下<br />&nbsp;KeyNoChangedTime=0;<br />&nbsp;KeyOld=0;<br />&nbsp;KeyCurrent=0;<br />&nbsp;KeyLast=0;<br />&nbsp;KeyDown=0;<br />&nbsp;KeyUp=0;<br />&nbsp;InitTimer0();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//初始化定时器<br />&nbsp;KeyCanChange=1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//允许键值改变<br />}<br />/*******************************************************************/<br /><br />/********************************************************************<br />函数功能:定时器0中断处理。<br />入口参数:22.1184M晶体约5ms中断一次。<br />返&nbsp;&nbsp;&nbsp;&nbsp;回:无。<br />备&nbsp;&nbsp;&nbsp;&nbsp;注:无。<br />********************************************************************/<br />void&nbsp;Timer0Isr(void)&nbsp;interrupt&nbsp;1<br />{&nbsp;<br />&nbsp;TH0=(65536-Fclk/1000/12*5+15)/256;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//定时器0重装<br />&nbsp;TL0=(65536-Fclk/1000/12*5+15)%256;<br /><br />&nbsp;if(!KeyCanChange)return;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//如果正在处理按键,则不再扫描键盘&nbsp;<br /><br />&nbsp;//开始键盘扫描<br />&nbsp;//保存按键状态到当前按键情况<br />&nbsp;//KeyCurrent总共有8个bit<br />&nbsp;//当某个开关按下时,对应的bit为1<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;KeyCurrent=~KeyIO;&nbsp;&nbsp;&nbsp;&nbsp;<br /><br />&nbsp;if(KeyCurrent!=KeyOld)&nbsp;&nbsp;//说明按键情况发生了改变<br />&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;KeyNoChangedTime=0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//键盘按下时间为0<br />&nbsp;&nbsp;&nbsp;KeyOld=KeyCurrent;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//保存当前按键情况<br />&nbsp;&nbsp;&nbsp;return;<br />&nbsp;&nbsp;}<br />&nbsp;else<br />&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;KeyNoChangedTime++;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//按下时间累计<br />&nbsp;&nbsp;&nbsp;if(KeyNoChangedTime&gt=1)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//如果按下时间足够<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;KeyNoChangedTime=1;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;KeyPress=KeyOld;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//保存按键<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;KeyDown|=(~KeyLast)&(KeyPress);&nbsp;//求出新按下的键<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;KeyUp|=KeyLast&(~KeyPress);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//求出新释放的键<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;KeyLast=KeyPress;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//保存当前按键情况<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;}<br />}<br />/*******************************************************************/
holle 发表于 2008-2-22 15:31 | 显示全部楼层

我刚开始学习单片机时也考虑过这个问题

考虑不用重入函数<br />改用switch&nbsp;&nbsp;&nbsp;case实现的状态机<br />通过多个参数传递键盘消息
jx_207 发表于 2008-2-26 20:09 | 显示全部楼层

状态机方法

4楼方法比较好,偶用过,相当好。能做按下,弹起,多键检测.
您需要登录后才可以回帖 登录 | 注册

本版积分规则

144

主题

566

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部