请教:按键去抖怎么样对CPU使用率最低?

[复制链接]
4399|14
 楼主| dsoyy 发表于 2007-12-14 13:35 | 显示全部楼层 |阅读模式
我用延时函数。头说CPU使用率太高,说用计数的办法,我没有太明白,请指教!急!<br />谢谢!&nbsp;小弟初学。
阿南 发表于 2007-12-14 18:10 | 显示全部楼层

那就用定时中断吧

  
yatelanda 发表于 2007-12-14 23:06 | 显示全部楼层

最好是在操作系统的idle状态下去检查按键

这样既不与任务抢占CPU,又能提高CPU利用率.
1dqmoon 发表于 2007-12-15 00:02 | 显示全部楼层

你头说的就是计算按键时间

定时一次,如果此时有键按下,则累加1,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果没有键按下,累加器清零
玄德 发表于 2007-12-15 18:44 | 显示全部楼层

这可是基本功。

应当这样:<br />初次检测到有键被按下时,启动定时器,设中断,等等。<br />当时间达到你的设定值(几毫秒吧),就再次检测按键。如果结果同上一次一样,则说明确实有按键;否则说明不是。<br />也可以不用定时器,可以很灵活。<br />
computer00 发表于 2007-12-15 19:08 | 显示全部楼层

看看俺这个:

KeyPress反映的当前按下的键情况,KeyDown表示有键按下,KeyUp表示有键送开。总共八个键,由8个bit表示。<br /><br />/******************************************************************<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 />/*******************************************************************/<br />
gouki_s 发表于 2007-12-17 13:17 | 显示全部楼层

to: yatelanda

不要误导别人
xwj 发表于 2007-12-17 16:15 | 显示全部楼层

不要用延时,要用隔一段时间扫描一次的方式

程序流程如下:<br /><br />我设计按键程序的思路:<br />1、一般都不在键盘程序中延时,而是通过隔一段时间调用(比如10毫秒)来扫描按键,以尽量释放CPU资源;<br />2、所有键盘程序基本上都是一个模式,可以处理加速键、一键多功能等情况;<br />3、对外接口只有2个,换用不同硬件的键盘只需把该键盘程序加入工程编译即可,其他不需要作任何改动,非常方便。<br /><br /><br />基本上都是一个模式:<br />有键?--YES——和上次相同?--No--Keyold=0;退出&nbsp;<br />&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br />&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;YES--Keyold++;<br />&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br />&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Keyold==首键延时KEYDELAY?--No--退出<br />&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br />&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;YES--Keyok=1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//按下不放一定时间发首键,后面发加速键<br />&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;保存键值到Keydata;(必要时译码)<br />&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Keyold=KEYDELAY-KEYLOOP(按住不放的延时);--退出<br />&nbsp;&nbsp;|<br />&nbsp;&nbsp;No--Keyold==0?--YES--退出<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;N0--Keyok=1;&nbsp;&nbsp;&nbsp;&nbsp;//不为0说明按了键再放开,当然作按键有效处理<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;保存键值到Keydata;(必要时译码)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Keyold=0;--退出<br /><br />所有键盘程序对外接口:<br />unsigned&nbsp;char&nbsp;KeyGetCode(void)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//返回按键码<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;key_ok=0;<br />&nbsp;&nbsp;&nbsp;&nbsp;return(key_data);<br />}<br /><br />bit&nbsp;KeyTest(void)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//检查有无按键<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;KeyScan();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//键扫描<br />&nbsp;&nbsp;&nbsp;&nbsp;return(key_ok);<br />}<br />&nbsp;&nbsp;&nbsp;&nbsp;<br /><br />&nbsp;<br />&nbsp;<br /> <br /> 相关链接:<a href='https://bbs.21ic.com/club/bbs/showEssence.asp?id=6186&page=2'>https://bbs.21ic.com/club/bbs/showEssence.asp?id=6186&page=2</a>
fffzxm 发表于 2007-12-17 21:46 | 显示全部楼层

有些ARM带硬件按键功能

硬件上实现抖动消除,占用CPU最低
 楼主| dsoyy 发表于 2007-12-18 14:22 | 显示全部楼层

非常感谢大家

  
 楼主| dsoyy 发表于 2007-12-18 14:24 | 显示全部楼层

以前学校学到的都是延时

我用了计数器的方法
龙飞天下 发表于 2007-12-19 15:14 | 显示全部楼层

学校的课程真实误导人

定式扫描这是对键盘处理的不二选择。至于你是用状态机,还是裸奔没有关系。<br />小键盘,大学问。<br />00的程序不错,好像和Jean&nbsp;J.&nbsp;Labrosse编程思想差不多。<br /><br />是不是现在的研究生有专门研究状态机的编程方法。
 楼主| dsoyy 发表于 2007-12-20 17:11 | 显示全部楼层

小键盘,大学问。

谢谢热心的朋友,以后还请多多指教。
fluke56512 发表于 2007-12-20 19:08 | 显示全部楼层

你们的软件工程师真勤快啊。

在我们公司,按键去抖是我们搞硬件的活。<br /><br />丫一低通就搞定了,还靠编程解决??
sz_kd 发表于 2007-12-20 19:51 | 显示全部楼层

去抖还用硬件来

  
您需要登录后才可以回帖 登录 | 注册

本版积分规则

144

主题

566

帖子

3

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