Open Call: send us your Debounce code

Diablo

New member
debounce-waveform.jpg


If you’ve ever designed an embedded system with at least one button you’ve had to deal with button debouncing. This is also know as contact bounce, a*phenomenon*where a button press can be registered as multiple button presses if not handled correctly. One way to take care of this is with a hardware filter built from a resistor-capacitor setup, or by using a couple of NAND gates. We find that [Jack Ganssle] put together the most comprehensive and approachable look at contact bounce which you should read through if you want to learn more.

We’re interested in software solutions for debouncing buttons. This seems to be one of the most common forum questions but it can be hard to find answers in the form of reliable code examples. Do you have debounce code that you depend on in every application? Are you willing to share it with the world? We’d like to gather as many examples as possible and publish them in one-post-to-rule-them-all.

Send your debounce code to: [email protected]

Here’s some guidelines to follow:


  • Please only include debounce code. Get rid of other unrelated functions/etc.
  • You should send C code. If you want to also send an assembly code version that’s fine, but it must be supplementary to the C code.
  • Please comment your code. This will help others understand and use it. You may be tempted to explain the code in your email but this info is best placed in the code comments
  • Cite your sources. If you adapted this code from someone else’s please include a note about that in the code comments.
As an example we’ve included one of our favorite sets of debounce code after the break. Please note how it follows the guidelines listed above.



/*-------------------------------------------------------------------------- 10/13/2010: Button debounce code by Mike Szczys based on "danni debounce" code by Peter Dannegger: http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=189356#189356 This code detects and debounces button presses. It is tailored for use with AVR microcontrollers but I've adapted it for other architectures easily and successfully. It can be modified to use all eight bits on the same port for up to eight buttons. The interrupt service routine (ISR) at the bottom uses binary counter variables (ct0 and ct1) to check the buttons once every 10ms until 40ms has passed. If the button registeres the first and last times it reads it as a keypress. There is no functionality in this code for detecting a held button. --------------------------------------------------------------------------*/ // F_CPU used by debounce to calculate 10ms interrupts #define F_CPU 1200000 #include #include //define pins used by buttons #define KEY_DDR DDRB #define KEY_PORT PORTB #define KEY_PIN PINB #define KEY0 1 //Button on PB1 #define KEY1 2 //Button on PB2 //Debounce variables unsigned char debounce_cnt = 0; volatile unsigned char key_press; unsigned char key_state; /*-------------------------------------------------------------------------- Prototypes --------------------------------------------------------------------------*/ unsigned char get_key_press( unsigned char key_mask ); void init_timers(void); void init_io(void); /*-------------------------------------------------------------------------- FUNC: 10/13/10 - Used to read debounced button presses PARAMS: A keymask corresponding to the pin for the button you with to poll RETURNS: A keymask where any high bits represent a button press --------------------------------------------------------------------------*/ unsigned char get_key_press( unsigned char key_mask ) { cli(); // read and clear atomic ! key_mask &= key_press; // read key(s) key_press ^= key_mask; // clear key(s) sei(); // enable interrupts return key_mask; } /*-------------------------------------------------------------------------- FUNC: 10/13/10 - Sets and starts a system timer PARAMS: NONE RETURNS: NONE --------------------------------------------------------------------------*/ void init_timers(void) { cli(); // read and clear atomic ! //Timer0 for buttons TCCR0B |= 1
 
Back
Top