Simple Debounce Routine

2020-02-20 05:16发布

Do you have a simple debounce routine handy to deal with a single switch input?

This is a simple bare metal system without any OS.

I would like to avoid a looping construct with a specific count, as the processor speed might fluctuate.

标签: embedded
11条回答
可以哭但决不认输i
2楼-- · 2020-02-20 05:36

To debounce, you want to ignore any switch up that lasts under a certain threshold. You can set a hardware timer on switch up, or use a flag set via periodic interrupt.

查看更多
手持菜刀,她持情操
3楼-- · 2020-02-20 05:40

use integration and you'll be a happy camper. Works well for all switches.

just increment a counter when read as high and decrement it when read as low and when the integrator reaches a limit (upper or lower) call the state (high or low).

查看更多
4楼-- · 2020-02-20 05:41

The algorithm from ganssle.com could have a bug in it. I have the impression the following line

static uint8_t Count = RELEASE_MSEC / CHECK_MSEC;

should read

static uint8_t Count = PRESS_MSEC / CHECK_MSEC;

in order to debounce correctly the initial press.

查看更多
▲ chillily
5楼-- · 2020-02-20 05:42

What I usually do is have three or so variables the width of the input register. Every poll, usually from an interrupt, shift the values up one to make way for the new sample. Then I have a debounced variable formed by setting the logical-and of the samples, and clearing the inverse logical-or. i.e. (untested, from memory)

input3 = input2;
input2 = input1;
input1 = (*PORTA);

debounced |= input1 & input2 & input3;
debounced &= (input1 | input2 | input3);

Here's an example:

debounced has xxxx (where 'x' is "whatever")

input1 = 0110,
input2 = 1100,
input3 = 0100

With the information above,

We need to switch only bit 2 to 1, and bit 0 to 0. The rest are still "bouncing".

debounced |= (0100); //set only bit 2
debounced &= (1110); //clear only bit 0

The result is that now debounced = x1x0

查看更多
神经病院院长
6楼-- · 2020-02-20 05:45

At the hardware level the basic debouncing routine has to take into account the following segments of a physical key's (or switch's) behavior:

Key sitting quietly->finger touches key and begins pushing down->key reaches bottom of travel and finger holds it there->finger begins releasing key and spring pushes key back up->finger releases key and key vibrates a bit until it quiesces

All of these stages involve 2 pieces of metal scraping and rubbing and bumping against each other, jiggling the voltage up and down from 0 to maximum over periods of milliseconds, so there is electrical noise every step of the way:

(1) Noise while the key is not being touched, caused by environmental issues like humidity, vibration, temperature changes, etc. causing voltage changes in the key contacts

(2) Noise caused as the key is being pressed down

(3) Noise as the key is being held down

(4) Noise as the key is being released

(5) Noise as the key vibrates after being released

Here's the algorithm by which we basically guess that the key is being pressed by a person:

read the state of the key, which can be "might be pressed", "definitely is pressed", "definitely is not pressed", "might not be pressed" (we're never really sure)

loop while key "might be" pressed (if dealing with hardware, this is a voltage sample greater than some threshold value), until is is "definitely not" pressed (lower than the threshold voltage) (this is initialization, waiting for noise to quiesce, definition of "might be" and "definitely not" is dependent on specific application)

loop while key is "definitely not" pressed, until key "might be" pressed

when key "might be" pressed, begin looping and sampling the state of the key, and keep track of how long the key "might be" pressed - if the key goes back to "might not be" or "definitely is not" pressed state before a certain amount of time, restart the procedure - at a certain time (number of milliseconds) that you have chosen (usually through experimenting with different values) you decide that the sample value is no longer caused by noise, but is very likely caused by the key actually being held down by a human finger and you return the value "pressed"


while(keyvalue = maybepressed){
//loop - wait for transition to notpressed
sample keyvalue here;
maybe require it to be "notpressed" a number of times before you assume
it's really notpressed;
}
while(keyvalue = notpressed){
//loop - wait for transition to maybepressed
sample keyvalue
again, maybe require a "maybepressed" value a number of times before you 
transition
}
while(keyvalue=maybepressed){
  presstime+=1;
  if presstime>required_presstime return pressed_affirmative
  }
}
return pressed_negative
查看更多
走好不送
7楼-- · 2020-02-20 05:46

There's no single simple solution that works for all types of buttons. No matter what someone here tells you to use, you'll have to try it with your hardware, and see how well it works. And look at the signals on a scope, to make sure you really know what's going on. Rich B's link to the pdf looks like a good place to start.

查看更多
登录 后发表回答