打印
[Logic]

开关抖动及其处理办法(英文文档)

[复制链接]
1331|31
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Theory
What is switch bounce? When you push a button, press a mico switch or flip a toggleswitch, two metal parts come together. For the user, it might seem that the contact is made instantly. That is not quite correct. Inside the switch there are moving parts. When you push the switch, it initially makes contact with the other metal part, but just in a brief split of a microsecond. Then it makes contact a little longer, and then again a little longer. In the end the switch is fully closed. The switch is bouncing between in-contact, and not in-contact. "When the switch is closed, the two contacts actually separate and reconnect, typically 10 to 100 times over a periode of about 1ms." ("The Art of electronics", Horowitz & Hill, Second edition, pg 506.) Usually, the hardware works faster than the bouncing, which results in that the hardware thinks you are pressing the switch several times. The hardware is often an integrated circuit. The following screenshots illustrates a typical switch bounce, without any sort of bounce control:

Each switch has its own characteristics regarding the bounce. If you compare two of the same switches, there is a great chance that they will bounce differently.

I will show you how 4 different switches bounce. I have 2 micro switches, 1 push button, and 1 toggle switch:

使用特权

评论回复

相关帖子

沙发
杨寅辉|  楼主 | 2020-2-23 14:26 | 只看该作者
Hardware setup
All the switches will be connected the same way (this is essential if we are going to compare the results). First we will see how the switches behave in their raw form. The basic of our circuit will be the HCF4017BE. This is a decade counter/divider made by STMicroelectronics. They do not produce this IC anymore, so this actual type is obsolete. However, there are many other manufacturers that still make this little IC, and they are often pin compatible. You can find a datasheet for the 4017-types IC here.
The IC receives a clock signal on PIN 14 and then lights the LED on Q1. When the next clock signal is received, the IC turns off Q1 and lights Q2, and so on. When the counting reaches Q8 (PIN 9), it clocks PIN 15, which is the reset pin. That makes the whole counting start at Q0.
Our basic circuit:
Further details of the circuit will not be explained.

First we will try with no bounce control at all. This is the clock circuit:
Clock pin held low - pulse high
Clock pin held high - pulse low

In the video we are using the circuit on the right. Clock pin held high - pulse low.
https://training.ti.com/debounce-switch


使用特权

评论回复
板凳
杨寅辉|  楼主 | 2020-2-23 14:27 | 只看该作者
Now, let us see some screenshots from the oscilloscope.
This is switch A:
This is switch B:
This is switch C:
This is switch D:
This is switch C, with the clock pin held high, and we pulse low:
Click on images for better resolution. The screenshots are from the clock circuit on the left, where the clock pin is held low.

使用特权

评论回复
地板
杨寅辉|  楼主 | 2020-2-23 14:28 | 只看该作者
As you can see, the small IC is sensing what seems to be a lot of pressing on the switch. This is not the case, since the switch was pressed only one time.
Let us add a ceramic capacitor, like this:
Clock pin held low - pulse high
Clock pin held high - pulse low

While adding the capacitor, we are maknig a R-C circuit. R-C circuits will not be discussed here.
The screenshots from the oscilloscope, are very different from the above screenshots. This shows that the R-C circuit is filtering out the bounces.

使用特权

评论回复
5
杨寅辉|  楼主 | 2020-2-23 14:33 | 只看该作者
Switch A:
Switch B:
Switch C:
Switch D:
This is switch C,, with the clock pin helt high, and pulse low:
Click on images for better resolution. The screenshots are from the clock circuit on the left. Clock pin held low - pulse high.
The screenshots tells us that the bouncing has stopped, and that the IC is only "seeing" one push or one flip. This is what we want.

使用特权

评论回复
6
杨寅辉|  楼主 | 2020-2-23 14:35 | 只看该作者
Software debounce
When working with microcontrollers, we can deal with switch bounce in a different way that will save both hardware space and money. Some programmers do not care much about bouncing switches and just add a 50ms delay after the first bounce. This will force the microcontroller to wait 50ms for the bouncing to stop, and then continue with the program. This is actually not a good practice, as it keeps the microcontroller occupied with waiting out the delay.

Another way is to use an interrupt for handling the switch bounce. Be aware that the interrupt might be fired on both the rising and falling edge, and some microcontrollers might stack up one waiting interrupt. There are different opinions on how to use it, but interrupt driven switch debouncing will not be discussed here.

The following is a simple software debounce code for Arduino.

/* SoftwareDebounce
*
* At each transition from LOW to HIGH or from HIGH to LOW
* the input signal is debounced by sampling across
* multiple reads over several milli seconds.  The input
* is not considered HIGH or LOW until the input signal
* has been sampled for at least "debounce_count" (10)
* milliseconds in the new state.
*
* Notes:
*   Adjust debounce_count to reflect the timescale
*     over which the input signal may bounce before
*     becoming steady state
*
* Based on:
*   http://www.arduino.cc/en/Tutorial/Debounce
*
* Jon Schlueter
* 30 December 2008
*
* http://playground.arduino.cc/Learning/SoftwareDebounce
*/

int inPin = 7;         // the number of the input pin
int outPin = 13;       // the number of the output pin

int counter = 0;       // how many times we have seen new value
int reading;           // the current value read from the input pin
int current_state = LOW;    // the debounced input value

