mikrocontroller.net

Forum: Compiler & IDEs Entprellung in der ISR


Autor: Letizia (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Letizia (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Letizia (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Letizia (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
http://www.mikrocontroller.net/articles/Entprellun...


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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.