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

[复制链接]
1807|31
 楼主| 杨寅辉 发表于 2020-2-23 14:15 | 显示全部楼层 |阅读模式
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.

 楼主| 杨寅辉 发表于 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.

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| 杨寅辉 发表于 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.

  1. /* SoftwareDebounce
  2. *
  3. * At each transition from LOW to HIGH or from HIGH to LOW
  4. * the input signal is debounced by sampling across
  5. * multiple reads over several milli seconds.  The input
  6. * is not considered HIGH or LOW until the input signal
  7. * has been sampled for at least "debounce_count" (10)
  8. * milliseconds in the new state.
  9. *
  10. * Notes:
  11. *   Adjust debounce_count to reflect the timescale
  12. *     over which the input signal may bounce before
  13. *     becoming steady state
  14. *
  15. * Based on:
  16. *   http://www.arduino.cc/en/Tutorial/Debounce
  17. *
  18. * Jon Schlueter
  19. * 30 December 2008
  20. *
  21. * http://playground.arduino.cc/Learning/SoftwareDebounce
  22. */

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

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

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

  32. void setup()
  33. {
  34.   pinMode(inPin, INPUT);
  35.   pinMode(outPin, OUTPUT);
  36.   digitalWrite(outPin, current_state); // setup the Output LED for initial state
  37. }


  38. void loop()
  39. {
  40.   // If we have gone on to the next millisecond
  41.   if(millis() != time)
  42.   {
  43.     reading = digitalRead(inPin);

  44.     if(reading == current_state && counter > 0)
  45.     {
  46.       counter--;
  47.     }
  48.     if(reading != current_state)
  49.     {
  50.        counter++;
  51.     }
  52.     // If the Input has shown the same value for long enough let's switch it
  53.     if(counter >= debounce_count)
  54.     {
  55.       counter = 0;
  56.       current_state = reading;
  57.       digitalWrite(outPin, current_state);
  58.     }
  59.     time = millis();
  60.   }
  61. }


The above code is written in Arduino IDE.
 楼主| 杨寅辉 发表于 2020-2-23 14:36 | 显示全部楼层
The following program toggles two LEDs connected to a PIC microcontroller. The code can be something like this:
  1. // INCLUDES
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <xc.h>

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

  14. // DEFINITIONS
  15. #define _XTAL_FREQ 4000000
  16. #define LED1 PORTBbits.RB3
  17. #define LED2 PORTBbits.RB2
  18. #define BTN PORTBbits.RB5

  19. // VARIABLES
  20. char BTN_pressed = 0;
  21. char BTN_press = 0;
  22. char BTN_release = 0;
  23. char Bouncevalue = 500;

  24. // MAIN PROGRAM
  25. int main(int argc, char** argv) {
  26.     // Comparators off
  27.     CMCON = 0x07;
  28.    
  29.     // Port directions, RB5 input, the rest is output
  30.     TRISA = 0b00000000;
  31.     TRISB = 0b00100000;
  32.    
  33.     // Port state, all low
  34.     PORTA = 0b00000000;
  35.     PORTB = 0b00000000;
  36.    
  37.     // Starting with LED1 high and LED2 low
  38.     LED1 = 1;
  39.     LED2 = 0;
  40.    
  41.     while (1)
  42.     {
  43.         // If BTN is pressed
  44.         if (BTN == 1)
  45.         {
  46.             // Bouncing has started so increment BTN_press with 1, for each "high" bounce
  47.             BTN_press++;
  48.             // "reset" BTN_release
  49.             BTN_release = 0;
  50.             // If it bounces so much that BTN_press is greater than Bouncevalue
  51.             // then button must be pressed
  52.             if (BTN_press > Bouncevalue)
  53.             {
  54.                 // This is initial value of BTN_pressed.
  55.                 // If program gets here, button must be pressed
  56.                 if (BTN_pressed == 0)
  57.                 {
  58.                     // Toggle the LEDs
  59.                     LED1 ^= 1;
  60.                     LED2 ^= 1;
  61.                     // Setting BTN_pressed to 1, ensuring that we will
  62.                     // not enter this code block again
  63.                     BTN_pressed = 1;
  64.                 }
  65.                 // LEDs toggled, set BTN_pressed to 0, so we can enter
  66.                 // toggle code block again
  67.                 BTN_press = 0;
  68.             }
  69.         }
  70.         else
  71.         {
  72.             // Increment the "low" in the bouncing
  73.             BTN_release++;
  74.             BTN_press = 0;
  75.             // If BTN_release is greater than Bouncevalue, we do not have a
  76.             // pressed button
  77.             if (BTN_release > Bouncevalue)
  78.             {
  79.                 BTN_pressed = 0;
  80.                 BTN_release = 0;
  81.             }
  82.         }
  83.         
  84.     }
  85.     return (EXIT_SUCCESS);
  86. }
kkzz 发表于 2020-3-3 20:32 | 显示全部楼层
纯英文的看不懂啊。     
hudi008 发表于 2020-3-3 20:32 | 显示全部楼层
在一些对按键抖动敏感的情况下需要进行消抖设计
lzmm 发表于 2020-3-3 20:32 | 显示全部楼层
进行滤波处理。  
minzisc 发表于 2020-3-3 20:33 | 显示全部楼层
解决问题的关键就是如何降低按键程序所运行的时间
fentianyou 发表于 2020-3-3 20:33 | 显示全部楼层
楼主翻译翻译吧   
xiaoyaodz 发表于 2020-3-3 20:33 | 显示全部楼层
必须消除由于抖动造成的影响
febgxu 发表于 2020-3-3 20:34 | 显示全部楼层
这个软件是什么      
sdlls 发表于 2020-3-3 20:34 | 显示全部楼层
谢谢楼主分享的英文资料。      
pixhw 发表于 2020-3-3 20:35 | 显示全部楼层
            
minzisc 发表于 2020-3-3 20:35 | 显示全部楼层
按键开关和机械按键都这样的  
lzmm 发表于 2020-3-3 20:35 | 显示全部楼层
楼主使用的仿真吗?   
selongli 发表于 2020-3-3 20:35 | 显示全部楼层
没有看懂呢。         
fentianyou 发表于 2020-3-3 20:35 | 显示全部楼层
高深的理论了。        
您需要登录后才可以回帖 登录 | 注册

本版积分规则

39

主题

295

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部