// ************************************************************************ // * * // * Arcade Stick * // * Tastenprogrammierung * // * * // ************************************************************************ #include #include #include #include #include "lcd.h" #include "LCD_Driver.h" #ifndef F_CPU #define F_CPU 4000000 // Processor Takt-Frequenz definieren #warning kein F_CPU definiert #endif // Tasteneingänge definieren // ========================= #define KEY_DDR DDRB #define KEY_PORT PORTB #define KEY_PIN PINB #define KEY0 6 #define KEY1 7 #define KEY2 0 #define KEY3 1 #define KEY4 2 #define KEY5 3 #define KEY6 4 #define KEY7 5 #define ALL_KEYS (1< Taste wurde gedrückt volatile uint8_t key_press; // Tastendruck registriert volatile uint8_t key_rpt; // Tastendruckdauer volatile uint8_t nKonfig = 1; // Tasten-Konfiguration volatile uint8_t Summe = 0; // Tastenzuordnung bei gedrückten Tasten volatile uint8_t nFire = 0; // Dauerfeuer-Konfiguration volatile uint8_t nFireTime = 12; // Dauerfeuer-Zeit volatile uint8_t MenuOnScreen = 0; // LCD-Menü aktiv? unsigned char menu_index = 0; unsigned char sub_menu_index = 1; // Timer Interrupt von 10ms definieren // =================================== ISR(TIMER0_OVF_vect) { static uint8_t ct0, ct1, rpt, cntTicks; uint8_t i; TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5); i = key_state ^ ~KEY_PIN; // Taste geändert? ct0 = ~(ct0 & i); // resete oder zähle CT0 ct1 = ct0 ^ (ct1 & i); // resete oder zähle CT1 i &= ct0 & ct1; // Überlauf gezählt? key_state ^= i; // dann Entprellstatus ändern key_press |= key_state & i; // 0->1: Tastendruck erkannt if((key_state & REPEAT_MASK) == 0) // Überprüfe Tastenwiederholfunktion rpt = REPEAT_START; // Starte Verzögerung if(--rpt == 0) { rpt = REPEAT_NEXT; // Wiederhole Verzögerung key_rpt |= key_state & REPEAT_MASK; } if (nFire != 0) { cntTicks++; // Ist Dauerfeuer aktiv if(cntTicks >= nFireTime) // und Feuergeschwindigkeit x 10ms { // toggle abhängig von Konfiguration, Ausgang PortC.0 KonfigPattern[nKonfig-1][KonfigPattern[nKonfig-1][6]] ^= 0x01; cntTicks = 0; } } } // Überprüfen, ob eine Taste gedrückt wurde. // Jede gedrückte Taste wird nur einmal gemeldet // ============================================= uint8_t get_key_press(uint8_t key_mask) { cli(); // Interrupts deaktivieren key_mask &= key_press; // Tasten auslesen key_press ^= key_mask; // Tasten löschen sei(); // Interrupts aktivieren return key_mask; } // Erfolgt ein längerer Tastendruck, so wird nach einiger Zeit // der Tastendruck automatisch wieder verworfen. // =========================================================== uint8_t get_key_rpt(uint8_t key_mask) { cli(); // Interrupts deaktivieren key_mask &= key_rpt; // Tasten auslesen key_rpt ^= key_mask; // Tasten löschen sei(); // Interrupts aktivieren return key_mask; } // Kurzer Tastendruck // ================== uint8_t get_key_short(uint8_t key_mask) { cli(); // Interrupts deaktivieren return get_key_press(~key_state & key_mask); } // Langer Tastendruck // ================== uint8_t get_key_long(uint8_t key_mask) { return get_key_press(get_key_rpt(key_mask)); } void lcd_update() { MenuOnScreen = 0; lcd_gotoxy(0,0); // Startmeldung am LCD anzeigen lcd_puts(menu_000); lcd_gotoxy(0,1); lcd_puts(menu_001); menu_index = 0; } // Initialisierung der Ports // ========================= void init() { // Ports initialisieren // -------------------- OUT_DDR |= ALL_OUT; // Controller als Ausgang definieren KEY_DDR &= ~ALL_KEYS; // Tastenports als Eingang definieren KEY_PORT |= ALL_KEYS; // Tastenports PullUp // Interrupt aktvieren // ------------------- TCCR0 = (1<