《匠人手记》推荐网上购书渠道:
互动出版网(china-pub)购书入口   >>>
当当网(dangdang)购书入口   >>>
卓越亚马逊网 购书入口   >>>
淘宝网(taobao)购书入口   >>>
更多购书渠道……   >>> 

设为首页加入收藏联系匠人管理入口21IC首页21IC博客21IC社区侃单片机回复的贴参与的贴

天气预报
百宝日历
载入中...

百宝专栏

载入中...
最新货色

载入中...

粉丝评论

载入中...

载入中...



百宝信息

载入中...

百宝流量

(2006-07-01开始)


匠人手记

 匠人观点: 好记性不如烂笔头  
 黑色幽默:三鹿门——后世畅想

一种软件去除键抖动的方法
程序匠人 发表于 2006-6-17 20:19:00  阅读全文 | 回复(2) | 引用通告 | 编辑

一种软件去除键抖动的方法
来源:单片机及嵌入式系统应用 肖广安    时间:2006-05-16     发布人:meitai

  概述

在单片机控制系统中,通过按键实现控制功能是很常见的。对按键处理的重要环节是去抖动,包括去除按下和抬起瞬间的抖动。去抖动的方法有很多种,如使用R-S触发器的硬件方法、运用不同算法的各种软件方法等。硬件方法会增加成本和体积,对于按键较多的矩阵式键盘,会用硬件方法;软件方法用的比较普遍,但有一种加固定延时的去抖动法效率最低,它以无谓地耗费机时来实现去抖动。

此处介绍的是一种软件方法。简单说来是一种运算法,配合定时中断读取按键,通过运算逻辑表达式:

Keradyn=Ktemp Kinput+Kreadyn-1 (Ktemp ⊙Kinput)    (1)

Ktemp=Kinput    (2)

可以获得消除抖动的按键消息。这种方法效率高,不需耗时的循环等待,而且算法简单、使用方便。

  一、基本原理

由于按键的按下与抬起都会有10~20ms的抖动毛刺存在,因此,为了获取稳定的按键信息,须要避开这段抖动期。

设置3个变量Kready、Ktemp和Kinput,并设置定时中断周期为20ms。在定时中断服务程序中读取按键,并把读取的数据存于变量Kinput中。变量Kready中是所需要的稳定的按键信息;Ktemp是中间变量,它的值是上一次的Kinput。

根据当前按键的状态,考虑到Kready中是20ms抖动后的有效键信息,则Kready、Ktemp和Kinput之间,在不同时刻的状态关系如表1所列。

  表1 

时 刻 Kready Ktemp Kinput
1 0 0 0
2 0 0 1
3 0 1 0
4 0 0 1
5 1 1 1
6 1 1 1
7 1 1 0
8 1 0 1
9 1 1 0
10 0 0 0
11 0 0 0

时刻1为没有键按下的初始状态;时刻2的Kinput为1,但时刻3的Kinput又变为0,说明时刻2的Kinput为1并不是有键按下,可能只是干扰,所以Kreqdy为0;时刻4同时刻2的情况类似,但是时刻4和时刻5时Kinput都为1,说明有按键按下,在时刻5时Kready为1;虽然时刻7时Kinput为0,但时刻5、6、8时Kinput都为1,说明按键一直按下,只不过有干扰,Kready保持为1;时刻9、10连续两个时刻Kinput为0,表示按键抬起,时刻10时Kready为0。

通过分析可以看出,Kready中是消除了抖动并在一定程度上排除了干扰的有效按键信息。从按键按下到Kready为1,最长时间约为40ms,最短约为20ms。其时间长短取决于键按下时处于定时中断周期的所在时刻。如果按键一直按下,则有效键信息以20ms的间隔重复输出。

仔细分析表1,还可知道当前时刻Kready的值不但与Ktemp和Kinput有关,还与Kready前一时刻的值有关。我们把Keady的当前时刻记作Kreadyn,作为因变量;前一时刻记作Kreadyn-1,并和Ktemp、Kinput一起作为自变量,依照表1绘出卡诺图如图1所示。

表达式(1)就是由图1的卡诺图得出的最简逻辑表达式。

二、实际应用扩展

表达式(1)中的Kready提供的是间隔20ms的重复键信息;有的地址不需要重复键值,按一次键获得一次键值就够了;而有的应用系统则两种键值都要有,比如电视监控系统的控制键盘中对镜头云台的控制需要重复键值,其他命令键则不需要。为了满足这种要求,就要对表达式(1)进行扩展。为此,引入了另外两个变量和1个常量。它们分别是Koutput、Kstore和Kconst。Koutput作为最终的键信息输出;Kstore作为中间变量用作保存上一次去抖动后的键信息;Kconst是常量,它的值需要先给定;0对应非重复键,1则对应重复键。

表露Koutput、Kconst、Kstore和Kready之间关系的真值表如表2所列。

表2 

Koutput Kconst Kstore Kready
1 x 0 1
1 1 1 1
0 0 1 1
0 x 1 0
0 x 0 0

由图2获得了如下最简逻辑表达式,作为表达式(1)的扩展:

Kstore中是上一次的Kready,所以

Kstroe=Kready    (4)

根据表2绘出的卡诺图如图2所示。

表达式(3)是1个包含了表达式(1)的通用逻辑表达式。它用于既有重复键输出也有非重复键输出的系统中。对于只有重复键输出的系统,Kconst全为1,则Koutput=Kready,所以只用表达式(1)就可以了。如果系统只要求非重复键输出,则Kconst全为0,表达式(3)简化为:

在实际应用中,1个比特表示1个键。C51中的字符变量可以处理8个键,如果系统需要更多的键,可选用整型变量、长整型变量或数组。如果系统的按键数量过多,则会占用较多单片机宝贵的内部寄存器,这是该方法的不足之处。

  三.应用程序实例

为了进一步理解上述方法如何在编程中得以实现,在此提供了1个用C51单片机编程语言编制的8个按键的键处理程序,以供参考。该程序在KEIL C51 V6.02/uVsion2 demo编译环境下编译通过。

#i nclude<intrins.h>

#i nclude<at89x51.h>

unsigned char key_value;

unsigned char Kinput;

unsigned char Ktemp;

unsigned char Kstore;

unsigned char Kready;

unsigned char Koutput;

unsigned char bdata flag;

code unsigned char Kconst=0xaa; /*重复键和非重复键格式*/

sbit endebounce=flag^0;

sbit getkey=iag^1;

sbit kprocess=flag^2;

sbit ACC_7=ACC^7;

void main(void);

void debounce(void);

void get_key_value(void);

void main(void)

{

/*初始化*/

kinput=Ktemp=kready=Kstore=0;

endebounce=0;

getkey=0;

kprocess=0;

TMOD=0x01;

TL0=0xe0;

TH0=0xb1;

TR0=1;

ET0=1;

EA=1;

/*……*/

while(1)/*循环*/

{

debounce();/*调用去除键抖动函数*/

get_key_value();/*调用获取键值函数*/

key_processing();/*调用键处理函数*/

/*other functions*/

}

}

void debounce(void)

{

if (endebounce)

{

/*以下是去除键抖动表达式*/

Kreqdy=Ktemp & Kinput |Kready & (Ktemp^Kinput);

Ktemp=Kinput;

/*以下表示式用于输出重复键和非重复键*/

Koutput=Kready &(~Kstore | Kconst);

Kstore=Kready;

if (Koutput ! =0)/*如果有键按下,置标志准备获取键值*/

getkey=1;

}

}

void get_key_value(void)

{

if(getkey)

{

unsigned char temp;

unsigned char j;

getkey=0;/*清标志*/

for(j=0;j<8;j++)

{

temp=_cror_(koutput,1);/*循环右移寻找按下的键*/

if(_testbit_(ACC_7))/*如果ACC_7=1,找到了按下的键*/

{

key_value=j;/*获得键值*/

j=8;/*找到按下的键就退出循环*/

kprocess=1;/*置标志,准备进行键处理*/

}

else Koutput=temp;/*准备下一次寻找*/

}

}

}

void timer0_interrupt_handler(void) interrupt using1

