mikrocontroller.net

Forum: Compiler & IDEs Interruptprogrammierung


Autor: Braun Fabian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo miteinander!

Habe Probleme mit Interruptprogrammierung in AVR-GCC!
Es gibt ja zwei verschiedene Arten wie man Interruptroutinen aufrufen 
kann.
Die eine ist INTERRUPT(SIG_OVERFLOW0) und die andere 
SIGNAL(SIG_OVERFLOW0). Was ist der Unterschied zwischen diesen Beiden? 
Im Englischen Tutorial hab ich sowas rauslesen können, dass SIGNAL auch 
benutzt werden kann wenn die Interrupts nicht eingeschaltet sind. Und 
was nützten überhaupt sei() und cli()?
Ich hatte ein Programm wo ich während der Ausführung immer beim Externen 
Interrupt 0 (INT0) von Triggern auf steigende und Triggern auf fallende 
Flanke wechselte. Dies Funktionierte erst als ich vor dem Wechsel cli() 
und nach dem Wechsel sei() angefügt habe. Wieso das?

Wär echt froh wenn mir das jemand mal auf Deutsch erklären könnte! Danke 
schon im Voraus.

Gruss Fabian

Autor: Peter Fleury (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei INTERRUPT() kann die Interrupt-Routine durch einen anderen Interrupt 
unterbruchen werden.
Bei SIGNAL() wird die Interrupt-Routine nicht durch einen anderen 
Interrupt unterbrochen.

Da steht übrigens im avr-libc User Manuel, zwar auf English.

Eine lokale Kopie dieses Manuals befindet sich auf deinem PC im 
Verzeichnis:
C:\WinAVR\doc\avr-libc\avr-libc-user-manual\index.html

Autor: Joerg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du hast das aus dem Englischen nicht ganz richtig rausgelesen:
SIGNAL() läßt die Interrupts ausgeschaltet (was sie erstmal
innerhalb einer Interruptroutine standardmäßig sind -- mit dem
abschließenden RETI werden sie wieder zugeschaltet), während
INTERRUPT() sofort im Funktionskopf ein sei() ausführt und
damit geschachtelte Interrupts zuläßt.

Wenn Du nicht weißt, was Du willst, dann willst Du immer SIGNAL(). :-)
Insebesondere Interruptroutinen für UARTs sind hier extrem mit
Vorsicht zu genießen, da bei denen die Interruptbedingung erst
gelöscht wird, wenn das zugehörige UDR gelesen bzw. geschrieben
wird.  Werden die Interrupts vorher wieder freigeschaltet, dann
wird sofort ein neuer Interrupt ausgelöst!

Während aller Aktionen, die die Interruptbedingungslogik
umschalten, sollte man generell die Interrupts erstmal
ausschalte (cli()), andernfalls kann es passieren (je nachdem,
welcher Interrupt und ob seine Bedingung jetzt schon anliegt),
daß sofort beim Umstellen ein Interrupt ausgelöst wird.  Gerade
bei externen Interrupts ist es allemal auch eine gute Idee,
das entsprechende Hardware-Flag nach dem Umstellen und vor
dem sei() noch manuell zu löschen (das ist das zugehörige
INTFx Flag, je nach Prozessor im GIFR oder im EIFR Register
gelegen).  Achtung, Löschen bedeutet dabei, ein 1-Bit zu
schreiben (das ist beinahe generell beim AVR so).

Autor: Braun Fabian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

OK...langsam machts klick :-)
Also d.h. wenn ich jetzt eine Interruptroutine mit SIGNAL(blablabla) 
nehmen und in dieser cli() ausführe etwas ändere und nacher nicht mehr 
sei() ausführen sondern diesen befehl einfach auslasse, dann wird das 
sozusagen am schluss automatisch gemacht? ist das korrekt?

herzlichen dank für eure hilfe!

Fabian Braun

Autor: Joerg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Immer noch nicht. :)  Du brauchst gar kein cli() innerhalb von
SIGNAL() machen, Interrupts sind automatisch abgeschaltet für
diese Zeit.

Du kannst aber innerhalb von SIGNAL() explizit ein sei() machen,
wenn Du bereits vorfristig Interrupts wieder zulassen willst
(und damit eine Schachtelung von Interruptroutinen), anonsten
werden sie ab dem Ende der SIGNAL-Routine wieder freigegeben.

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.