Forum: Compiler & IDEs Entprellung in der ISR


von Letizia (Gast)


Lesenswert?

Hallo,

ich habe einen Button K1, der über Port E an dem ATmega 128 angebracht 
ist. Diese K1 löst durch Drücken (low level) die ISR(INT6_vect) aus, die 
den µC aus seinem Schlafmodus heraus holt.
Nun stehe ich vor dem Problem, dass ich den Button Entprellen muss, doch 
bin ich mir nicht ganz sicher, wie das funktioniert.
Ich würde gerne auf die erste Änderung des Buttons reagieren. Wenn ich 
ein delay() einbauen würde, würde dies doch nicht das Problem lösen? Ich 
verstehe es so, dass durch das Prellen immer weiter ISRs ausgelöst 
werden und dies gilt zu Verhindern?

Danke
Gruß
Letizia

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Wie macht man es im richtigen Leben? Man pennt. Der Wecker brüllt. Man 
haut auf die Stummtaste. Man schaut nach, welche Zeit und welcher Tag 
ist. Dann steht man auf oder pennt wieder ein.

Wenn ein low-level INT deinen AVR weckt, könnte der als erstes weitere 
INTs sperren (disable) und ggf. noch durchs Prellen anstehende löschen. 
Dann könnte er innerhalb paar ms nachsehen, ob die Wecktaste noch 
gedrückt ist oder ob es ein kurzer Glitch auf der Leitung war. Im ersten 
Fall (noch low level) kann er loslegen und im zweiten Fall (bereits high 
level) legt er sich wieder schlafen, nachdem er zuerst den INT wieder 
scharf gemacht hat.

von Peter D. (peda)


Lesenswert?

Eine zuverlässige Methode ist, man nimmt den Interrupt nur zum Aufwachen 
und läßt dann die Taste ganz normal über den Timerinterrupt entprellen.

War es nur ein Störimpuls oder gibt es nichts weiter zu tun, dann 
enabled der Timerinterrupt nach ner Weile wieder Sleepmodus und 
Aufwachinterrupt.


Peter

von Letizia (Gast)


Lesenswert?

Würde es einen Unterschied machen, ob ich Timerinterrupt oder einen 
delay benutze? Im Endeffekt bewirkt doch beides nur, dass für eine 
gewisse Zeit nicht gemacht werden kann?

Danke

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Letizia schrieb:

> Würde es einen Unterschied machen, ob ich Timerinterrupt oder einen
> delay benutze? Im Endeffekt bewirkt doch beides nur, dass für eine
> gewisse Zeit nicht gemacht werden kann?

Jein. Du kannst schon was machen bis das Ergebnis (entprellter 
Tastendruck oder Spike) vorliegt.

Bei der delay-Lösung muss die Wartezeit und die Ausführungszeit der 
Zwischenfunktionen dann eben klein genug sein.

Beispiel: Du willst 30ms Entprellen. Dann könntest du 30s 1ms delays 
benutzen und zwischen den delays noch was machen. Stünde das Ergebnis 
früher fest, kannst du auch früher abbrechen.

Bei der allgemeinen Timer-Lösung zum Entprellen hast du deutliche 
Vorteile gegenüber der delay-Lösung. Die Timer-Lösung läuft im 
Hintergrund neben dem Userprogramm und pollt ständig die Eingabepins. 
Wenn das Userprogramm eine Eingabe abfrägt, stellt die Timer-Lösung die 
sofort zur Verfügung. Das Userprogramm braucht nicht selbst zu 
entprellen.

Beim Spezialfall Aufwecken hast du einen leicht geänderten Fall, wenn 
der Timer erst ab dem Aufwecken weiterläuft. Das Pollen startet auch 
erst dann. D.h. bis das Ergebnis vorliegt, muss der Timer auch eine 
gewisse Zeit laufen, d.h. das Userprogramm hat nicht sofort das 
Ergebnis. Das Userprogramm müsste in diesem Fall auch warten. Dann 
könnte es auch gleich mit delay warten und selbst pollen.

Trotzdem würde ich die Timerlösung nehmen, wenn im normal laufenden 
Userprogramm ggf. prellende Eingaben behandelt werden sollen und/oder 
Zeiträume abgepasst werden sollen.

von Peter D. (peda)


Lesenswert?

Letizia schrieb:
> Würde es einen Unterschied machen, ob ich Timerinterrupt oder einen
> delay benutze? Im Endeffekt bewirkt doch beides nur, dass für eine
> gewisse Zeit nicht gemacht werden kann?

Nein.
Der Timerinterrupt gibt die Wartezeit immer an die Mainloop zurück.
Es können also neben der Entprellung noch viele andere Tasks laufen.
Außerdem spart es Code, wenn man bei der Entprellung nicht unterscheiden 
muß zwischen Aufwachen und Betrieb.

Nach dem Aufwachen kann es sein, daß die Mainloop noch nichts zu tun 
hat.
Die Zeit kann aber genutzt werden, wenn nötig, d.h. Du bist in jedem 
Fall flexibler.


Peter

von Letizia (Gast)


Lesenswert?

Ich habe die Register, in welchen die Bits für einen Timerinterrupt 
gesetzt werden müssen, gefunden. Ich stelle mir vor, dass diese in der 
ISR, die auf das Drücken reagiert, gesetzt werden. Aber woher wie kann 
ich sicher gehen, dass der Button entprellt ist?

Meine jetzige Lösung sieht so aus, dass ich die Bits, die gesetzt 
werden, damit das Drücken einen Interrupt auslöst in der ISR wieder 
disable. In der main werden diese wieder gesetzt, nur leider tritt 
danach noch einen einzige Prellung auf, die ich nicht haben möchte...

von Letizia (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Eine zuverlässige Methode ist, man nimmt den Interrupt nur zum Aufwachen
> und läßt dann die Taste ganz normal über den Timerinterrupt entprellen.

Wie würde sowas aussehen?

von Karl H. (kbuchegg)


Lesenswert?

http://www.mikrocontroller.net/articles/Entprellung#Komfortroutine_.28C_f.C3.BCr_AVR.29


Bau zuerst die Entprellung ein lass den Aufwachinterrtup bzw. Sleepmodus 
noch weg.

Wenn du das dann alles am laufen hast, ergänzt du die wieder. Der 
Aufwachinterrupt disabled einfach nur in seiner ISR seinen Interrupt. 
Enabled wird er dann wieder nach einiger Zeit ehe sich der µC wieder 
schlafen legt.

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.