Archiv verlassen und diese Seite im Standarddesign anzeigen : Interrupt unterbricht Printbefehl
Hallo zusammen,
kann es sein, das ein Interrupt den Printbefehl unterbrechen kann? Wenn ich einen längeren String senden will und dieser noch nicht ganz raus ist, während der Interrupt ausgelöst wird, dann springt der µC doch erst mal in die Interruptroutine oder?
Und wenn ich "Config Print verwende für die automatische Senderichtungsumschaltung", passiert das dann im Hintergrund oder, kann das auch von einem Interrupt unterbrochen werden?
Vielen Dank für euere Hilfe
Hallo demmy,
ein Interrupt unterbricht jedem Bascom Befehl, der in mehrere Maschinenbefehle übersetzt wird, also auch einen Print Befehl.
Die Annahme ist, dass die Arbeiten im Interrupt so wichtig sind, dass unmittelbar darauf reagiert werden muss.
Wenn du das nicht möchtest, kannst du vor dem Print Befehl die Interrupts global sperren und hinterher wieder freigeben.
Ja ok, das heißt aber auch, dass nach dem Interrupt das Senden weiter fortgesetzt wird oder?
Besserwessi
03.10.2012, 21:37
So langer Interrupt nicht gegen die üblichen Regeln verstößt, läuft danach das Hauptprogramm normal weiter, als wäre nichts gewesen, außer halt einer kleinen Verzögerung.
Wenn für den Print Befehl eine Software UART genutzt wird, könnte es eventuell Probleme geben, denn da ist eine Unterbrechung nicht zu jeder Zeit erlaubt. Das müsst jemand klären der sich genau mit BASCOM auskennt.
Thomas E.
05.10.2012, 23:52
Wenn du das nicht möchtest, kannst du vor dem Print Befehl die Interrupts global sperren und hinterher wieder freigeben.
Was mich irgendwie zu der Frage bringt, ob der Controller anschließend den anstehenden Interrupt auch ausführt? Oder gilt ein Interrupt, der während der "Sperrphase" eintrifft als verloren?
Was mich irgendwie zu der Frage bringt, ob der Controller anschließend den anstehenden Interrupt auch ausführt? Oder gilt ein Interrupt, der während der "Sperrphase" eintrifft als verloren?
Soweit ich weiß ja. Für den Controller sind die Interrupts gesperrt und solange die gesperrt sind beachtet er die nicht.
Ein einfaches Beispiel....wenn du den Interrupt bei einem Mikrocontroller erst 30 Sekunden nach Programmanfang aktivierst führt er doch auch nicht alle Interrupts aus die bis dahin eingegangen sind ;).
Das wäre zumindest mein Denkansatz.
Was mich irgendwie zu der Frage bringt, ob der Controller anschließend den anstehenden Interrupt auch ausführt? Oder gilt ein Interrupt, der während der "Sperrphase" eintrifft als verloren?
Wenn eine Interrupt Bedingung zutrifft, wird das entsprechende Flag im zugehörigen Register gesetzt. Werden dann irgendwann die Interrupts global freigegeben, werden die ISR der gespeicherten Interrupts in der Reihenfolge ihrer Priorität angesprungen.
Wenn du das nicht willst, gibt es auch hier einen Weg, die Ausführung zu vermeiden, indem du das Flag selber noch einmal setzt.
Der erste Interrupt geht also nicht verloren. Trifft der gleiche Interrupt allerdings mehrfach ein, bevor seine ISR ausgeführt wird, dann gehen die Interrupts dann doch verloren.
Thomas E.
06.10.2012, 11:23
Das heißt also, es gibt für jeden Interrupt (Timer0, INT0, etc.) sozusagen einen 1-Bit-Speicher (ganz doof ausgedrückt)?
Besserwessi
06.10.2012, 11:34
Für alle Interrupts gibt es je einen solchen Speicher (Flag Bit in den entsprechenden Registern). Nur wenn der Externe Interrupt auf Level angestellt ist, wird das Bit auch ggf. wieder gelöscht, wenn kein externes Signal mehr anliegt - da fehlt dann der Zwischenspeicher.
z.B. Datenblatt ATMega8:
A flexible interrupt module has its control registers in the I/O space with an additional global
interrupt enable bit in the Status Register. All interrupts have a separate Interrupt Vector in the
Interrupt Vector table. The interrupts have priority in accordance with their Interrupt Vector position.
The lower the Interrupt Vector address, the higher the priority.
also für alle Interrupts gibts Sprungmarken, die man setzen muss wenn man den interrupt verwenden will.
In Bascom schaut das dann z.B. so aus: On Urxc1 Zeichenempfang:
The AVR Status Register – SREG – is defined as:
Bit 7 – I: Global Interrupt Enable
Das ist dann das SEI bzw. Enable Interrupts, also die generelle Aktivierung der Interrupts.
Es kann in bestimmten Fällen sinnvoll sein einen Programmabschnitt unterbrechungslos zu programmieren, dann kann man einfach
vor diesem Programmabschnitt ein "Disable Interrupts" oder CLI setzen und dahinter wieder "Enable Interrupts" oder SEI.
wichtig in dem Zusammenhang:
When an interrupt occurs, the Global Interrupt Enable I-bit is cleared and all interrupts are disabled.
The user software can write logic one to the I-bit to enable nested interrupts. All enabled
interrupts can then interrupt the current interrupt routine. The I-bit is automatically set when a
Return from Interrupt instruction – RETI – is executed.
wenn also ein Interrupt ausgeführt wird werden die anderen Interrupts generell abgeschaltet bis dieser abgearbeitet wurde. Dann werden die Interrupts wieder aktiviert. Man kann aber in einer Interruptroutine wiederum die Interrupts per SEI oder Enable Interrupts aktivieren, dann kann ein Interrupt in einem Interrupt erfolgen, was zu "interessanten" Ergebnissen führen kann. Kann aber in Ausnahmefällen sinnvoll sein.
if one or more interrupt conditions occur while the global interrupt
enable bit is cleared, the corresponding Interrupt Flag(s) will be set and remembered until the
global interrupt enable bit is set, and will then be executed by order of priority.
Das bedeutet, wenn z.B. der URXC Interrupt für Zeichenempfang aktiviert wurde, aber global die Interruptverarbeitung deaktiviert ist, so wird der Interrupt bei Zeichenempfang zwar ausgelöst, aber erst abgearbeitet wenn global die Interrupts aktiviert wurden.
Einen Interrupt kann man je nach dem auch löschen, z.B. um bei der UART zu bleiben, da steht im UCSRA Register als Bit7
This flag bit is set when there are unread data in the receive buffer and cleared when the receive
buffer is empty (that is, does not contain any unread data). If the Receiver is disabled, the
receive buffer will be flushed and consequently the RXC bit will become zero. The RXC Flag can
be used to generate a Receive Complete interrupt
Du kannst nun dieses Interruptflag auf zwei Arten löschen ... einmal indem Du einfach in das Bit eine 0 hinein schreibst UCSRA.7=0
oder indem Du das empfangene Zeichen auf dem zugehörigen Datenregister UDR ausliest: Dummmybyte=UDR
Generell gilt, die Interrupts immer knackig kurz halten, nur das was unbedingt hinen muss dort auch rein packen.
Resourcenfressende Routinen wie LCD-Ausgaben oder Print oder Input / Waitkey oder Kalkulationen mit Single-Variablen, die Rechenzeit fressen, haben da wenig drinnen verloren.
Man sollte also die Aufgaben dann teilen, z.B. den Zeichenempfang für ein UART-Protokoll. Die Daten empfangen und im Ringspeicher ablegen in den Interrupt, dort dann auch ein Flag setzen und die Verarbeitung dann von der Mainloop aus anspringen.
Hallo Vitis,
wo hast du diese Info her?
Du kannst nun dieses Interruptflag auf zwei Arten löschen ... einmal indem Du einfach in das Bit eine 0 hinein schreibst UCSRA.7=0
oder indem Du das empfangene Zeichen auf dem zugehörigen Datenregister UDR ausliest: Dummmybyte=UDR
Ich dachte, dass man das einmal gesetzte Flag nur durch Lesen des UDR oder durch disablen des Receivers (UCSRB.RXEN=0) wegbekommt.
Versuch macht kluch, hab ich mal so gemacht, war in dem Fall aber Käse, ist unterm Strich genau so schnell wenn man einfach das Register liest und ggf. Inhalt verwirft.
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.