Forum: Mikrocontroller und Digitale Elektronik Mehrere Taster an Int0


von Jäpke Lesselich (Gast)


Angehängte Dateien:

Lesenswert?

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

von Mike (Gast)


Lesenswert?

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

von Peter D. (peda)


Lesenswert?

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

von Jäpke Lesselich (Gast)


Lesenswert?

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)

von Peter D. (peda)


Lesenswert?

@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

von crazy horse (Gast)


Lesenswert?

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.

von Peter D. (peda)


Angehängte Dateien:

Lesenswert?

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

von Markus Burrer (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.