Allgemein
Prinzipiell gibt es zwei Möglichkeiten um ein Peripheriegerät zu bedienen. Entweder durch Polling, d.h. ständiges Abfragen der Geräte, oder durch einen Interrupt, bei dem sich das Gerät selbst meldet, wenn es bedient werden muß.
Polling
Die Abfragetechnik oder Polling hat zwei Einschränkungen:
Prozessorzeit wird verschwendet beim unnötigen Durchtesten des Status aller peripheren Einheiten in jedem Durchlauf.
Sie ist vom Prinzip her langsam, da der Status aller E/A-Einheiten getestet werden muß, bevor man zur Abarbeitung einer bestimmten Anfrage kommt. Das kann in einem Echtzeitsystem, in dem man eine Peripherieeinheit, in einem festgelegtem Zeitabschnitt bearbeitet werden muß, echte Schwierigkeiten bereiten. Insbesondere, wenn schnelle Peripherieeinheiten an das System angeschlossen sind, kann die Abfragetechnik einfach nicht schnell genug sein, um noch eine rechtzeitige Bearbeitung der Anfrage zu gewährleisten.
Die Abfragetechnik ist ein synchroner Mechanismus, bei dem die einzelnen Einheiten nacheinander bearbeitet werden.
Interrupts
Programmunterbrechungen, kurz Unterbrechungen (Interrupts), sind ein asynchroner Mechanismus. Jede E/A-Einheit oder ihr Steuerbaustein ist an eine Unterbrechungsleitung angeschlossen. Diese Leitung überträgt eine Unterbrechungsanforderung (interrupt request) an den Mikroprozessor. Jedesmal, wenn eine der E/A-Einheiten bedient werden muß, erzeugt sie einen Impuls oder einen bestimmten Pegel auf dieser Leitung, um den Mikroprozessor auf sich aufmerksam zu machen.
Ein Mikroprozessor testet am Ende jedes Befehlszyklus, ob eine Unterbrechungsanfrage vorliegt. Ist dies der Fall, wird die Unterbrechung durchgeführt. Ist keine Anfrage vorhanden, wird der nächste Befehl übernommen. Dies ist in untenstehendem Flußdiagramm dargestellt.
Werden kritische Prozesse bearbeitet, muß sichergestellt sein, daß die Programmabarbeitung nicht durch eine Unterbrechung gestört wird. Jedesmal, wenn das Maskierungsbit eingeschaltet ist, werden die Unterbrechungsanforderungen nicht beachtet. Die "Maskierungsfähigkeit" wird oft als "Aktivierung" (enable) bezeichnet. Eine Unterbrechung ist aktiviert, d.h. ermöglicht, wenn sie nicht maskiert ist.
Abarbeiten einer Unterbrechung
Wenn die Unterbrechungsanforderung empfangen und entgegengenommen ist, muß die zugehörige Einheit bedient werden. Um dies zu tun, arbeitet der Mikroprozessor eine spezielle Bedienungsroutine (Interrupt Service Routine) ab. Dabei ergeben sich zwei Probleme:
Zum einen muß der Status des gerade abzuarbeitenden Programms zum Zeitpunkt, in dem die Unterbrechungsanforderung entgegengenommen wurde, gerettet werden. Das beinhaltet, daß alle Registerinhalte im Mikroprozessor abgesichert werden müssen. Diese Register werden auf dem Stapel (stack) abgespeichert. Zumindest muß der Programmzähler auf den Stapel gebracht werden, da an seine Stelle die Anfangsadresse der Unterbrechungsroutine gesetzt werden muß. Das Retten der restlichen Register kann mittels Hardware geschehen oder liegt in der Hand der Interrupt Service Routine. Wenn der Programmzähler (und eventuell die anderen Register) auf den Stapel gebracht ist, springt der Mikroprozessor zu der Unterbrechungsroutine. An dieser Stelle ergibt sich das zweite Problem:
Eine ganze Reihe von E/A-Einheiten kann an dieselbe Unterbrechungsleitung angeschlossen sein. Wohin soll der Mikroprozessor springen, um die richtige Einheit zu bedienen? Das Problem liegt darin, die Einheit, die die Unterbrechung anforderte, ausfindig zu machen. Diese Ermittlung kann durch Hardware, durch Software oder eine Kombination von beidem geschehen.
Abfragetechnik
Ist die vom Hardwarestandpunkt einfachste Routine. Hier ist eine Softwareroutine nötig, um die Einheit herauszufinden, die die Unterbrechung anforderte. Hierbei wird die Abfragetechnik benutzt. Die Identifizierungsroutine fragt jede an das System angeschlossene Einheit ab. Eine Möglichkeit wäre, daß jede Einheit einen Porteingang am mC hat, daß bedeutet aber das bei vielen Interrupts viele Eingänge belegt sind. Durch die Reihenfolge der Abfrage ergibt sich eine bestimmte Priorität. In solchen Systemen wird der Vorrang einer Einheit durch Software festgestellt (software-priority scheme), falls mehrere Einheiten zugleich eine Unterbrechung angefordert haben. Ein Nachteil dieser Methode ist natürlich die lange Reaktionszeit auf einen Interrupt.
Daisy-chain Technik
Eine zweite softwareorientierte Methode arbeitet mit Hardwareunterstützung und ist deutlich schneller. Hier wird, wie unten dargestellt, ein Bestätigungssignal (ACK) für die Unterbrechung durch die verschiedenen Einheiten durchgeschleift, die sogenannte daisy-chain (Gänse-blümchenkette). Alle Einheiten hängen auf einer Interruptleitung. Wenn eine Einheit einen Interrupt anfordert, so öffnet sie den Schalter und sendet auf der Interruptleitung die Interrupt-anforderung. Der Prozessor muß bei Eintreffen der Interruptanforderung zumindest den Programmzähler am Stapel absichern. Danach erzeugt der Mikroprozessor ein besonderes Bestätigungssignal (acknowledge auch INTA, d.h. Interrupt Acknowledge) genannt), daß er die Unterbrechung entgegengenommen hat. Dieses Bestätigungssignal erreicht nun die Einheit, die den Interrupt angefordert hat. Diese Einheit setzt nun eine Erkennungsnummer auf den Datenbus, von dem sie der Mikroprozessor einliest. Anhand dieser Erkennungsnummer weiß der mP, welche Interrupt Service Routine er ausführen muß. Wenn mehrere Einheiten einen Interrupt angefordert haben, dann ergibt sich durch die Verbindung vom Acknowledge Signal für jede Einheit eine bestimmte Priorität.
Diese Technik kommt z.B. bei der 8080/8085 Familie zur Anwendung. Da es sich bei der 8051 Familie um Mikrocontroller handelt sind die meisten früheren externen Interruptquellen (Timer od. serielle Schnittstelle) bereits integriert und werden über Interruptvektoren behandelt.
Interruptvektoren
Die schnellste Methode arbeitet mit Unterbrechungszeigern und wird daher als vectored interrupt bezeichnet. Hier hat die E/A-Einheit die Aufgabe, sowohl die Unterbrechungsanforderung zu erzeugen und die Sprungadresse zu der Bedienungsroutine zur Verfügung zu stellen. Wenn die entsprechende Steuerung nur eine Identifikationsnummer zur Verfügung stellt, ist es eine einfache Sache der Software, in einer Tabelle die zugehörige Sprungadresse zu finden. Das ist vom Hardwarestandpunkt aus einfacher, aber ergibt nicht die größtmögliche Leistung. Die größte Leistung erhält man folgendermaßen: Wenn der Mikroprozessor die Unterbrechungsanforderung erhält, muß er den Programmzähler auf dem Stapel absichern und dann ein Acknowledge Signal aussenden. Danach muß die EA-Einheit die Interrupt Vektor Adresse auf den Adressbus legen, von wo sie der mP einliest und in den Programmzähler schreibt. Dadurch kann der mP unmittelbar zu der Speicherzelle springen und mit der Bedienung der Einheit anfangen.
Interruptcontroller
Ein Interruptcontroller ist ein Baustein, der aus einem Interrupteingang am mP mehrere Interrupteingänge macht. Er hat für jede E/A-Einheit einen eigenen Interrupteingang. Deshalb weiß der Interruptcontroller sofort, welche Einheit die Unterbrechung angefordert hat und kann dann eine Interrupt Vektor Adresse auf den Datenbus legen.
Der Vorteil gegenüber der Daisy-Chain Technik ist, daß hier nur der Interruptcontroller "intelligent" sein muß. Bei der Daisy-Chain Technik muß jede Peripherieeinheit eine Logik eingebaut haben, die es ermöglicht die Interrupt Vektor Adresse auf den Datenbus zu legen.
Interruptantwort eines 8085 Prozessor [i]
Nachdem der Interrupt erkannt wird, startet der Mikroprozessor einen speziellen Befehlszyklus, den Interrupt Acknowledge Machine Cycle (INA). Das spezielle an diesem Befehlszyklus ist, daß anstelle von /RD /INTA ausgesendet wird. Am Adreßbus wird trotzdem der Inhalt des Programmzählers gelegt, dies bewirkt jedoch nichts. Wenn /INTA ausgesendet wird, muß die externe Logik den Opcode des auszuführenden Befehls auf den Datenbus legen. Wenn der Opcode das erste Byte eines Mehrbyte-Befehls ist, dann werden zusätzliche /INTA Impulse erzeugt. Ein logischer Befehl wäre z.B. ein Call Befehl, da der Prozessor bei diesem Befehl den Programmzähler am Stapel absichert, bevor er zur angegebenen Adresse springt. Dieser Call-Befehl könnte vom 8259A, einem programmierbarem Interruptcontroller (im 85er mode programmiert) angelegt werden.
Signale |
M2 (MR) |
M1 (INA) |
M2 (INA) |
M3 (INA) |
M4 (MW) |
M5 (MW) |
M1 (OF) |
|||||||||||||||
T2 |
T3 |
T1 |
T2 |
T3 |
T4 |
T5 |
T6 |
T1 |
T2 |
T3 |
T1 |
T2 |
T3 |
T1 |
T2 |
T3 |
T1 |
T2 |
T3 |
T1 |
T2 |
|
CLK |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
INTR |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/INTA |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
IO /M, S1,S0
OUT OUT OUT OUT OUT OUT OUT OUT IN IN IN IN PCH(B3) (SP-1)H (SP-2)H PCH PCH PCH (PC-1)H
A8-A15
D0-D7
(PCL) D0-D7
(PCH) D0-D7
(B3) B2 (SP-2)L (SP-1)L PCL D0-D7
(B2) PCL D0-D7
(Call) PCL D0-D7
AD0-AD7
ALE
/RD
/WR
Timing Diagramm bei Verwendung eines 8085 Prozessors und eines 8259A Interruptcontrollers
Nachdem der Prozessor den Opcode erhalten hat, beschließt er in unserem Fall, daß der Call-Befehl 2 weitere Bytes benötigt. Deshalb sind die nächsten Befehlszyklen 2 weitere INA-Zyklen, um das zweite und dritte Byte des Befehls zu lesen. Da nun der gesamte Befehl eingelesen ist, wird dieser ausgeführt. Als Befehl kann jeder beliebige Befehl außer enable oder disable Interrupt verwendet werden. Die logischsten Befehle wäre ein RESTART oder CALL Befehl, da hier der Programmzähler automatisch abgesichert wird. Innerhalb der 3 INA Zyklen wurde ein erhöhen des Programmzählers verhindert, d.h. der korrekte Wert kann während M4 und M5 abgesichert werden.
Während M4 und M5 führt die CPU Memory Write machine cycles aus, um das höher- und niederwertigere Byte des Programmzählers abzusichern. Danach werden die zwei Bytes, die in M2 und M3 eingelesen wurden in den Programmzähler geschrieben. Das hat den gleichen Effekt, wie ein Sprung zu dieser Adresse.
Interruptantwort eines 8086 Prozessors [ii]
Bei Verwendung eines 8086 Prozessors wird bei einem Interrupt im Prozessor intern ein Call-Befehl ausgelöst. Der Interrupt-Controller legt beim zweiten /INTA Impuls eine 8bit Vektor Adresse auf den Datenbus, die mit der positiven Flanke übernommen wird und den Sprung zur Interrupt Service Routine bewirkt.
Signale |
|
|
|
|
|
|
INTR |
|
|
|
|
|
|
/INTA |
|
|
|
|
|
|
Datenbus |
|
|
|
|
|
|
Timing Diagramm bei Verwendung eines 8086 Prozessors und eines 8259A Interruptcontrollers
Interruptquellen der 8051 Familie
Der 80552 besitzt 15 verschiedene Interruptquellen. Die Interrupts können einer Prioritätsebene zugeordnet werden (0 oder 1). Innerhalb einer Prioritätsebene gelten bei gleichzeitig auftretenden Interrupts folgende Prioritäten:
Interruptquelle |
Name |
Vector Address |
Priorität innerhalb Prioritätsebene |
Externer Interrupt 0 |
X0 |
0003h | |
SIO1 (I²C) |
S1 |
002Bh |
|
ADC completion |
ADC |
0053h |
|
Timer 0 overflow |
T0 |
000Bh |
|
Timer 2 capture 0 |
CT0 |
0033h |
|
Timer 2 compare 0 |
CM0 |
005Bh |
|
Externer Interrupt 1 |
X1 |
0013h |
|
Timer 2 capture 1 |
CT1 |
003Bh |
|
Timer 2 compare 1 |
CM1 |
0063h |
|
Timer 1 overflow |
T1 |
001Bh |
|
Timer 2 capture 2 |
CT2 |
0043h |
|
Timer 2 compare 2 |
CM2 |
006Bh |
|
SIO0 (UART) |
S0 |
0023h |
|
Timer 2 capture 3 |
CT3 |
004Bh |
|
Timer T2 overflow |
T2 |
0073h |
grau unterlegt: auch beim 8051 vorhanden; Vektor Adressen identisch
Externe Interrupts INT0, INT1
TCON |
8F |
8E |
8D |
8C |
8B |
8A |
|
|
Externer Interr upt 0 |
88h |
TF1 |
TR1 |
TF0 |
TR0 |
IE1 |
IT1 |
IE0 |
IT0 |
|
|
Timer Control Register TCON |
||||||||
IEN0 |
AF |
AE |
AD |
AC |
AB |
AA |
A9 |
A8 |
|
A8h |
EA |
EAD |
ES1 |
ES0 |
ET1 |
EX1 |
ET0 |
EX0 |
|
|
Interrupt Enable Register IEN0 |
||||||||
IP0 |
BF |
BE |
BD |
BC |
BB |
BA |
B9 |
B8 |
|
B8h |
|
PAD |
PS1 |
PS0 |
PT1 |
PX1 |
PT0 |
PX0 |
|
|
Interrupt Priority Register IP0 |
Die externen Interrupts /INT0 und /INT1 werden über EX0 und EX1 enabled bzw. disabled.
Mit IT0 und IT1 kann zwischen pegelaktiv und flankenaktiv ausgewählt werden. Wenn ITx 1 ist, dann reagiert der mP auf eine negative Flanke; wenn ITx 0 ist, dann reagiert der mP auf einen Low-Pegel.
IE0 und IE1 sind die Interrupt Request Flags, die gesetzt werden, wenn ein Interrupt aufgetreten ist.
Da die externen Interrupts nach jedem Maschinenzyklus abgefragt werden, sollte ein High- oder Low-Signal mindestens 12 Oszillator Perioden gehalten werden, um sicherzustellen, daß das Signal richtig erkannt wird.
Flankenaktiv:
Damit der Interrupt erkannt wird, muß die externe Spannungsquelle den Interrupt Request Pin für mindestens einen Zyklus auf 1 und für mindestens einen Zyklus auf 0 halten, damit der Übergang von 1 auf 0 erkannt wird. IEx wird automatisch gelöscht, wenn die ISR aufgerufen wird.
Pegelaktiv:
Hier muß der Interrupt Request Pin mindestens einen Maschinenzyklus auf 0 gehalten werden, damit er erkannt wird. Wenn der Interrupt aus irgendeinem Grund erst später behandelt werden kann (siehe 3.1 Interrupt Response Time), dann kann es passieren, daß der Interrupt verloren geht. Die externe Logik bzw. die Interrupt Service Routine müssen dafür sorgen, daß die Interruptanforderung zumindest bis zum Sprung in die Interrupt Service Routine und höchstens bis zum beenden der ISR aktiv bleibt.
Die Bits PX0 und PX1 legen die Priorität des Interrupts fest (0-low priority; 1-high priority).
Timer 0 bzw. Timer 1 Overflow
TCON |
8F |
8E |
8D |
8C |
8B |
8A |
|
|
Timer 1 Overflow Interrupt |
88h |
TF1 |
TR1 |
TF0 |
TR0 |
IE1 |
IT1 |
IE0 |
IT0 |
|
|
Timer Control Register TCON |
||||||||
IEN0 |
AF |
AE |
AD |
AC |
AB |
AA |
A9 |
A8 |
|
A8h |
EA |
EAD |
ES1 |
ES0 |
ET1 |
EX1 |
ET0 |
EX0 |
|
|
Interrupt Enable Register IEN0 |
||||||||
IP0 |
BF |
BE |
BD |
BC |
BB |
BA |
B9 |
B8 |
|
B8h |
|
PAD |
PS1 |
PS0 |
PT1 |
PX1 |
PT0 |
PX0 |
|
|
Interrupt Priority Register IP0 |
TF0 und TF1 werden bei einem Überlauf von Timer 0 bzw. Timer 1 gesetzt (außer bei Timer 0 Mode 3), sie werden bei Aufruf der Interrupt Service Routine wieder rückgesetzt. Die Priorität der Interrupts wird über PT0 und PT1 gesetzt. Über ET0 und ET1 können die Interrupts enabled bzw. disabled werden.
Serielles Port SIO0
S0CON |
9F |
9E |
9D |
9C |
9B |
9A |
|
|
SIO 0 Interrupt |
98h |
SM0 |
SM1 |
SM2 |
REN |
TB8 |
RB8 |
TI |
RI |
|
|
Serial Port Control Register S0CON |
||||||||
IEN0 |
AF |
AE |
AD |
AC |
AB |
AA |
A9 |
A8 |
|
A8h |
EA |
EAD |
ES1 |
ES0 |
ET1 |
EX1 |
ET0 |
EX0 |
|
|
Interrupt Enable Register IEN0 |
||||||||
IP0 |
BF |
BE |
BD |
BC |
BB |
BA |
B9 |
B8 |
|
B8h |
|
PAD |
PS1 |
PS0 |
PT1 |
PX1 |
PT0 |
PX0 |
|
|
Interrupt Priority Register IP0 |
Der Interrupt wird durch eine ODER-Verknüpfung von RI (Receive Interrupt) und TI (Transmit Interrupt) ausgelöst, d.h. der Prozessor "weiß" beim Sprung in die Interrupt Service Routine nicht, durch was der Interrupt ausgelöst wurde. In der ISR müssen RI und TI überprüft und rückgesetzt werden, da sonst bei beenden der ISR ein neuer Interrupt ausgelöst werden würde.
Interrupt Verarbeitung
Interrupt Response Time
Zum Zeitpunkt S5P2 in jedem Maschinenzyklus werden die Interrupts abgefragt und in ein Latch gespeichert. Nachdem der Interrupt anerkannt wurde, ist der nächste Befehl ein Call-Befehl zur Interrupt Service Routine. Dieser Call Befehl benötigt selbst 2 Maschinenzyklen. Das heißt, bis der erste Befehl der Interrupt Service Routine ausgeführt wird vergehen mindestens 3 Maschinenzyklen.
Kürzeste Reaktionszeit auf einen Interrupt, wenn C2 der letzte Befehlszyklus eines Befehls außer RETI oder eines Zugriffes auf IE oder IP ist [7p39]
Die Interrupts werden in jedem Maschinenzyklus während S5P2 gelatched, die gelatchten Zustände werden aber erst im darauffolgenden Maschinenzyklus abgefragt. Dann erst kann der Prozessor entsprechend den im vorigen Zyklus gelatchten Zuständen reagieren.
Anm.: Da in jedem Zyklus gelatched und die alten Werte vom vorigen Zyklus gepolled werden, müssen die Werte doppelt gespeichert werden, oder vor S5P2 gepolled werden.
Wiederholung: Taktperiode (T-State, Phase) / Schritt (State, besteht aus 2 Taktperioden P1, P2) /
Maschinenzyklus (cycle, besteht aus 6 States) / Befehlszyklus (instruction cycle, besteht aus 1 bis 4 cycles)
T 12 MHz Takt - 1 Maschinenzyklus = 1 ms
Eine längere Reaktionszeit kann aus mehreren Gründen vorkommen:
Wenn ein Interrupt gleicher oder höherer Priorität gerade in Arbeit ist, dann hängt die Reaktionszeit von der Interrupt Service Routine des anderen Interrupts ab.
Wenn der gerade ausgeführte Befehl im Augenblick des Pollings nicht den letzten Maschinenzyklus ausführt, dann kann die zusätzliche Verzögerung maximal 3 Zyklen sein, da die längsten Befehle (MUL und DIV) 4 Zyklen lang sind.
Bei einem Zugriff auf IE oder IP oder beim Befehl RETI wird, bevor die Interrupt Service Routine gestartet wird noch ein zusätzlicher Befehl ausgeführt, da möglicherweise gerade der Interrupt gesperrt worden ist und deshalb die Interrupts neu gepollt werden müssen. Dadurch ergibt sich eine zusätzliche Wartezeit von maximal 5 Maschinenzyklen (bei MUL oder DIV Befehl).
Aus diesen Gründen beträgt die Interrupt Response Time immer mehr als 3, aber immer weniger als 9 Maschinenzyklen (falls gerade kein anderer Interrupt abgearbeitet wird).
Die Zuordnung zu einer Priorität wird in jedem Maschinenzyklus wiederholt, und die verglichenen Werte sind diejenigen, die während S5P2 des vorangegangenen Maschinenzyklus vorhanden waren. Ist ein Interrupt-Kennzeichnungsbit gesetzt, das aber wegen einer der obigen Sperrbedingungen nicht bedient werden kann, und ist es bei Aufhebung der Sperrbedingungen nicht mehr gesetzt, so wird der zurückgewiesene Interrupt nicht mehr ausgeführt. Mit anderen Worten: Das System erinnert sich nicht daran, daß das Kennzeichnungsbit gesetzt war, aber nicht bedient wurde. Jeder Zyklus, in dem eine Prioritätenzuordnung erfolgt, muß in diesem Sinn für sich betrachtet werden.
Genaue Zusammenfassung der Interruptreaktionszeit:
3 Perioden + letzter Zyklus eines Befehls + 2 Zyklen CALL-Befehl =
Min. Zeit. 3 Perioden + 3 Zyklen 3.25 ms
3 Perioden + ( bis 3 + 1 Zyklen) + 2 Zyklen Polling nicht während letzem Maschinenzyklus eines Befehls
3 Perioden + 4-6 Zyklen 4.25-6.25 ms
Spezialfall: 3 Perioden + 2 Zyklen RETI + 4 Zyklen (MUL/DIV) + 2 Zyklen CALL =
3 Perioden + 8 Zyklen 8.25 ms
Eine beliebige Zeit kann noch hinzukommen, wenn gerade ein Interrupt gleicher oder höherer Priorität abgearbeitet wird, da dieser nicht unterbrochen werden kann. Dies läßt sich durch den Einbau eines zusätzlichen Prioritätslevel verhindern (siehe Simulieren eines dritten Prioritätslevels)
Anm.: Die hier berechnete Reaktionszeit geht immer von dem Zeitpunkt aus, in dem der Interrupt eingelatched wird.
Interruptablaufdiagramm
zeitbezogen |
programm (adreß) bezogen |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
INT-1 |
|
INT-2 |
|
ISR2RETI |
|
ISR1RETI |
|
INT-3 |
|
ISR3RETI |
SP |
|
SP |
|
SP |
|
SP |
|
SP |
|
|
|
SP |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
RA-1 low |
|
RA-1 low |
|
RA-1 low |
|
|
|
RA-3 low |
|
|
|
|
|
RA-1 high |
|
RA-1 high |
|
RA-1 high |
|
|
|
RA-3 high |
|
|
|
|
|
|
|
RA-2 low |
|
|
|
|
|
|
|
|
|
|
|
|
|
RA-2 high |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
HPHauptprogramm
Interruptannahme: 1 Setzen des IIP-FF ( Interrupt In Progress ) 2 Retten der Rücksprungadresse auf Stack [ PUSH (PC)[iii]] 3 Sprung entsprechend aktuellem Interruptvektor (Sprung zur Interrupt Service Routine ISR ) Rückkehr von der ISR: 1 IIP-FF rücksetzen 2 Rücksprungadresse vom Stack holen [ POP (PC) ] 3 und Programm das vom INT unterbrochen wurde fortsetzen |
A) Tritt während Interrupt in Progress ein Interrupt der selben Prioritätsebe auf, so kann dieser ( selbst wenn er innerhalb dieser Prioritätsebene eine höhere Priorität besitzt ) den laufenden Interrupt nicht unterbrechen. Erst nachdem der laufende Interrupt fertig abgearbeitet ist, reagiert das System auf den Interrupt. Dabei muß ein Befehl des Programmes, das durch den vorigen Interrupt unterbrochen wurde ausgeführt werden.
In obigem Ablaufdiagramm tritt dieser Fall bei der Reaktion auf INT-3 (TIMER1OFL) auf. Man erkennt, daß die Reaktionszeit auf einen Interrupt relativ groß sein kann. Vor allem ist sie nicht vorhersagbar, da man nicht weiß, wieviele Interrupts höherer Priorität schon warten. Schnelle vorhersagbare Reaktion ist nur mit dem Interrupt höchster Priorität möglich.
Interruptanwendungen
Einzelschrittbetrieb [iv]
Die Interrupt-Struktur des 8051 gestattet Einzelschrittbetrieb mit sehr geringem zusätzlichem Software-Aufwand. Wie bereits oben dargelegt, wird eine Interrupt-Anforderung solange nicht bedient, wie ein Interrupt gleicher oder höherer Priorität läuft, oder bis nach einem Befehl RETI wenigstens ein weiterer Befehl ausgeführt worden ist. Somit kann, sobald eine Interrupt Service Routine begonnen hat, sie nicht erneut einsetzen, bevor nicht wenigstens ein Befehl des unterbrochenen Programms ausgeführt wurde. Eine Möglichkeit, diese Tatsache für den Einzelschrittbetrieb zu nutzen besteht darin, einen der externen Interrupt-Anschlüsse (z.B. /INT) so zu programmieren, daß er pegelaktiviert ist. Die Interrupt-Routine wird dann mit folgender Codierung abgeschlossen:
JNB P3.2,$ ;Warte hier, bis INT0 high ist
JB P3.2,$ ;Warte jetzt hier, bis INT0 low ist
RETI ;Springe zurück und führe einen Befehl aus
Wird jetzt der Anschluß /INT0 (gleich dem Anschluß P3.2) normalerweise auf LOW gehalten, so startet die Zentraleinheit die durch den externen Interrupt 0 ausgelöste Routine und bleibt so lange in dieser, bis INT0 gepulst wird (von LOW nach HIGH und von dort nach LOW). Dann führt die Zentraleinheit den Befehl RETI aus, geht ins Hauptprogramm zurück, führt dort einen einzigen Befehl aus und beginnt sofort erneut mit der Routine des externen Interrupts 0, um auf den nächsten Puls von P3.2 zu warten. Bei jedem Puls an P3.2 führt die Zentraleinheit einen Schritt des Hauptprogramms aus.
Simulieren eines dritten Prioritätslevels
Manche Anwendungen benötigen mehr als 2 Prioritätslevel. In solchen Fällen kann eine relativ einfache Routine geschrieben werden um einen dritten Prioritätslevel zu simulieren. Zuerst müssen Interrupts, die eine höhere Priorität als 1 haben sollen im Interrupt Priority Register auf 1 gesetzt werden. Die Interrupt Service Routine für Priorität 1, die durch Interrupts der Priorität 2 unterbrochen werden kann muß folgenden Code enthalten:
PUSH IE
MOV IE,#MASK
CALL LABEL
** ** *************
(Ausführung der Service Routine)
POP IE
RET
LABEL: RETI
Sobald ein Interrupt der Priorität 1 auftritt werden alle Interrupts der Priorität 0 und 1 disabled. Der CALL to LABEL Befehl bewirkt die Ausführung des RETI Befehls und damit ein Löschen des Interrupt in Progress Flip Flop der Priorität 1. Zu diesem Zeitpunkt kann jeder Interrupt bedient werden, aber es sind nur Interrupts der Priorität 2 enabled
POPing IE stellt das original Enable Byte wieder her. Danach wird ein normaler RET Befehl (nicht RETI) verwendet um die Interrupt Service Routine abzuschließen. Diese zusätzliche Software verlängert die ISR von Interrupts der Priorität 1 um 10ms.
Interrupt Arbeitsblatt
Erläuterungen zur Interrupt Logik
Prioritäts-level |
Haupt- programm |
ISR 1 + 2 |
S1 |
R1 |
S0* |
R0 |
/Q1.S0 |
Q1 |
Q0 |
Interrupt-annahme |
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||
Low |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||
High |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||
Low |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Prioritäts-level |
Haupt- programm |
ISR 1 + 2 |
S1 |
R1 |
S0* |
R0 |
/Q1.S0 |
Q1 |
Q0 |
Interrupt-annahme |
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||
Low |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||
High |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||
Low |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[i] Aus Intel MCS-80/85 Family Users Manual Seite 2-13
[ii] OKI Microprocessors Data Book 1987 S.307
[iii] genau genommen erfolgen 2 PUSH-Befehle, da PUSH beim 8051 nur ein 8-Bit-Wort rettet.
[iv] Aus Philips 8051 Datenbuch 1995 S.71
Haupt | Fügen Sie Referat | Kontakt | Impressum | Nutzungsbedingungen