Skip to content

Instantly share code, notes, and snippets.

@fd0
Created March 16, 2010 17:28
Show Gist options
  • Save fd0/334261 to your computer and use it in GitHub Desktop.
Save fd0/334261 to your computer and use it in GitHub Desktop.
simple debounce routine
#include <avr/io.h>
#include <util/delay.h>
/* call every 10 ms, for buttons at pins PC0-PC3 */
uint8_t button_sample(void) {
static uint8_t state = 0b1111; /* initialize state, buttons are active low! */
static uint8_t last_sample = 0b1111; /* initialize old sample */
uint8_t new_sample = PINC & 0b1111; /* read inputs */
/* mark bits which are sampled with the same value */
uint8_t same_sample = (last_sample ^ ~new_sample);
/* all bits set in same_sample now have been sampled with the same value at
* least two times, which means the button has settled */
/* compare the current button state with the most recent sampled value,
* but only for those bits which have stayed the same */
uint8_t state_different = state ^ (new_sample & same_sample);
/* all bits set in state_different have been sampled at least two times
* with the same value, and this value is different from the current button state */
/* if a bit is set in state (means: button is not pressed) AND bit is set
* in state_different (means: input has settled and value is different from state)
* together means: button has been pressed recently */
uint8_t button_press = state & state_different;
/* toggle all bits for inputs which switched state */
state ^= state_different;
/* store current sample for next time */
last_sample = new_sample;
/* if bit is set in button_press, a button has been pressed (not released yet) */
return button_press;
}
/**
* light leds according to parameter led_config
* (bit0-bit4 for led1-led4) and wait 200ms
*/
static void display(uint8_t led_config) {
/* set outputs according to led_config */
if (led_config & 0b1)
PORTC |= _BV(PC4);
else
PORTC &= ~_BV(PC4);
if (led_config & 0b10)
PORTD |= _BV(PD3);
else
PORTD &= ~_BV(PD3);
if (led_config & 0b100)
PORTD |= _BV(PD6);
else
PORTD &= ~_BV(PD6);
if (led_config & 0b1000)
PORTD |= _BV(PD7);
else
PORTD &= ~_BV(PD7);
/* wait 10ms */
_delay_loop_2(F_CPU/4/100);
}
int main(void) {
/* initialisierung */
/* led1 */
DDRC = _BV(PC4);
/* led2-led4 */
DDRD = _BV(PD3) | _BV(PD6) | _BV(PD7);
/* button pullups */
PORTC = _BV(PC0) | _BV(PC1) | _BV(PC2) | _BV(PC3);
uint8_t state = 0;
while(1) {
state ^= button_sample();
display(state);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment