打印

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

[复制链接]
3439|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
dsoyy|  楼主 | 2007-12-14 13:35 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
阿南| | 2007-12-14 18:10 | 只看该作者

那就用定时中断吧

使用特权

评论回复
板凳
yatelanda| | 2007-12-14 23:06 | 只看该作者

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

这样既不与任务抢占CPU,又能提高CPU利用率.

使用特权

评论回复
地板
1dqmoon| | 2007-12-15 00:02 | 只看该作者

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

定时一次,如果此时有键按下,则累加1,
         如果没有键按下,累加器清零

使用特权

评论回复
5
玄德| | 2007-12-15 18:44 | 只看该作者

这可是基本功。

应当这样:
初次检测到有键被按下时,启动定时器,设中断,等等。
当时间达到你的设定值(几毫秒吧),就再次检测按键。如果结果同上一次一样,则说明确实有按键;否则说明不是。
也可以不用定时器,可以很灵活。

使用特权

评论回复
6
computer00| | 2007-12-15 19:08 | 只看该作者

看看俺这个:

KeyPress反映的当前按下的键情况,KeyDown表示有键按下,KeyUp表示有键送开。总共八个键,由8个bit表示。

/******************************************************************
   本程序只供学习使用,未经作者许可,不得用于其它任何用途

        欢迎访问我的USB专区:http://group.**/93/
        欢迎访问我的blog:   http://www.**/blog/computer00
                             http://computer00.21ic.org

KEY.C  file

作者:Computer-lov
建立日期: 2007.03.20
修改日期: 2007.11.18
版本:V1.2
版权所有,盗版必究。
Copyright(C) Computer-lov 2007-2017
All rights reserved            
*******************************************************************/




#include "Key.h"
#include "my_type.h"
#include "config.h"

volatile uint8 idata KeyCurrent,KeyOld,KeyNoChangedTime;
volatile uint8 idata KeyPress;
volatile uint8 idata KeyDown,KeyUp,KeyLast;

volatile uint8 KeyCanChange;

/********************************************************************
函数功能:定时器0初始化,用来做键盘扫描,定时时间大约为5ms。
入口参数:无。
返    回:无。
备    注:无。
********************************************************************/
void InitTimer0(void)
{
 TMOD&=0xF0;
 TMOD|=0x01;
 TH0=0xDC;
 ET0=1;
 TR0=1;
}
/*******************************************************************/


/********************************************************************
函数功能:键盘初始化
入口参数:无。
返    回:无。
备    注:无。
********************************************************************/
void InitKeyboard(void)
{
 KeyIO=0xFF;      //键盘对应的口设置为输入状态
 KeyPress=0;          //无按键按下
 KeyNoChangedTime=0;
 KeyOld=0;
 KeyCurrent=0;
 KeyLast=0;
 KeyDown=0;
 KeyUp=0;
 InitTimer0();          //初始化定时器
 KeyCanChange=1;      //允许键值改变
}
/*******************************************************************/

/********************************************************************
函数功能:定时器0中断处理。
入口参数:22.1184M晶体约5ms中断一次。
返    回:无。
备    注:无。
********************************************************************/
void Timer0Isr(void) interrupt 1

 TH0=(65536-Fclk/1000/12*5+15)/256;     //定时器0重装
 TL0=(65536-Fclk/1000/12*5+15)%256;

 if(!KeyCanChange)return;     //如果正在处理按键,则不再扫描键盘 

 //开始键盘扫描
 //保存按键状态到当前按键情况
 //KeyCurrent总共有8个bit
 //当某个开关按下时,对应的bit为1
      
 KeyCurrent=~KeyIO;    

 if(KeyCurrent!=KeyOld)  //说明按键情况发生了改变
  {
   KeyNoChangedTime=0;       //键盘按下时间为0
   KeyOld=KeyCurrent;        //保存当前按键情况
   return;
  }
 else
  {
   KeyNoChangedTime++;         //按下时间累计
   if(KeyNoChangedTime>=1)     //如果按下时间足够
    {
     KeyNoChangedTime=1;
     KeyPress=KeyOld;      //保存按键
     KeyDown|=(~KeyLast)&(KeyPress); //求出新按下的键
     KeyUp|=KeyLast&(~KeyPress);     //求出新释放的键
     KeyLast=KeyPress;                 //保存当前按键情况
    }
  }
}
/*******************************************************************/

使用特权

评论回复
7
gouki_s| | 2007-12-17 13:17 | 只看该作者

to: yatelanda

不要误导别人

使用特权

评论回复
8
xwj| | 2007-12-17 16:15 | 只看该作者

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

程序流程如下:

我设计按键程序的思路:
1、一般都不在键盘程序中延时,而是通过隔一段时间调用(比如10毫秒)来扫描按键,以尽量释放CPU资源;
2、所有键盘程序基本上都是一个模式,可以处理加速键、一键多功能等情况;
3、对外接口只有2个,换用不同硬件的键盘只需把该键盘程序加入工程编译即可,其他不需要作任何改动,非常方便。


基本上都是一个模式:
有键?--YES——和上次相同?--No--Keyold=0;退出 
  |      |
  |     YES--Keyold++;
  |      |
  |     Keyold==首键延时KEYDELAY?--No--退出
  |      |
  |     YES--Keyok=1;     //按下不放一定时间发首键,后面发加速键
  |            保存键值到Keydata;(必要时译码)
  |            Keyold=KEYDELAY-KEYLOOP(按住不放的延时);--退出
  |
  No--Keyold==0?--YES--退出
            |
           N0--Keyok=1;    //不为0说明按了键再放开,当然作按键有效处理
                 保存键值到Keydata;(必要时译码)
                 Keyold=0;--退出

所有键盘程序对外接口:
unsigned char KeyGetCode(void)        //返回按键码
{
    key_ok=0;
    return(key_data);
}

bit KeyTest(void)            //检查有无按键
{
    KeyScan();            //键扫描
    return(key_ok);
}
    

 
 

相关链接:https://bbs.21ic.com/club/bbs/showEssence.asp?id=6186&page=2

使用特权

评论回复
9
fffzxm| | 2007-12-17 21:46 | 只看该作者

有些ARM带硬件按键功能

硬件上实现抖动消除,占用CPU最低

使用特权

评论回复
10
dsoyy|  楼主 | 2007-12-18 14:22 | 只看该作者

非常感谢大家

使用特权

评论回复
11
dsoyy|  楼主 | 2007-12-18 14:24 | 只看该作者

以前学校学到的都是延时

我用了计数器的方法

使用特权

评论回复
12
龙飞天下| | 2007-12-19 15:14 | 只看该作者

学校的课程真实误导人

定式扫描这是对键盘处理的不二选择。至于你是用状态机,还是裸奔没有关系。
小键盘,大学问。
00的程序不错,好像和Jean J. Labrosse编程思想差不多。

是不是现在的研究生有专门研究状态机的编程方法。

使用特权

评论回复
13
dsoyy|  楼主 | 2007-12-20 17:11 | 只看该作者

小键盘,大学问。

谢谢热心的朋友,以后还请多多指教。

使用特权

评论回复
14
fluke56512| | 2007-12-20 19:08 | 只看该作者

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

在我们公司,按键去抖是我们搞硬件的活。

丫一低通就搞定了,还靠编程解决??

使用特权

评论回复
15
sz_kd| | 2007-12-20 19:51 | 只看该作者

去抖还用硬件来

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

144

主题

566

帖子

3

粉丝