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
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.
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
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
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.
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
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...
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?
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.