mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik 8051 external interrupt: mehrfaches aufrufen verhindern?


Autor: Maverick (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bin neu in der 8051 programmierung.

Folgendes Problem: ich will den INT0-Interrupt zum umschalten von 
Funktionen nutzen. Aber es scheint, dass bei einem Tastendruck der 
interrupt 2 oder mehr mal aufgerufen wird.

Ich nehme an, dass es mit dem typischen verhalten des Tasters 
zusammenhängt. Die klassische Lösung mit der verzögerung bringt nichts: 
auch wenn ich innerhalb des Handlers  EA = 0; setze, 20ms aktiv-warten 
und erst dann wieder EA aktiviere, scheint es doppelt aufgerufen zu 
werden.

Ich benutze den uC51-compiller.


Was wäre die beste standartlösung?

Danke

Autor: Thomas B. (detritus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Taster nicht per Interrupt abfragen, sondern pollen. Dann kann man auch 
gleich entprellen. Wirklich kein neues Thema hier, einfach mal suchen.

Wegen dem Mehrfach-Aufruf trotz Wartezeit:
Mit EA sperrst du nur den Aufruf des Interrupthandlers. Wenn bei EA=0 
das Interrupt-Ereignis auftritt, wird das zugehörige Interruptbit 
gesetzt, aber nix weiter unternommen. Sobald EA dann wieder da ist, 
werden die Handler aufgerufen.

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

du solltest niemals in Interrupts solche Sachen wie Warteschleifen 
o.ä. einbauen. Interrupts müssen eigentlich so schnell wie möglich 
fertig sein, ausserdem blockst du damit unnötig andere Interrupts. Bei 
kleinen Projekten mag dies nicht ins Gewicht fallen, aber wenns mal 
komplexer wird, wunderst du dich dann, warum die Interrupts so langsam 
abgearbeitet werden oder womöglich Interrupts verloren gehen.

Du kannst wie bereits von  Thomas B. erwähnt per Polling arbeiten, das 
heisst, an bestimmten Stellen im Hauptprogramm prüfen, ob der Eingang 
aktiv ist. Wenn ja, dann wartest du 20ms, und prüfst nochmal. Wenn der 
Eingang dann immer noch aktiv ist, änderst du die Funktion. Das lässt 
sich in ein Unterprogramm packen, welches du dann immer per CALL-Befehl 
aufrufst.

Eine Alternative mit Interrupts gibts natürlich auch, allerdings ist der 
INT0/1-Interrupt (=Externer Interrupt) dafür ungeeignet. Nimm besser 
einen der Timer-Interrupts. Du stellst den Timer-Interrupt auf 20ms ein. 
Wenn der Interrupt zuschlägt, prüfst du den Eingang, setzt/löschst 
entsprechend ein Bit und verlässt den Interrupt. Beim nächsten 
Timer-Interrupt prüfst du das Bit. Ist es gesetzt und der Eingang immer 
noch aktiv, dann signalisierst du über ein weiteres Bit dem 
Hauptprogramm, dass sich die Funktion geändert hat. Ist der Eingang 
nicht mehr aktiv gewesen, dann gibts auch keine Nachricht ans 
Hauptprogramm, und das "Merk"-Bit innerhalb des Interrupts wird gelöscht 
(Wird natürlich auch gelöscht, wenn das Hauptprogramm die Nachricht 
erhalten hat, denn dann hat es seinen Zweck erfüllt). Das Entprellen ist 
damit auch gelöst.

Es gibt natürlich weitere Ansätze, die eben anders arbeiten. Ich 
verwende eben immer den Timer-Interrupt, wobei dieser eine kleinere 
Zeitbasis hat. Bei mir sind es etwa 138 µs. Über eine Vorteiler-Variable 
teile ich die Interrupt-Zeit in drei Abschnitte von jeweils 3,33ms. 
Jeder Abschnitt hat eine andere Aufgabe: Matrix-Tastatur-Abfrage, 
Software-Timer (10ms Auflösung) und Aktualisierung der Software-RTC. Da 
bei jedem Interrupt ein anderer Abschnitt drankommt, sind diese 3,33ms 
zueinander versetzt. Jeder Abschnitt kommt alle 10ms dran (3x3,33ms).

Du siehst, jeder hat da so seine Lösungsart :)

Wenn du Fragen dazu hast, ruhig zu.

Ralf

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Maverick wrote:
> Die klassische Lösung mit der verzögerung bringt nichts:

Das stimmt, man sollte daher von der klassisch schlechten Lösung 
sprechen.


Die zuverlässige Lösung entprellt und flankenerkennt immer mindestens 
einen ganzen Port parallel (aufm 8-Bitter: 8 Tasten).

Sie ist allerdings so gut, daß sie selbst für nur eine Taste die 
klassisch schlechte Lösung weit in den Schatten stellt.

Sie benutzt den Timerinterrupt und tastet 4-mal ab:

http://www.mikrocontroller.net/articles/Entprellun...

Für den 8051 muß man nur die Interruptsyntax, Timerinitialisierung und 
Portdefinitionen etwas anpassen.


Peter

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn du ein mehrfaches aufrufen des interupts verhindern möchtest,

musst du dann über software den interrupt sperren und dann später wieder 
freischalten.

ich weiß nicht mehr genau den befehl, war nur ein tipp

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.