Geht das jetzt nur um Tastenabfragen an den Inputs?
Dann würde ich NICHT den PortChange-Interrupt verwenden, sondern einen Timer im ms-Bereich. Der alleine bewerkstelligt schon die Entprellung.
Der Code gestaltet sich vielleicht mithilfe einer Loop etwas schöner, wobei ich auch gleich das Allgemeingültige vom Anwendungsspezifischen trennen würde:
InitKeys wird einmalig nach dem Controllerreset aufgerufen, die ISR wäre hier z.B. der TimerOverflow.Code:uint8_t prevPINA; void InitKeys() { prevPINA = PINA; } ISR (TIM0_OVF_vect) { uint8_t actPINA = PINA; //buffer actual state uint8_t chPINA = prevPINA ^ actPINA; //get changes with XOR uint8_t setPINA = chPINA & actPINA; // get new set pins uint8_t clPINA = chPINA & ~actPINA; // get new cleared pins prevPINA = actPINA; //save actual PINA in prevPINA for next ISR call for (uint8_t i = 0; i<8; i++) { if ((setPINA >>i) & 0x01) KeyDown(i); if ((clPINA >>i) & 0x01) KeyUp(i); } }
Das Applikationsspezifische:
Ob man nun alle Pins mit Tasten belegt hat oder nur einige, ist dem allgemeinen Teil egal. Das wird erst durch die cases in den Switches entschieden.Code:#define KEY_ENTER 0 #define KEY_ESC 1 #define KEY_UP 6 #define KEY_DOWN 7 void KeyDown(uint8_t key) { switch (key) { case KEY_ENTER: //TODO break; case KEY_ESC: //TODO break; } } void KeyUp(uint8_t key) { //Das gleiche in grün }
(nicht kompiliert, daher ohne Gewähr! Aber mal so als Idee)







Zitieren




Lesezeichen