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
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
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).
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
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.