Hallo ich habe folgende Frage an euch: Ich habe einen Mikrocontroller (Mega32) der Hardware ansteuert (Aktoren, Sensoren etc.). Dieser bekommt vom PC über die serielle Schnittstelle Parameter zugeschickt. Der Mikrocontroller (in Assembler programmiert) löst bei Empfang eines Zeichens einen Interrupt aus. In dieser ISR werden Interrupts deaktiviert, der Parameter entgegen genommen, kurz verarbeitet und gespeichert, danach Interrupts wieder aktiviert und die ISR beendet um mit dem Hauptprogramm weiter zu machen. So jetzt kommt die eigentliche Frage: Wenn jetzt in der Zeit der Abarbeitung der ISR weitere Parameter gekommen sind und im Puffer der serielle Schnittstelle hinterlegt wurden, löst der Mikrocontroller dann nach der ISR gleich einen weiteren Interrupt (weil er sieht das im Puffer Daten sind) aus oder muss ich in der ISR solange lesen bis der Puffer leer ist (weil das alleinige vorhanden sein von Daten im Puffer keinen Interrupt auslöst)? Gibt es eine Möglichkeit zu verhindern, dass die ISR unterbrochen wird und trotzdem neue Interrupts angenommen werden können? Vielen Dank im Vorraus
Das RXC-Flag bleibt gesetzt, bis der Puffer komplett ausgelesen ist. Wenn also in einer ISR das UDR gelesen wird und in der Zwischenzeit ein neues Zeichen eintrifft, dann wird die ISR nach dem Rücksprung ins Hauptprogramm erneut aufgerufen. Das Deaktivieren der Interrupt-Bearbeitung in der ISR geschieht übrigens automatisch durch die Hardware. Da braucht im Programm nichts geändert zu werden.
Ich würde dir empfehlen nen Fifo zu basteln. In der ISR werden einfach alle empfangenen Daten in den Fifo geschrieben. Bei jedem Zeichen wird eine globale Zählervariable inkrementiert. Außerhalb der ISR machst du quasi eine While-Schleife, die guckt ob noch Daten im Fifo sind. Solange dies der Fall ist werden die Parameter nacheinander abgearbeitet (und für jedes verarbeitete Zeichen auf dem Fifo die Zählervariable dekrementiert). Wenn du es so machst wird s wohl kaum passieren dass dir Daten verloren gehen.
Ich dachte dafür ist das globale Interrupt Enable Bit vs. den einzelnen Interrupt Enable Bits da? Wenn die einzlenen gesetzt sind, werden die Flags in den Flag-Registern gesetzt und nur wenn auch das globale I-Bit gesetzt ist, kommt es zur Ausführung des Int-Vektors.. deswegen ja auch SEI und CLI, am Ein- und Ausgang einer ISR.. Wenn ein Interrupt kommt -> CLI, dann werden alle weiteren Interrupts ihre Flags setzen, aber die aktuelle ISR nicht unterbrochen. Am Ende der ISR ein -> SEI und zurück.. dann können die in der Zwischenzeit eingetrudelten Interrupts anhand ihrer Flags und ihrer Priorität (siehe Interrupt Vektor Tabelle) abgearbeitet werden. So mein Bild des Geschehens.. allerdings nutze ich nur C (dort wird standardmässig SEI und CLI erzeugt), deshalb könnte obiges auch falsch sein. Steht nix in dem AVR-Tutorial? Aus den Datenblättern hab ichs bisher immer so verstanden.. Grüsse
Joan P. wrote: > Ich dachte dafür ist das globale Interrupt Enable Bit vs. den einzelnen > Interrupt Enable Bits da? Wofür? > Wenn die einzlenen gesetzt sind, werden die Flags in den Flag-Registern > gesetzt und nur wenn auch das globale I-Bit gesetzt ist, kommt es zur > Ausführung des Int-Vektors.. deswegen ja auch SEI und CLI, am Ein- und > Ausgang einer ISR.. Falsch. Die Flags werden immer gesetzt, wenn das dazugehörige Hardware-Ereignis auftritt (*). Durch die lokale und globale Freigabe wird lediglich die Interrupt-/Bearbeitung/ freigegeben. Wenn ein Flag gesetzt ist und die Interrupt-Bearbeitung wird freigegeben, dann wird sofort der dazugehörige Handler ausgeführt. > Wenn ein Interrupt kommt -> CLI, dann werden alle weiteren Interrupts > ihre Flags setzen, aber die aktuelle ISR nicht unterbrochen. Am Ende der > ISR ein -> SEI und zurück.. dann können die in der Zwischenzeit > eingetrudelten Interrupts anhand ihrer Flags und ihrer Priorität (siehe > Interrupt Vektor Tabelle) abgearbeitet werden. Noch mal: Das cli und sei macht die µC-Hardware automatisch! > So mein Bild des Geschehens.. allerdings nutze ich nur C (dort wird > standardmässig SEI und CLI erzeugt), deshalb könnte obiges auch falsch > sein. Steht nix in dem AVR-Tutorial? Nein, das hat nichts mit C zu tun! Auch wenn Du in Assembler programmierst, ist ein Interrupt-Handler ohne weitere Maßnahmen nicht unterbrechbar, weil die Hardware das I-Bit im SREG beim Einsprung in den Vektor löscht und bei einem entsprechenden Rücksprung wieder setzt! (*) Wenn z.B. ein Timer überläuft, dann wird immer das betreffende Timer-Overflow-Flag gesetzt (sofern es noch nicht gesetzt war), auch wenn das dazugehörige "Timer Overflow Interrupt Enable"-Bit und/oder das I-Bit im SREG nicht gesetzt ist. Ansonsten wäre v.a. Polling von Flags nicht möglich, wenn andere Interrupts freigegeben sind.
Joan P. wrote: > Ich dachte dafür ist das globale Interrupt Enable Bit vs. den einzelnen > Interrupt Enable Bits da? > > Wenn die einzlenen gesetzt sind, werden die Flags in den Flag-Registern > gesetzt und nur wenn auch das globale I-Bit gesetzt ist, kommt es zur > Ausführung des Int-Vektors.. deswegen ja auch SEI und CLI, am Ein- und > Ausgang einer ISR.. > > Wenn ein Interrupt kommt -> CLI, dann werden alle weiteren Interrupts > ihre Flags setzen, aber die aktuelle ISR nicht unterbrochen. Am Ende der > ISR ein -> SEI und zurück.. dann können die in der Zwischenzeit > eingetrudelten Interrupts anhand ihrer Flags und ihrer Priorität (siehe > Interrupt Vektor Tabelle) abgearbeitet werden. Noch mal. Genau das macht die Hardware schon ganz von alleine. Am besten ist es wenn man sich da komplett raus hält, sonst kann es dir nämlich passieren, dass noch bevor eine ISR fertig ist, die nächste ISR schon angesprungen wird, weil du die Interrupts global ein klein wenig zu früh freigibst. Sobald eine ISR aufgerufen wird, wird von der Hardware völlig von alleine das globale Interrupt Flag gelöscht und sobald der zugehörige RETI (Return from Interrupt) kommt, schaltet die Hardware ganz von alleine die Interrupts wieder frei.
Vielen Dank für die Antwort man lernt immer etwas dazu. Dachte immer man muss die sei und cli selber setzten aber so kann man sich täuschen werde dass bei Gelegenheit mal ausprobieren. Danke
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.