Moin. Schon wieder so ne dumme Anfängerfrage: Ich habe hier zwei Taster an zwei Portpins hängen, zusätzlich löst jeder der Taster auch noch den externen Int0 aus. (Die beiden Tasten sind über Dioden voneinander entkoppelt) Klappt auch so weit, bis ich versuche zu unterscheiden ob eine der beiden oder beide Tasten gleichzeitig gedrückt sind (1,2,1+2): Wenn beide Taster schnell hintereinander gedrückt werden (z.B. immer abwechselnd einen der beiden) kommt das Programm durcheinander und behauptet es würden beide gleichzeitig gedrückt sein. (schnell hintereinander und gleichzeitig jeweils im sinne einen bedienenden Menschen, nicht im Sinne von Echtzeitanwendung) Ich kann mir nicht vorstellen das ich schnell genug drücken kann um während des prellen des einen Tasters den anderen zu drücke (zumal auch beide Taster mit RC entprellt sind, und im Programm eine Pause von 30ms in der Innterrupt Routine eingebaut ist. Mache ich hier einen Denkfehler und kann das so gar nicht funktionieren? Hat dafür jemand schon mal einen Ansatz entwickelt - ich werde doch wohl kaum der erste mit so einer Idee sein. Freue mich auf Antworten! JL
Hallo, ich habe mir jetzt den Quellcode nicht genau angeschaut aber ich würde es anders machen. Mit dem EXT-INT nur die beiden Tasten Bits in ein Register lesen und evtl. noch ein Bit setzen (es waren Tasten da) dann den INT sperren. Dann eine Routine die die Bits auswertet und den INT wieder freigibt, jetzt hast Du warscheinlich nie beide gleichzeitig, wenn Du beid egleichzeitig brauchst wirds schwieriger. Gruß Mike
Das Hauptproblem ist der falsche Ansatz: Die Interrupts sind nur dann nötig, wenn wirklich schnell auf ein Signal reagiert werden muß. Und eine manuell bediente Taste gehört auf keinen Fall dazu. Für solche arschlahmen Sachen ist das Polling im Timerinterrupt oder in der Hauptprogrammschleife wesentlich einfacher und effektiver. Abgesehen davon macht Dir ein Warten von elendlangen 30ms innerhalb eines Interrupts jegliche Performance zunichte. Warten im Interrupt, sowas tut man einfach nicht. Ein Zug wartet ja auch nicht auf den Fahrgast eine Stunde später, sondern dieser Fahrgast nimmt dann den planmäßig nächsten Zug. Ein Timerinterrupt alle 5ms ... 100ms ist ideal zum Abfragen und gleichzeitigen Entprellen. Hier ein Beispiel für das Abfragen einer Tastaturmatrix mit der 8051-Familie: http://www.specs.de/users/danni/appl/soft/keyscan/index.htm Das Prinzip ist aber ähnlich, wenns ein AVR mit einzelne Tasten sein soll. Peter
Vielen Dank erstmal für die Tips, war anscheinend ein hardware Problem und falsches "löschen" der Interrupt-Flags - wer lesen (und löten) kann... indieeckestellundschäm @Peter: Ich möchte den Timer nicht für die Tasten verwenden, außerdem habe ich noch genug andere Signale die ich pollen muss, dann kann die Kiste wenigstens die Tasten ignorieren wenn nix los ist :) (Es geht mir auch nicht unbedingt um effizienteste Programmierung, sondern viel mehr darum, mich mal an den Chip zu gewöhnen und nen bischen auszuprobieren)
@Jäpke, wenn Du auch noch andere Sachen machen willst, ist es erst recht äußerst unklug, im Interrupt riesige 300000 Zyklen (10MHz Quarz) zu verschwenden. Wenn Du z.B. noch einen Timerinterrupt alle 10ms brauchst, gehen Dir, bei 30ms Nichtstun, bei jedem Tastendruck 2 Stück verloren. Und wenn Du für andere Sachen schon den Timer benötigst, kann da doch bequem die Tastenabfrage mit rein. Z.B. bei 10ms Timerinterruptzeit und 2µs (= 20 Befehle bei 10MHz) zum Tastenabfragen, hast Du nur 0,02% der CPU-Zeit damit belegt. Schau Dir mal größere Programme an, langes Warten im Interrupt wirst Du da nie finden. Peter
so isses, das tut man niemals nirgends nicht :-) Gar nicht erst angewöhnen, Warteschleifen haben in einer ISR nichts zu suchen, allerhöchstens ganz kurze von ein paar Takten.
Anbei die Abfrage von bis zu 8 Tasten per Timerinterrupt. Es wird dabei nur das Tastendrücken, also der Übergang von 1-0 gewertet (Taste schaltet gegen 0V). Das Prinzip beruht auf einigen einfachen Logikgleichungen, die bitweise für jede Taste separat ausgeführt werden: Das Debounce-Bit merkt sich immer den vorherigen Wert des Tasten-Bits. Das Old-Bit übernimmt den Wert des Tasten-Bits immer nur dann, wenn auch das Debounce-Bit den gleichen Wert hat, d.h. zweimal hintereinander der gleiche Tastenpegel erkannt wurde. Und das Code-Bit wird gesetzt, wenn Tasten- und Debounce-Bit = 0 sind, aber das Old-Bit = 1 ist, d.h. also nur beim 1-1-0-0 Übergang. Als Kommentar sind alle 8 möglichen Kombinationen der Tasten-, Debounce- und Old-Bits angegeben und nur eine davon ist ein Tastendruck. Das ganze kostet Dich gerade mal 12 Zyklen im Interrupt und nicht 300000. Peter
Ich hab hier ein paar Schaltungen, wie man Taster an einen Controller anschließen kann, unter anderem auch mit IRQ http://www.elektronik-projekt.de/Schaltungen/Taster.html Sind aber sicher nicht alle Möglichkeiten abgedeckt Markus
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.