{

TL0=0xe0;/*加载定时器参数,使晶振频率12MHz时中断周期为20ms*/

TH0=0xb1;

/*键扫描*/

P2_0;/*使能键扫描位*/

Kinput=~P0;/*从P0读入按键信息,反相后保存*/

endebounce;/*置标志位准备去抖动*/

/*其它与定时器有关的语句*/

看《匠人手记》,与匠人同行!北航出版,正在热卖!

回复:一种软件去除键抖动的方法
初学者(游客)发表评论于2006-7-26 15:18:00  个人主页 | 引用 | 返回 | 删除 | 回复

初学者(游客)

/*4个键的扫描程序*/

P0.0  第一个键P0.1  第二个键P0.2  第三个键P0.3第四个键

单击和加速请大家帮我看一下

 

#define KEY_PIN P2

INT8U KeyScan (void)
{  
    INT8U keyval ;
    INT8U keyswitch ;
    keyswitch  = 0xFF;
    keyval     = 0xFF ;
                 
 if ((KEY_PIN & 0x0F) != 0x0F) {
     Dly(2) ;
     if ((KEY_PIN & 0x0F) != 0x0F) {
         Dly(20) ;
      if ((KEY_PIN & 0x0F) != 0x0F) {
       keyval = KEY_PIN & 0x0F ;   
                switch (keyswitch) {
                    case 7:
                        keyval = 3 ;    //键码
                    break ;
                    case 11:
                        keyval = 2 ;
                    break ;
                    case 13:
                        keyval = 1 ;
                    break ;
                    case 14:
                        keyval = 0 ;
                    break
                    default :
                        keyval = 0xFF;
                    break ;
                }

 
                if ((KEY_PIN & 0x0F) != 0x0F) { 
                    Dly(100) ;
                    if ((KEY_PIN & 0x0F) == keyswitch) {
                        switch (keyswitch) { //加速键码
                            case 7:
                                keyval = 7;  
                            break ;
                            case 11:
                                keyval = 6;
                            break ;
                            case 13:
                                keyval = 5 ;
                            break ;
                            case 14:
                                keyval = 4 ;
                            break
                            default :
                                keyval = 0xFF;
                            break ;
                        }
                       
                    }
             }              
      }
           
  }


       
    return keyval ;                              // 确认1键长时间按下返回4键值          
    }


}

看《匠人手记》,与匠人同行!北航出版,正在热卖!

回复:一种软件去除键抖动的方法
USB开发(游客)发表评论于2006-6-24 18:43:00  个人主页 | 引用 | 返回 | 删除 | 回复

USB开发(游客)

http://www.dataie.com

USB快速开发模块

看《匠人手记》,与匠人同行!北航出版,正在热卖!

发表评论:
载入中...

芯片专题

器件专题

软件专题

硬件专题

综合专题

项目专题

原创专题

器件检测
LCD LED
按键 触摸键
E2PROM
电池 电机
电阻 电容 电感

指令系统
软件算法
编程规范
滤波算法
串行通讯

PCB设计
I2C PWM
红外遥控
充电技术
中断 ADC 

匠人手记
匠人夜话
网络心路
一周热点串烧
从零开始玩PIC
DIY旋转时钟

广告5号位 [投放]


学习板、开发板、编程器、下载器、仿真器(查看详情……)

广告3号位 [投放]

站内搜索


站外搜索


百度  google
mp3  歌词 
图片  FLASH 
知道  文档
新闻  词典 
地图  mp3 
软件  天网 
雅虎  爱问 
搜狗  讯雷 
网讯  华军 
天空 

21IC器件搜索
百宝箱分站
  • 《匠人的百宝箱》21IC站
  • 《匠人的百宝箱》21IC笔记团队
  • 《匠人手记》21IC书友会
  • 《匠人的百宝箱》MCUBLOG站
  • 《匠人的百宝箱》MCUBLOG笔记团队
  • 《匠人的百宝箱》EDN站
  • 《匠人手记》EDN书友会
  • 《匠人的百宝箱》与非网站
  • 《匠人的百宝箱》新浪站
  • 《匠人的百宝箱》百度站
  • 《匠人的百宝箱》网易126站
  • 《匠人的百宝箱》网易163站
  • 《匠人的百宝箱》互动出版网站
  • 广告4号位 [投放]

     
     

    匠人原创

    往日酷贴

     
     
     

    大千八卦

    友情连接

    新浪新闻:
    新浪财经:
    AK58新闻:
    新浪股票:
    新浪股票:
    证券之星:

     [更多酷站连接]

     

     

    [欢迎交换连接]

    [百宝箱之与非门分舵]

    [电脑圈圈的家当]

    [IC921的博客]

    [柔月阁]

    [八楼的呼吸]

    [hotpower 的水潭]

    [xwj的文君阁]

    [所长的BLOG]

    [阿摆手记]

    [电子伙伴]

    [unaided的笔记]

    [小飞的笔记]

    [单片机开发联盟]

    [网址之家]

    [好东西网址大全]

    [美萍中文精选]

    [数字电视之家]

    [SMARTCODE电子书斋]

    [软件开发之窗]

    [Armoric]

    [我爱研发网]

    [infernal的笔记]

    [雄鹰的空中加油站]

    [SunK]

    [逍遥电子]

    [ningpanda的博客]

    [C-Design]

    [一网见天下]

    [海边淘沙]

    [嵌入式365]

    [水牛的仓库]

    [股剩是怎样炼成的]

    [PIC论坛]

    [ICC AVR开发网]

    [中国高校自动化网]

     

     

     

    MCU博客-中国电子工程师博客网 

    大学生电子网 

     

     

     

     

     

    !!! 《匠人的百宝箱》 !!!