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))
 {
  delay_ms(DEBOUNCE_TIME);
  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()
{
 buttonCounter++;
 if(buttonCounter > BUTTON_OVERFLOW_COUNT)
 {
  buttonWaiting = FALSE;
  timerDetach(TIMER2OVERFLOW_INT);
 }
}

 

 

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 *