// the following variable is a long because the time, measured in milliseconds,
// will quickly become a bigger number than can be stored in an int.
long time = 0;         // the last time the output pin was sampled
int debounce_count = 10; // number of millis/samples to consider before declaring a debounced input

void setup()
{
  pinMode(inPin, INPUT);
  pinMode(outPin, OUTPUT);
  digitalWrite(outPin, current_state); // setup the Output LED for initial state
}


void loop()
{
  // If we have gone on to the next millisecond
  if(millis() != time)
  {
    reading = digitalRead(inPin);

    if(reading == current_state && counter > 0)
    {
      counter--;
    }
    if(reading != current_state)
    {
       counter++;
    }
    // If the Input has shown the same value for long enough let's switch it
    if(counter >= debounce_count)
    {
      counter = 0;
      current_state = reading;
      digitalWrite(outPin, current_state);
    }
    time = millis();
  }
}


The above code is written in Arduino IDE.

使用特权

评论回复
7
杨寅辉|  楼主 | 2020-2-23 14:36 | 只看该作者
The following program toggles two LEDs connected to a PIC microcontroller. The code can be something like this:
// INCLUDES
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>

// CONFIG
#pragma config FOSC = INTOSCIO  // Oscillator Selection bits (INTOSC oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON       // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is MCLR)
#pragma config BOREN = ON       // Brown-out Detect Enable bit (BOD enabled)
#pragma config LVP = ON         // Low-Voltage Programming Enable bit (RB4/PGM pin has PGM function, low-voltage programming enabled)
#pragma config CPD = OFF        // Data EE Memory Code Protection bit (Data memory code protection off)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)

// DEFINITIONS
#define _XTAL_FREQ 4000000
#define LED1 PORTBbits.RB3
#define LED2 PORTBbits.RB2
#define BTN PORTBbits.RB5

// VARIABLES
char BTN_pressed = 0;
char BTN_press = 0;
char BTN_release = 0;
char Bouncevalue = 500;

// MAIN PROGRAM
int main(int argc, char** argv) {
    // Comparators off
    CMCON = 0x07;
   
    // Port directions, RB5 input, the rest is output
    TRISA = 0b00000000;
    TRISB = 0b00100000;
   
    // Port state, all low
    PORTA = 0b00000000;
    PORTB = 0b00000000;
   
    // Starting with LED1 high and LED2 low
    LED1 = 1;
    LED2 = 0;
   
    while (1)
    {
        // If BTN is pressed
        if (BTN == 1)
        {
            // Bouncing has started so increment BTN_press with 1, for each "high" bounce
            BTN_press++;
            // "reset" BTN_release
            BTN_release = 0;
            // If it bounces so much that BTN_press is greater than Bouncevalue
            // then button must be pressed
            if (BTN_press > Bouncevalue)
            {
                // This is initial value of BTN_pressed.
                // If program gets here, button must be pressed
                if (BTN_pressed == 0)
                {
                    // Toggle the LEDs
                    LED1 ^= 1;
                    LED2 ^= 1;
                    // Setting BTN_pressed to 1, ensuring that we will
                    // not enter this code block again
                    BTN_pressed = 1;
                }
                // LEDs toggled, set BTN_pressed to 0, so we can enter
                // toggle code block again
                BTN_press = 0;
            }
        }
        else
        {
            // Increment the "low" in the bouncing
            BTN_release++;
            BTN_press = 0;
            // If BTN_release is greater than Bouncevalue, we do not have a
            // pressed button
            if (BTN_release > Bouncevalue)
            {
                BTN_pressed = 0;
                BTN_release = 0;
            }
        }
        
    }
    return (EXIT_SUCCESS);
}

使用特权

评论回复
8
kkzz| | 2020-3-3 20:32 | 只看该作者
纯英文的看不懂啊。     

使用特权

评论回复
9
hudi008| | 2020-3-3 20:32 | 只看该作者
在一些对按键抖动敏感的情况下需要进行消抖设计

使用特权

评论回复
10
lzmm| | 2020-3-3 20:32 | 只看该作者
进行滤波处理。  

使用特权

评论回复
11
minzisc| | 2020-3-3 20:33 | 只看该作者
解决问题的关键就是如何降低按键程序所运行的时间

使用特权

评论回复
12
fentianyou| | 2020-3-3 20:33 | 只看该作者
楼主翻译翻译吧   

使用特权

评论回复
13
xiaoyaodz| | 2020-3-3 20:33 | 只看该作者
必须消除由于抖动造成的影响

使用特权

评论回复
14
febgxu| | 2020-3-3 20:34 | 只看该作者
这个软件是什么      

使用特权

评论回复
15
sdlls| | 2020-3-3 20:34 | 只看该作者
谢谢楼主分享的英文资料。      

使用特权

评论回复
16
pixhw| | 2020-3-3 20:35 | 只看该作者
            

使用特权

评论回复
17
minzisc| | 2020-3-3 20:35 | 只看该作者
按键开关和机械按键都这样的  

使用特权

评论回复
18
lzmm| | 2020-3-3 20:35 | 只看该作者
楼主使用的仿真吗?   

使用特权

评论回复
19
selongli| | 2020-3-3 20:35 | 只看该作者
没有看懂呢。         

使用特权

评论回复
20
fentianyou| | 2020-3-3 20:35 | 只看该作者
高深的理论了。        

使用特权

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

本版积分规则

39

主题

295

帖子

2

粉丝