Created
March 16, 2010 17:28
-
-
Save fd0/334261 to your computer and use it in GitHub Desktop.
simple debounce routine
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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