0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

单片机按键去抖动的方法

CHANBAEK 来源:科创追梦者 作者:谢士金 2023-11-02 15:16 次阅读

在使用按键时,我们想按一次按键,但在实际中却经常发现我们要的”一次“,实际上去并不是”一次“而可能是多次。为什么呢?这是因为,我们使用的机械按键,在我们按下时,并非只是接触一次,因为存在机械抖动,导致接触多次。因此,按键检测去抖动就很有必要了。下面,我就向大家介绍按键去抖动的方法。

一、STC15W408AS按键电路

图片

二、按键按下和松开时的波形

下面的图形中显示的是按键按下和松开时的理想状态和实际状态。

图片

三、按键去抖动方法

理想波形:没有按下为高电平,按下之后为低电平,松开之后又为高电平。

实际波形:按下之后,存在机械抖动,需要过一段时间才会稳定成低电平,然后,松开时又会产生机械抖动。机械式按键在按下或者释放时,由于机械弹性的影响,通常会伴随有一定的时间触电机械抖动,然后其触电才稳定下来。在触点抖动期间检测按键的通与断,可能会导致错误,也就是有可能被认为进行了多次操作,这种情况是不允许出现的。

因此,在单片机检测键盘是否按下都要加上去抖动操作,按键少时,可采用硬件消抖,按键较多时,采用软件消抖。

我们在编写单片机的按键检测程序时,一般在检测按下时加入去抖动延时(10~20ms即可),也就是当检测到按键输入口是低电平时,延时20MS再检测一次按键的状态是不是还是低电平。如果还是低电平,则认为按键被真正按下一次。

四、按键检测去抖动关键代码

if(!GetKey_High()) //如果检测到按键低电平

{

        Delay20ms(); //延时20MS

        if(!GetKey_High()) //如果还是检测到按键低电平

        {

            bKeyDown=TRUE; //确认按键已按下

            mNum++; //按键次数加1

        }

        while(!GetKey_High()); //等待按键松开

}



* //1MS定时中断函数Timer0_ISR()

void Timer0_ISR (void) interrupt 1

{

        if(mDelay >0)//如果mDelay >0

        {

             mDelay--; //则中断到来时,mDelay减1

        }

}



* //20MS延时函数Delay20ms()

void Delay20ms(void)

{

        mDelay=20;            //设置mDelay的值为20

        while(mDelay >0);    //等待mDelay在中断中减到0

}



* //500MS延时函数Delay500ms()

void Delay500ms(void)

{

        mDelay=500;

        while(mDelay >0);

}

五、本例完整源程序

#define FOSC 11059200L

#define T1MS (65536-FOSC/1000)      // 1 T模式

#define BIT0 0x01

#define BIT1 0x02

#define BIT2 0x04

#define BIT3 0x08

#define BIT4 0x10

#define BIT5 0x20

#define BIT6 0x40

#define BIT7 0x80



#define TRUE 1

#define FALSE 0



#define Pin_LED P32

#define Pin_LED_M1 P3M1

#define Pin_LED_M0 P3M0

#define Pin_LED_BIT BIT2

#define PinLed_High() Pin_LED=1

#define PinLed_Low() Pin_LED=0

#define Pin_KEY P12

#define Pin_KEY_M1 P1M1

#define Pin_KEY_M0 P1M0

#define Pin_KEY_BIT BIT2

#define GetKey_High() Pin_KEY==1

#define BOOL unsigned char

#define UINT unsigned int



void PinLED_DirOut(void);

void PinKEY_DirIn(void);

void Timer0_Init(void);

void Delay20ms(void);

void Delay500ms(void);

void LedFlash(UINT num);



BOOL bKeyDown=FALSE;

UINT mDelay=0;

UINT mNum=0;



void main(void)

{

        PinKEY_DirIn();

        PinLED_DirOut();

        PinLed_High();

        Timer0_Init();

        while(TRUE)

        {

            if(!GetKey_High())

            {

                Delay20ms();

                if(!GetKey_High())

                {

                      mNum++;

                      bKeyDown=TRUE;

                 }



               while(!GetKey_High());

           }



          if(bKeyDown)

          {

              bKeyDown=FALSE;

              LedFlash(mNum);         

          }

     }    

}



void PinKEY_DirIn(void)

{

        Pin_KEY_M1 &=~Pin_KEY_BIT;

        Pin_KEY_M0 &=~Pin_KEY_BIT;   

}



void PinLED_DirOut(void)

{

        Pin_LED_M1 &=~Pin_LED_BIT;

        Pin_LED_M0 |=Pin_LED_BIT; 

}



void Timer0_Init(void)

{

        AUXR |= 0x80;         //定时器0为1T模式

        TMOD = 0x00;          //设置定时器为模式0(16位自动重装载)

        TL0 = T1MS;           //初始化计时值

        TH0 = T1MS > > 8;

        TR0 = 1;              //定时器0开始计时

        ET0 = 1;              //使能定时器0中断

        EA = 1;

}



// 1ms

void Timer0_ISR (void) interrupt 1

{

        if(mDelay >0)

        {

              mDelay--;

        }    

}



void Delay20ms(void)

{

        mDelay=20;

        while(mDelay >0);

}



void Delay500ms(void)

{

        mDelay=500;

        while(mDelay >0);

}



//为了方便检验效果,我写了下面这个LED闪动函数,第1次按下,LED闪动1次,第2次按下,LED闪动2次,依次类推。

void LedFlash(UINT num)

{

        UINT i;

        for(i=0;i< num;i++)

        {

               PinLed_Low();

               Delay500ms();

               PinLed_High();

               Delay500ms();

        }

}
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 单片机
    +关注

    关注

    6001

    文章

    43978

    浏览量

    620871
  • 去抖动
    +关注

    关注

    0

    文章

    2

    浏览量

    6321
  • 按键电路
    +关注

    关注

    1

    文章

    35

    浏览量

    21608
  • 按键检测
    +关注

    关注

    0

    文章

    21

    浏览量

    4797
收藏 人收藏

    评论

    相关推荐

    单片机按键的问题(转)

    在网上看到这篇心得,感觉还是很实用的小问题,转来希望大家共同学习,在网上看了《单片机按键一次处理的优化方法》这篇文章,很有点启发,不过我疑惑的是第二个程序中的消除抖动语句怎么没了,再查
    发表于 08-11 11:03

    单片机如何区别按键长按和短按?

      单片机工程师在面试的过程中,经常会碰到一些相同的问题,笔者总结了十个提问率较高的问题,供大家参考。现在我们来分析单片机工程师常遇面试问题之二:单片机如何区别按键长按和短按?    
    发表于 01-14 16:59

    如何使用基于51单片机的新型按键扫描程序

    如何使用基于51单片机的新型按键扫描程序?基于51单片机的新型按键扫描程序有哪些应用?
    发表于 10-19 09:14

    单片机如何消除按键抖动

    单片机如何消除按键抖动
    发表于 10-21 09:29

    单片机按键检测程序分享

    单片机按键检测程序(定时器法消抖)相信大家在初学51单片机的时候按键检测为了消抖都会加一些空循环做软件延时。这样做可是浪费了CPU的不少资源。对于51这种低端
    发表于 12-03 07:23

    如何消除按键抖动的影响

    按键抖动:在机械按键的触点闭合和断开时,都会产生抖动,为了保证系统能正确识别按键的开关,就必须对按键
    发表于 01-17 07:46

    STM32单片机按键消抖和FPGA按键消抖的相关资料分享

    写在前面:STM32单片机按键消抖和FPGA按键消抖大全按键抖:由上图可以看出理想波形与实际波形之间是有区别的,实际波形在按下和释放的瞬间
    发表于 01-18 06:39

    怎样编写单片机的独立按键与矩阵按键的扫描函数呢

    单片机的独立按键是什么?单片机的矩阵按键是什么?怎样编写单片机的独立
    发表于 02-23 06:24

    单片机按键抖原理是什么?

    单片机按键抖原理
    发表于 11-06 06:57

    单片机按键产生的抖动是方波还是尖刺?

    单片机 按键产生的抖动是方波还是尖刺
    发表于 11-08 07:03

    单片机按键防抖子程序详情解说

    要解决单片机按键抖动问题,首先要了解被键的类型,按键有触点式和非触点式两种,单片机中应用的- 一般是由机械触点构成的。在下图中,当开关未被按
    发表于 11-15 15:16 1w次阅读
    <b class='flag-5'>单片机</b><b class='flag-5'>按键</b>防抖子程序详情解说

    STM单片机中的按键消抖和FPGA消抖

    闭合的时间超过了 20ms。因此单片机在检测键盘是否按下时都要加上去抖动操作,有专用的去抖动电路,也有专门的去抖动芯片,但通常我们采用软件延时的方法
    的头像 发表于 11-30 17:39 1968次阅读

    单片机按键检测程序(定时器法消抖)

    单片机按键检测程序(定时器法消抖)相信大家在初学51单片机的时候按键检测为了消抖都会加一些空循环做软件延时。这样做可是浪费了CPU的不少资源。对于51这种低端
    发表于 11-23 17:51 5次下载
    <b class='flag-5'>单片机</b><b class='flag-5'>按键</b>检测程序(定时器法消抖)

    单片机零基础入门(7):按键消抖--独立按键按下点亮LED灯,松开LED灯灭--解决独立按键抖动的问题

    单片机零基础入门(7):解决独立按键抖动的问题一、按键抖动的原因二、解决按键
    发表于 01-17 11:05 6次下载
    <b class='flag-5'>单片机</b>零基础入门(7):<b class='flag-5'>按键</b>消抖--独立<b class='flag-5'>按键</b>按下点亮LED灯,松开LED灯灭--解决独立<b class='flag-5'>按键</b><b class='flag-5'>抖动</b>的问题

    STM32F407 按键抖动 延时消抖

    按键抖动:在机械按键的触点闭合和断开时,都会产生抖动,为了保证系统能正确识别按键的开关,就必须对按键
    发表于 01-18 10:30 4次下载
    STM32F407 <b class='flag-5'>按键</b><b class='flag-5'>抖动</b> 延时消抖