Simple AVR Button Debounce

14 Jan

I needed a simple debounce for a push button wired directly to a digital input on an ATMega.  I’m sure there are more advanced techniques but this is working well for me.

int ButtonPressed()
 /* the button is pressed when BUTTON_BIT is clear */
 if (bit_is_clear(BUTTON_PIN, BUTTON_BIT))
  if (bit_is_clear(BUTTON_PIN, BUTTON_BIT)) return 1;
 return 0;

Where bit_is_clear is defined in AVR-LIBC IO.H as

#define bit_is_clear ( sfr, bit ) (!(_SFR_BYTE(sfr) & _BV(bit)))

and when I actually use this to detect a press I incorporate a timer to prevent another detection (double press).  The timer is started and a blocking flag cleared upon completion, which will then allow a second detection.

BOOL buttonWaiting = FALSE;
int buttonCounter = 0;

void ProcessCurrentState()
 // Check buttons here
 if (!buttonWaiting && ButtonPressed())
  buttonWaiting = TRUE;
  buttonCounter = 0;

  timerAttach(TIMER2OVERFLOW_INT, ClearButtonWait);

  // Process button press
  // or take appropiate action

void ClearButtonWait()
 if(buttonCounter > BUTTON_OVERFLOW_COUNT)
  buttonWaiting = FALSE;



Tweet about this on TwitterShare on Google+Share on FacebookShare on RedditEmail this to someoneShare on LinkedInShare on StumbleUpon

Leave a Reply

Your email address will not be published. Required fields are marked *