SCM按键的说明:去抖

51单片机按键的分类:1.矩阵按键;2.独立按键.

Q:不管是矩阵按键还是独立按键,只要是弹性按键,我们都要消抖,为什么要消抖?
A:按键按下和弹起的瞬间的不确定性的电平变化。通常的按键所用开关为机械弹性开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开。因而在闭合及断开的瞬间均伴随有一连串的抖动,为了不产生这种干扰正常电平的判断的现象而作的措施就是按键消抖。总之,单片机的处理速度很快,如果不做处理,那么会导致程序多次执行按键后的操作,从而导致逻辑错误。例如,要实现按下灯亮,再次按下灯灭,如果不消抖,就可能导致一次按下,多次处理,灯的开关状态就有可能没有变化。
      抖动时间的长短由按键的机械特性决定,一般为5ms~10ms(消抖的定时时间由按键的机械特性决定,多调试)。这是一个很重要的时间参数,在很多场合都要用到。按键稳定闭合时间的长短则是由操作人员的按键动作决定的,一般为零点几秒至数秒。为确保CPU对键的一次闭合仅作一次处理,必须去除键抖动。在键闭合稳定时读取键的状态,并且必须判别到键释放稳定后再作处理。

 

去抖方法:

硬件去抖,芯片加一个RS触发器或电容器。

软件去抖如果按键较多,常用软件方法消抖。

软件去抖:1.延时函数按键消抖
       在检测到有键按下时,先执行10ms左右的延时程序,然后再重新检测按键是否按下,以确认该键按下不是因为抖动引起的。同理,在检测到该键释放时,也采用延时再判断的方法消除抖动的影响。

如:

if(S1==0){       //第一次检测到S1按下
   delay(1200);  //延时10ms左右去抖动
    if(S1==0){    //第二次检测到S1按下
    .......
   }
}

但是,如果只写去抖不加个判断按键释放的语句的话,往往有时候会出现按好几次按键才有反应或其他情况。所以我们最好每次写关于按键的代码的时候都要写“去抖-判断释放”。

if(S1==0){       //第一次检测到S1按下
   delay(1000);  //延时10ms左右去:前沿抖动
    if(S1==0){    //第二次检测到S1按下
         delay(1000);  //延时10ms左右去:后延抖动
        while(!S1);  //判断按键释放。当按键彻底释放的状态是S1=1,所以此句while就跳出。while(!S1); 相当于while(!0);即一直停留在执行空语句上面,直到释放。
          //需要的动作
        .......
      }
}

另外,判断释放去抖大可不必,因为你一旦被检测有按键按下了就确定有按下状态了,只要写个while(!S1);只要检测到按键有等于1就直接判断已经手指抬起了。这样就避免了CPU多执行10ms空函数。

if(S1==0){       //第一次检测到S1按下
   delay(1000);  //延时10ms左右去:前沿抖动
    if(S1==0){    //第二次检测到S1按下
        while(!S1);  //判断按键释放。当按键彻底释放的状态是S1=1,所以此句while就跳出。while(!S1); 相当于while(!0);即一直停留在执行空语句上面,直到释放。
          //需要的动作
        .......
     }
}

附:
如果前后延去抖按键释放检测都写好了的,还是发现有点不灵,这里推荐一个办法:利用定时器中断一直扫描
代码示例:

我感觉这个方法已经很稳了。


软件去抖:2.定时器按键消抖

很少用

 

注:是不是只要涉及按键都要去抖?
答案是任何时候都需要去抖。特别是涉及一个按键控制多种模式(即对按键按下需要记次数的那种),我们必须必须特别地做好充分的去抖;否则你会发现你按下,因为抖动,被认为按了“很多次”。
例如下面这个根据按键次数改变P13灯状态,我们不去抖这样运行你会发现很不正常。

#include<reg51.h>
sbit P13=P1^3;
sbit P20=P2^0;
unsigned int i,N;
void main(){
	P13=1;
	while(1)
	{
		if(P20==0)
		N++;

		if(N==1){
		P13=!P13;
		i=20000;while(i--);
		}
		if(N==2)
		P13=0;
		if(N==3)
		P13=1;
	}
}

又例下面这个没有涉及到按键次数的,我们完全不去抖,会发现功能能实现,但是很不灵:

#include<reg51.h>
sbit P13=P1^3;
sbit P20=P2^0;
unsigned int i,N;
void main(){
	P13=1;
	while(1)
	{
		if(P20==0)
		P13=!P13;
	}
}

 

更多详情点击此处跳转.

posted @ 2022-04-17 15:26  iZJ"Qq4577105  阅读(268)  评论(0编辑  收藏  举报