www.mikrocontroller.net

Forum: Mikrocontroller und Elektronik serieller Interrupt Mega32

Autor: Tobias (Gast)
Datum: 15.05.2008 12:46

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
Autor: Johannes M. (johnny-m)
Datum: 15.05.2008 13:09

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.
Autor: Timmo H. (masterfx)
Datum: 15.05.2008 13:15

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.
Autor: Joan P. (joan)
Datum: 15.05.2008 13:20

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
Autor: Johannes M. (johnny-m)
Datum: 15.05.2008 13:36

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.
Autor: Karl heinz Buchegger (kbuchegg) (Moderator)
Datum: 15.05.2008 13:38

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.
Autor: Tobias (Gast)
Datum: 15.05.2008 18:52

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
Autor: Joan P. (joan)
Datum: 15.05.2008 18:56

Danke für die Aufklärung!!^^ :-)

Antwort schreiben

Die Angabe einer Email-Adresse ist freiwillig. Wenn Sie automatisch per Email über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Suchfunktion und Betreffsuche benutzen - vielleicht gibt es schon einen ähnlichen Beitrag
  • Aussagekräftigen Betreff wählen
  • Im Betreff angeben um welchen Controllertyp es geht (AVR, PIC, ...)
  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
  • JPEG-Dateien (.jpg) nur für Fotos und Scans verwenden
  • Schaltpläne, Screenshots usw. als PNG oder GIF anhängen

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [pre]vorformatierter Text (z.B. Code in anderen Sprachen)[/pre]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel






webmaster@mikrocontroller.netImpressumWerbung auf Mikrocontroller.net