打印

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

[复制链接]
2138|7
手机看帖
扫描二维码
随时随地手机跟帖
沙发
ztzer| | 2007-12-15 20:11 | 只看该作者

我只是菜鸟

采用键盘专用芯片。

使用特权

评论回复
板凳
平常人| | 2007-12-17 21:26 | 只看该作者

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

而且程序绝对简单,当然硬件成本不低。这个方案把LZ的要求做到了极致。

[这年月错别字满天飞,自己也跟自己过意不去,晕~~~]

使用特权

评论回复
地板
21ic管理员| | 2007-12-17 21:54 | 只看该作者

定时器加状态机……

没有什么开销的,就是每次中断读一次而已,绝对没有“delay_ms(10);”这种代码出现

使用特权

评论回复
5
kunliu| | 2007-12-20 19:09 | 只看该作者

这个问题很简单

这个问题很简单,下面给出两种解决方案
方案一:用硬件去抖,如用一个触发器解决,具体电路网上多得是,这里就不哆嗦了。
方案二:用定时器,如果你的MCU里的定时器IDLE的话,不如叫它WORK。

使用特权

评论回复
6
computer00| | 2007-12-22 12:23 | 只看该作者

俺直接给代码……

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

        欢迎访问我的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
holle| | 2008-2-22 15:31 | 只看该作者

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

考虑不用重入函数
改用switch   case实现的状态机
通过多个参数传递键盘消息

使用特权

评论回复
8
jx_207| | 2008-2-26 20:09 | 只看该作者

状态机方法

4楼方法比较好,偶用过,相当好。能做按下,弹起,多键检测.

使用特权

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

本版积分规则

144

主题

566

帖子

3

粉丝