alles klar, Danke :)
Druckbare Version
alles klar, Danke :)
Ich versuche mal, das hier alles ein wenig zusammenzufassen:
Bei einem Interrupt wird die aktuell laufende Befehlskette unterbrochen, um einen anderen Programmabschnitt auszuführen. Nach der Ausführung dieses Programnmabschnitts kehrt der Controller wieder zu seiner vorherigen Position zurück.
Ein Interrupt wird verwendet, um
a) zeitkritische Funktionen zu erledigen
b) den Prozessor zu entlasten
Ein Beispiel zu a)
Du willst ein Signal abfragen, das aber sehr kurz ist, z.B. einen Impuls mit der Dauer 1µs. Die Durchlaufzeit Deiner Hauptschleife beträgt aber z.B. 10µs. Wenn Du in der Hauptschleife eine if-Abfrage ausführst, um den Impuls zu erfassen, ist es sehr wahrscheinlich, dass Du den Impuls verpasst. Benutzt Du einen Interrupt, erkennt der Prozessor den Impuls sofort und kann in der Interruptroutine entsprechend darauf reagieren. Somit wird kein Impuls verpasst.
Diese Hardware-Interrupts werden auch zum Auslesen von Kommunikationsleitungen verwendet, damit keine Übertragungen verloren gehen.
Ein Beispiel zu b)
Du willst einige Taster abfragen. Fragst Du die Taster per if in Deiner Hauptschleife ab, muss der Prozessor diese Abfrage bei jedem Durchlauf abarbeiten, auch wenn kein Taster gedrückt wurde. Das kostet Rechenzeit.
Hier kann man dann per Timer einen Interrupt z.B. alle 100 Millisekunden erzeugen lassen, durch den dann die Taster abgefragt werden. Dadurch wird der Controller entlastet.
Wichtig ist, dass Interruptroutinen möglichst kurz gehalten werden, vor allem dann, wenn mehrere Interruptroutinen benutzt werden.
Gruß,
askazo
Dazu vielleicht noch ein paar Worte, da es bisher nicht explizit erwähnt wurde:Zitat:
Das muss ja quasi auch in meinem Programmcode sein und dann wird es ja wieder nur an der bestimmten Stelle abgefragt.
Ja, um Interrupts zu nutzen müssen gewisse Dinge in deinem Programmcode stehen...
1. die ISR (also die Funktion welche bei einem bestimmten Interrupt aufgerufen werden soll)
2. die Konfiguration der Interrupts
Du programmierst also nicht "so, jetzt schau mal nach ob Pin X von LOW auf HIGH gesprungen ist, und falls ja springe zur ISR Y" sondern "hey, falls irgendwann mal PIN X von LOW auf HIGH springt, bitte geh zur ISR Y"
anders ausgedrückt:
der Sprung in die ISR (als Reaktion auf ein bestimmtes vorher eingestelltes Ereignis), erfolgt rein hardwaremäßig. Nicht du musst dich darum kümmern, sondern der Mikrocontroller.
Nicht ganz. Bei einem Interrupt (gut Deutsch Unterbruch) wird das aktuelle Programm SOFORT unterbrochen. Darum ist es auch wichtig, die Variablen in einem Programm, die vom Interrupt tangiert werden könnten, am Anfang es Interruptes zu sichern und kurz vor Ende der Intertuptroutine diese wieder herstellen, damit das unterbrochene Programm mit den korrekten Werten weiteraufgeführt werden kann.Zitat:
Zitat von Jaecko
Steht im jeweiligen Datenblatt des Controllers...Zitat:
Zitat von Jaecko
Sonst ist eignetlich alles gesagt worden.
Sofort geht nicht, der AVR kann schließlich nicht einfach einen Maschinenbefehl abbrechen, den er gerade abarbeiten soll. Auf den Interrupt reagiert er also erst, wenn er mit seinem aktuellen Befehl fertig ist.Zitat:
Bei einem Interrupt (gut Deutsch Unterbruch) wird das aktuelle Programm SOFORT unterbrochen.
Das würde ich so jetzt nicht sagen...Zitat:
Darum ist es auch wichtig, die Variablen in einem Programm, die vom Interrupt tangiert werden könnten, am Anfang es Interruptes zu sichern und kurz vor Ende der Intertuptroutine diese wieder herstellen, damit das unterbrochene Programm mit den korrekten Werten weiteraufgeführt werden kann.
Bei Assembler muss man die im Interrupt genutzten Register erstmal sichern, damit das Programm später fehlerfrei fortgesetzt werden kann, bei C hingegen nimmt einem der Compiler diese Arbeit ab, es sei denn man verbietet es ihm explizit.
Und Variablen muss man im Normalfall sowieso nicht sichern, denn wenn ein Programm die Änderung einer Variable durch eine ISR nicht verkraftet, dann ist es meiner Meinung nach schlecht programmiert. Meist ist es ja sogar die einzige Aufgabe einer ISR irgendeinen Wert in irgendeine Variable zu schreiben, würde man diese dann vor dem Rücksprung wiederherstellen, hätte man sich den kompletten Interrupt sparen können.
Entscheident hierbei ist das Verständnis des Wortes Anweisung/Befehl. Beim einem AtMega kann eine Anweisung die mehrere Takte dauert sehr wohl von einem Interrupt unterbrochen werden. Das kann zu sehr hässlichen Effekte führen. In solchen Fälle verbietet man die Interrupts vor dem Befehl und erlaubt sie danach wieder. Außerdem nennt sich das Critical Section und hört sich wichtig an. :-sZitat:
Zitat von Felix G
Eine Anweisung die nur einen Takt benötigt kann allerdings wirklich nicht unterbrochen werden :-)
Es gibt Programme die nur auf Ereignisse reagieren, die Interrupts auslösen. Man könnte fast sagen, die ereignisgesteuert sind. Die "Hauptschleife" bei diesen Programmen ist leer.
Gruß
Jens
Zitat:
Beim einem AtMega kann eine Anweisung die mehrere Takte dauert sehr wohl von einem Interrupt unterbrochen werden.
Alles andere wäre auch sinnlos...Zitat:
Zitat von ATmega32 Datenblatt, Seite 13
stell dir mal vor der AVR würde mitten in einem CALL (4 Zyklen) her gehen, und irgendwas anderes tun ... wo soll er dann nach der ISR hin springen?
Man könnte ein Programm so schreiben, aber empfehlen würde ich es nicht, da die ISRs sonst zu groß werden. Man stelle sich nur mal ein Programm mit 4 oder 5 Interrupts vor, bei denen die Routinen derart lang sind, daß sie sich ständig gegenseitig unterbrechen ... viel Spaß beim debuggen.Zitat:
Es gibt Programme die nur auf Ereignisse reagieren, die Interrupts auslösen. Man könnte fast sagen, die ereignisgesteuert sind. Die "Hauptschleife" bei diesen Programmen ist leer.
Meiner Meinung nach sollte man in den ISRs nur jeweils einzelne Flags setzen, und vielleicht noch einige Variablen ändern. Die eigentliche Arbeit, also komplexe Berechnungen etc. erledigt man dann sinnvollerweise woanders, nämlich in der Hauptschleife ("Flag XY gesetzt? gut, dann führe Funktion Z aus")
Hallo,
oh sorry, ich war so sehr in C. Es gibt in C Befehle die z.B. je nach Variablengröße in einen oder mehrere asm-Befehle übersetzt werden.
Da gilt das von mir geschriebene. Ansonsten hast du recht und was da steht ist so Quatsch. :oops:
Da schreib ich noch, dass es auf die def. von Befehl ankommt ...
Gruß
Jens
Ach so war das gemeint, dann ist alles klar...
bei C weiß man natürlich erst dann genau wieviel Assemblercode letztendlich entsteht, wenn man im Listing nachschaut.
Also: je weniger Variablen man in einer ISR ändert, desto besser. Denn in C kann sogar das setzen eines einzelnen Bits in einer Variable unter Umständen von einem Interrupt unterbrochen werden (je nachdem was der Compiler draus macht). Dennoch sollte das nicht zu Problemen führen, wenn man diesen Fall beim Programmieren im Hinterkopf behält, und das Programm entsprechend strukturiert.
Setzt man in einer ISR z.B. tatsächlich nur ein Flag, und erledigt die eigentliche Arbeit in der Hauptschleife, braucht man sich wegen solchen Dingen keine Sorgen machen (Ausnahme: der ADC, da kann es durchaus sinnvoll/notwendig sein den Interrupt abzuschalten, bevor man den aktuellen Wert ausliest).
Register meinte ich eigentlich. Anderseits kann man bei Assembler die Register umbenennen. Klassiches Beispiel temp1. Also kann man temp1 wie eine Variable anschauen...Zitat:
Bei Assembler muss man die im Interrupt genutzten Register erstmal sichern, damit das Programm später fehlerfrei fortgesetzt werden kann, bei C hingegen nimmt einem der Compiler diese Arbeit ab, es sei denn man verbietet es ihm explizit.Zitat:
...Darum ist es auch wichtig, die Variablen in einem Programm, die vom Interrupt tangiert werden könnten...