/* tastenzustand_02.c ATmega88 @ 1MHz */ #include <avr/io.h> #include <avr/interrupt.h> #include <avr/wdt.h> #define button_down !(PIND & (1<<PD2)) // Button = Low #define button_up (PIND & (1<<PD2)) // Button = High #define debounce_time 2 // Entprellzeit = 32ms x 2 #define short_keypress_timeout 15 // 15 x 32ms = 0,48s #define long_keypress_time 25 // 25 x 32ms = 0,8s enum press_type {short_keypress, long_keypress, running}; int main(void) { WDTCSR = (1<<WDIE) | (1<<WDP0); // watchdog @32ms + interrupt enabled DDRB |= (1 << PB0) + (1 << PB1); // PB0 und PB1 = Ausgang DDRD &= ~(1<<PD2); // PD2 = Eingang sei(); // Interrupts aktivieren while(1) { asm ("NOP"); // Nichts tun } } ISR (WDT_vect) // ISR Watchdogtimer Overflow Interrupt { static unsigned int button_timer; // timer to determine button state static enum press_type typ; typ = running; // vorherigen Tasterzustand verlassen if (button_down) // button wurde gedrückt (LOW) { if (button_timer < long_keypress_time) button_timer ++; } else // button wurde losgelassen (HIGH) { if (button_timer == long_keypress_time) { typ = long_keypress; // Tastendruck = langer Tastendruck } else if ((button_timer > debounce_time) && (button_timer < short_keypress_timeout)) { typ = short_keypress; // Tastendruck = kurzer Tastendruck } if (button_timer) // Button Timer nach Tastendruck zurücksetzen { button_timer = 0; } } if (typ == long_keypress) // Langer Tastendruck { PORTB ^= (1<<PB0); // Portpin PB0 toggeln } else if (typ == short_keypress) // Kurzer Tastendruck { PORTB ^= (1<<PB1); // Portpin PB1 toggeln } WDTCSR = (1<<WDIE); // Watchdog Interrupt aktivieren }