单片机交流
直播中

申换换

7年用户 1526经验值
私信 关注
[问答]

单片机如何消除按键抖动?

单片机如何消除按键抖动?

回帖(1)

王华梅

2021-10-21 16:03:11
我们前面在电子中的学习中就接触过按键,但是我们只清楚其电路图代表的含义,却不明白真正操作起来会遇到的一系列问题,由于机械触点的弹性,一个按键开关在闭合后不会马上稳定接通,断开时也不会马上断开,如果不处理的话,会导致按键识别为多下,故我们就来研究一下按键消抖(针对的是K1 K2 K3)
  实验原理




这个电路图我们在前面已经接触过,但我们现在主要来消除K1-K3的按键问题
当按键被按下的时候,电路导通接地,I/O口为低电平;
当按键未被按下时,电路断开,I/O口保持高电平。
但一般的按键所用开关为机械弹性开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开。因而在闭合及断开的瞬间均伴随有一连串的抖动,假如不加以处理,会导致按键被识别为按下多次。为了不产生这种现象而作的措施就是按键消抖。
消抖方法




  • 硬件消抖
    RS触发器




    这是一个双稳态电路,学过数字逻辑的小伙伴应该会明白
  • 软件消抖

法一:使用延时
检测出键闭合后执行一个延时程序,5ms~10ms的延时,让前沿抖动消失后再一次检测键的状态,如果仍保持闭合状态电平,则确认为真正有键按下。
当检测到按键释放后,也要给5ms~10ms的延时,待后沿抖动消失后才能转入该键的处理程序
法二:检测多次
可以设定一个检测周期,如果在一个检测周期内,按键被检测为被按下达到了一定次数,则确认为真正被按下

代码解析
由于按下K1加1,按下K2减1
初始化number为5000,显示在数码管上


全局变量
uint number;//显示在数码管上
uint flag;//位选的位置
int count1,count2,count3,count4;//用于消抖计数
bit status_P,status_P2;//记录按键前一状态


设置中断内容
void InterruptTimer0()interrupt 1
{
        switch(flag)
        {
                case 0:P0=0;P2=weixuan[flag];P0=duanxuan[number/1000];break;
                case 1:P0=0;P2=weixuan[flag];P0=duanxuan[(number/100)%10];break;
                case 2:P0=0;P2=weixuan[flag];P0=duanxuan[(number%100)/10];break;
                case 3:P0=0;P2=weixuan[flag];P0=duanxuan[(number%100)%10];break;
        }
        flag++;
       
        count1++;
        if(key1==0)
        {
                count2++;          //记录K1的按下状态
        }                        
               
        count3++;
        if(key2==0)
        {
                count4++;         //记录K2的按下状态
        }
}


主函数部分
void main()
{
        Init();
        while(1)
        {
                if(flag==4)//修正位选位置
                        flag=0;
               
                if(count1==30)//消抖大概6ms,总共统计次数30次
                {
                        if(count2>=20)// 如果低电平有效次数为2/3以上
                        {
                                if(status_P==1)
                                {
                                        status_P=0;
                                        number++;
                                }
                        }
                        else
                                status_P=1;
                        count1=0;
                        count2=0;
                }
               
                //同理 K2的按键消抖
                if(count3==30)//消抖大概6ms,总共统计次数30次
                {
                        if(count4>=20)// 如果低电平有效次数为2/3以上
                        {
                                if(status_P2==1)
                                {
                                        status_P2=0;
                                        number--;
                                }
                        }
                        else
                                status_P2=1;
                        count3=0;
                        count4=0;
                }
        }
}


代码比较的简单,其实也算是在一定时间内检测多次,即利用了软件消抖
举报

更多回帖

发帖
×
20
完善资料,
赚取积分