ON INTERRUPT/de

From MCS Wiki AVR
< ON INTERRUPT(Difference between revisions)
Jump to: navigation, search
((**COPIED FROM ENGLISH PAGE**) =)
(Partial Example)
 
(2 intermediate revisions by one user not shown)
Line 15: Line 15:
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
= <span class="f_Header">Remarks</span> =
+
= <span class="f_Header">Anmerkungen</span> =
 
<div style="padding: 0px; margin: 0px 0px 0px 4px;">
 
<div style="padding: 0px; margin: 0px 0px 0px 4px;">
 
{| width="577" cellspacing="0" cellpadding="1" border="1" style="border: 2px solid rgb(0, 0, 0); border-spacing: 0px; border-collapse: collapse;"
 
{| width="577" cellspacing="0" cellpadding="1" border="1" style="border: 2px solid rgb(0, 0, 0); border-spacing: 0px; border-collapse: collapse;"
 
|- style="vertical-align: top;"
 
|- style="vertical-align: top;"
 
| valign="top" width="13%" style="width: 71px; border: 1px solid rgb(0, 0, 0);" |  
 
| valign="top" width="13%" style="width: 71px; border: 1px solid rgb(0, 0, 0);" |  
Interrupt
+
interrupt
  
 
| valign="top" style="border: 1px solid rgb(0, 0, 0);" |  
 
| valign="top" style="border: 1px solid rgb(0, 0, 0);" |  
INT0, INT1, INT2, INT3, INT4,INT5, TIMER0 ,TIMER1, TIMER2, ADC , EEPROM , CAPTURE1, COMPARE1A, COMPARE1B,COMPARE1. Or you can use the AVR
+
INT0, INT1, INT2, INT3, INT4,INT5, TIMER0 ,TIMER1, TIMER2, ADC , EEPROM , CAPTURE1, COMPARE1A, COMPARE1B,COMPARE1. Man kann auch die AVR Namenskonventionen benutzen:
 
+
name convention:
+
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
Line 35: Line 33:
 
|- style="vertical-align: top;"
 
|- style="vertical-align: top;"
 
| valign="top" width="13%" style="width: 71px; border: 1px solid rgb(0, 0, 0);" |  
 
| valign="top" width="13%" style="width: 71px; border: 1px solid rgb(0, 0, 0);" |  
Label
+
label
  
 
| valign="top" style="border: 1px solid rgb(0, 0, 0);" |  
 
| valign="top" style="border: 1px solid rgb(0, 0, 0);" |  
The label to jump to if the interrupt occurs.
+
Label, zu dem gesprungen werden soll wenn der Interrupt auftritt.
  
 
|- style="vertical-align: top;"
 
|- style="vertical-align: top;"
Line 45: Line 43:
  
 
| valign="top" style="border: 1px solid rgb(0, 0, 0);" |  
 
| valign="top" style="border: 1px solid rgb(0, 0, 0);" |  
When you specify NOSAVE,&nbsp;<span style="font-weight: bold;">no</span>&nbsp;registers are saved and restored in the interrupt routine. So when you use this option make sure to save and restore all used registers.
+
Wenn man NOSAVE angibt dann werden&nbsp;<span style="font-weight: bold;">keine</span>&nbsp;Register bei Aufruf/Verlassen der Interruptroutine gesichert/wiederhergestellt. Wenn Sie diese Option benutzen dann müssen Sie selbst die benutzten Register sichern und wiederherstellen.
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
When you omit NOSAVE all used registers will be saved. These are SREG , R31 to R16 and R11 to R0 with exception of R6,R8 and R9 .
+
Wenn Sie NOSAVE nicht schreiben dann werden alle benutzten Register gesichert. Das sind:
 +
SREG , R31 bis R16 und R11 bis R0 mit Ausnahme von R6,R8 und R9.
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
R12 – R15 are not saved. When you use floating point math in the ISR(not recommended) you must save and restore R12-R15 yourself in the ISR.
+
R12 – R15 werden nicht gesichert. Wenn in der Interruptroutine Fließkommaarithmetik benutzt wird (was nicht empfohlen wird) dann müssen Sie R12 bis R15 selbst sichern und wiederherstellen.
  
 
My_Isr:
 
My_Isr:
  
Push R12 ' save registers
+
Push R12 ' Register sichern
  
 
Push R13
 
Push R13
Line 67: Line 66:
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
Single = single + 1 ' we use FP
+
Single = single + 1 ' Fließkommaarithmetik wird benutzt
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
Pop R15 &nbsp;' restore registers
+
Pop R15 &nbsp;' Register wiederherstellen
  
 
Pop R14
 
Pop R14
Line 85: Line 84:
 
&nbsp;
 
&nbsp;
  
[[File:Notice.jpg|left|Notice.jpg]]When the AVR has extended IO-space (for example ATMega48, 88 or 168, see datasheet at the end: Registersummary), the compiler uses&nbsp;<span style="font-weight: bold;">R23</span>for a number of operations. &nbsp;So Push and Pop R23 as well when using the NOSAVE-option when using these AVR's with extended IO-space.
+
[[File:Notice.jpg|left|Notice.jpg]]Wenn der Mikrocontroller Extendet IO-Space hat (wie zum Beispiel ATmega48, 88, 168, siehe Datenblatt am Ende: Registersummary) dann benutzt der Compiler R23 für einige Operationen. R23 muss dann auch gesichert/wiederhergestellt werden.
  
 
|- style="vertical-align: top;"
 
|- style="vertical-align: top;"
Line 92: Line 91:
  
 
| valign="top" style="border: 1px solid rgb(0, 0, 0);" |  
 
| valign="top" style="border: 1px solid rgb(0, 0, 0);" |  
This is the default and is the same as when no parameter is provided. The most common used registers, SREG, and RAMPZ are saved and restored.
+
Dies ist der Standardwert wenn kein Parameter angegeben wird. Die gebräuchlichsten benutzten Register,  
 +
SREG und RAMPZ werden gesichert und wiederhergestellt.
  
Saved&nbsp;: SREG , R31 to R16 and R11 to R0 with exception of R6,R8 and R9.
+
Gesichert: SREG , R31 bis R16 und R11 bis R0 mit Ausnahme von R6,R8 und R9.
  
If RAMPZ exists, it will be saved as well.
+
Wenn RAMPZ vorhanden ist dann wird es auch gesichert und wiederhergestellt.
  
 
|- style="vertical-align: top;"
 
|- style="vertical-align: top;"
Line 103: Line 103:
  
 
| valign="top" style="border: 1px solid rgb(0, 0, 0);" |  
 
| valign="top" style="border: 1px solid rgb(0, 0, 0);" |  
This will save all registers that SAVE will save, but it will also save R12-R15. You should use this option when using floating point math in the ISR.
+
Dies sichert alle Register, die auch SAVE sichert und zusätzlich noch R12-R15. Man sollte diese Option benutzen wenn man Gleitkommaarithmetik in der Interruptroutine benutzt.
  
 
|}
 
|}
Line 109: Line 109:
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
You must return from the interrupt routine with the RETURN statement.
+
Aus der Interrupt-Routine muss man mit dem RETURN-Befehl zurückkehren
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
The first RETURN statement that is encountered that is outside a condition will generate a RETI instruction. You may have only one such RETURN statement in your interrupt routine because the compiler restores the registers and generates a RETI instruction when it encounters a RETURN statement in the ISR. All other RETURN statements are converted to a RET instruction.
+
Der erste RETURN-Befehl der außerhalb einer Abfrage angetroffen wird generiert eine RETI Instruktion. Man kann nur einen solchen RETURN-Befehl in der ISR haben weil der Compiler die Register wiederherstellt und eine RETI-Instruktion erzeugt wenn es auf das RETURN in der ISR stößt. Alle anderen RETURN-Befehle werden in eine RET-Instruktion umgewandelt
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
The possible interrupt names can be looked up in the selected microprocessor register file. 2313def.dat for example shows that for the compare interrupt the name is COMPARE1. (look at the bottom of the file)
+
Die möglichen Interrupt-Namen können in der Register-Datei des benutzten Mikrocontrollers nachgelesen werden. Die Datei 2313def.dat zeigt zum Beispiel, dass der Name für den Compare-Interrupt den Namen COMPARE1 hat. Siehe am unteren Enede der Datei.
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
Line 123: Line 123:
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
What are interrupts good for?
+
Wofür gibt es Interrupt Service Routinen?
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
An interrupt will halt your program and will jump to a specific part of your program. You can make a DO .. LOOP and poll the status of a pin for example to execute some code when the input on a pin changes.
+
Ein Interrupt unterbricht das Programm und springt zu der angegebenen Routine.  
 +
MAn kann eine DO..LOOP Schleife schreiben und zum Beispiel den Stus eines Eingabepins abfragen um eine Routine anzuspringen wenn der Zustand des Pins sich ändert.
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
But with an interrupt you can perform other tasks and when then pin input changes a special part of your program will be executed. When you use INPUT "Name ", v for example to get a user name via the RS-232 interface it will wait until a RETURN is received. When you have an interrupt routine and the interrupt occurs it will branch to the interrupt code and will execute the interrupt code. When it is finished it will return to the Input statement, waiting until a RETURN is entered.
+
Bei Verwendung eines Interrupts kann man andere Ausgaben ausführen und wenn der Zustand des Pins sich ändert dann wird ein bestimmter Programmteil angesprungen.
 +
Wenn man zum Beispiel INPUT "Name ", v benutzt um einen Usernamen über die serielle Schnittstelle einzulesen dann wird gewartet bis ein RETURN empfangen wird.
 +
Wenn man eine Interruptroutine hat und der Interrupt tritt ein dann wird der Interrupt-Code ausgeführt und wenn er beendet ist dann wird zu dem Input-Befehl zurückgekehrt und gewartet bis ein RETURN empfangen wird.
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
Maybe a better example is writing a clock program. You could update a variable in your program that updates a second counter. But a better way is to use a TIMER interrupt and update a seconds variable in the TIMER interrupt handler.
+
Vielleicht ist ein Uhrenprogramm ein besseres Beispiel. Man könnte einen Sekundenzähler im Programm hochzählen aber es ist besser, einen Timer zu benutzen und einen Sekundenzähler in der Interruptroutine des Timers hochzuzählen.
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
There are multiple interrupt sources and it depends on the used chip which are available.
+
Es gibt verschiedene Interrupt-Quellen und es hängt vom verwendeten Mikrocontroller ab welche jeweils vorhanden sind.
 +
 
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
To allow the use of interrupts you must set the global interrupt switch with a ENABLE INTERRUPTS statement. This only allows that interrupts can be used. You must also set the individual interrupt switches on!
+
Um Interrupts benutzen zu können muss der globale Interrupt-Schalter mit ENABLE INTERRUPTS eingeschaltet werden. Nur dann können Interrupts benutzt werden. Außerdem müssen die jeweiligen individuellen Interrupt-Schalter eingeschaltet werden.
 +
 
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
ENABLE TIMER0 for example allows the TIMER0 interrupt to occur.
+
ENABLE TIMER0 zum Beispiel erlaubt es, dass TIMER0 Interrupts auftreten können.
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
With the DISABLE statement you turn off the switches.
+
Mit dem DISABLE-Befehl können die Schalter ausgeschaltet werden.
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
When the processor must handle an interrupt it will branch to an address at the start of flash memory. These addresses can be found in the DAT files.
+
Wenn der Prozessor einen Interrupt verarbeiten muss dann springt er an eine Adresse am Anfang des Flash-Speichers. Die Adressen stehen in der DAT-Datei.
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
The compiler normally generates a RETI instruction on these addresses so that in the event that an interrupt occurs, it will return immediately.
+
Der Compiler erzeugt normalerweise eine RETI-Instruktion zu diesen Adressen so dass im Falle eines Interrupt-Ereignisses sofort zurückgekehrt wird.
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
When you use the ON ... LABEL statement, the compiler will generate code that jumps to the specified label. The SREG and other registers are saved at the LABEL location and when the RETURN is found the compiler restores the registers and generates the RETI so that the program will continue where it was at the time the interrupt occurred.
+
Wenn man ON..LABEL benutzt dann erzeugt der Compiler Code, der zu dem angegebenen Label springt. DAS SREG und andere Register werden gesichert und wenn RETURN erreicht wird werde die Register wieder hergestellt und ein RETI erzeugt so dass das Programm dort fortgesetzt wird wo es war als der Interrupt aufgetreten war.
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
When an interrupt is services no other interrupts can occur because the processor(not the compiler) will disable all interrupts by clearing the master interrupt enable bit. When the interrupt is services the interrupt is also cleared so that it can occur again when the conditions are met that sets the interrupt.
+
Wenn eine Interruptroutine ausgeführt wird dan können keine anderen Interrupts auftreten weil der Prozessor (nicht der Compiler) alles Interrupts DISABLEd indem das MASTER Interrupt Bit gelöscht wird.  
 +
Nach Abarbeitung der Serviceroutine werden die Interrupts wieder eingeschaltet.
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
It is not possible to give interrupts a priority. The interrupt with the lowest address has the highest interrupt!
+
Es ist nicht möglich, Interrupts eine Priorität zu vergeben. Der Interrupt mit der niedrigsten Adresse hat die höchste Priorität.
 +
 
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
Line 177: Line 184:
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
Finally some tips&nbsp;:
+
Zum Schluss ein paar Tipps&nbsp;:
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
*when you use a timer interrupt that occurs each 10 uS for example, be sure that the interrupt code can execute in 10 uS. Otherwise you would loose time.
+
*Wenn Sie einen Timer-Interrupt haben der alle 10 uS auftritt dann stellen Sie sicher, dass der Interrupt-Code in 10 uS ausgeführt werden kann.
 +
 
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
*it is best to set just a simple flag in the interrupt routine and to determine it's status in the main program. This allows you to use the NOSAVE option that saves stack space and program space. You only have to Save and Restore R24 and SREG in that case.
+
*Es ist am besten, in der Interruptroutine nur ein Flag zu setzen und dessen Status im Hauptprogramm abzufragen. Dies ermöglicht die Benutzung der NOSAVE Option die Stack- und Programmplatz spart. Man muss dann nur R24 und SREG sichern und wiederherstellen.
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
*Since you can not PUSH a hardware register, you need to load it first:
+
*Weil man ein Hardware-Register nicht PUSHen kann muss man es erst laden:
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
PUSH R24&nbsp;; since we are going to use R24 we better save it
+
PUSH R24&nbsp;; Weil wir R24 benutzen werden sichern wir es lieber
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
IN r24, SREG&nbsp;; get content of SREG into R24
+
IN r24, SREG&nbsp;; Inhalt von SREG in R24
  
PUSH R24&nbsp;; we can save a register
+
PUSH R24&nbsp;; Man kann ein Register sichern
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
;here goes your asm code
+
;hier steht Ihr Assembler-Code
  
POP R24&nbsp;;get content of SREG
+
POP R24&nbsp;;Inhalt von SREG zurück
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
OUT SREG, R24&nbsp;; save into SREG
+
OUT SREG, R24&nbsp;; In SREG sichern
  
POP R24&nbsp;; get r24 back
+
POP R24&nbsp;; r24 zurück
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
= <span class="f_Header">See Also</span> =
+
= <span class="f_Header">Siehe auch</span> =
  
 
[[ON VALUE|On VALUE]]
 
[[ON VALUE|On VALUE]]
Line 223: Line 231:
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
= <span class="f_Header">Partial Example</span> =
+
= <span class="f_Header">Teilbeispiel</span> =
  
 
<br/><source lang="bascomavr">
 
<br/><source lang="bascomavr">
 
Enable Interrupts
 
Enable Interrupts
Enable Int0 'enable the interrupt
+
Enable Int0 'Int0 Interrupt einschalten
On Int0 Label2 Nosave 'jump to label2 on INT0
+
On Int0 Label2 Nosave 'Sprung zu label2 wenn INT0 auftritt
Do'endless loop
+
Do'Endlosschleife
 
nop
 
nop
 
Loop
 
Loop
Line 237: Line 245:
 
Dim A As Byte
 
Dim A As Byte
 
If A > 1 Then
 
If A > 1 Then
Return 'generates a RET because it is inside a condition
+
Return 'generiert ein RET weil es in der Abfrage ist
 
End If
 
End If
Return 'generates a RETI because it is the first RETURN
+
Return 'generiert ein RETI weil es das erste RETURN ist
Return 'generates a RET because it is the second RETURN
+
Return 'generiert ein RET weil es das zweite RETURN ist
 
</source><br/>{{Languages}}
 
</source><br/>{{Languages}}
  
 
[[Category:BASCOM Language Reference/de]]
 
[[Category:BASCOM Language Reference/de]]

Latest revision as of 00:57, 18 March 2013

Contents

Funktion

Führt die Subroutine aus wenn der angegebene Interrupt auftritt.

 

 

Syntax

ON interrupt label [NOSAVE|SAVE|SAVEALL]

 

 

Anmerkungen

interrupt

INT0, INT1, INT2, INT3, INT4,INT5, TIMER0 ,TIMER1, TIMER2, ADC , EEPROM , CAPTURE1, COMPARE1A, COMPARE1B,COMPARE1. Man kann auch die AVR Namenskonventionen benutzen:

 

OC2 , OVF2, ICP1, OC1A, OC1B, OVF1, OVF0, SPI, URXC,

UDRE, UTXC, ADCC, ERDY and ACI.

label

Label, zu dem gesprungen werden soll wenn der Interrupt auftritt.

NOSAVE

Wenn man NOSAVE angibt dann werden keine Register bei Aufruf/Verlassen der Interruptroutine gesichert/wiederhergestellt. Wenn Sie diese Option benutzen dann müssen Sie selbst die benutzten Register sichern und wiederherstellen.

 

Wenn Sie NOSAVE nicht schreiben dann werden alle benutzten Register gesichert. Das sind:

SREG , R31 bis R16 und R11 bis R0 mit Ausnahme von R6,R8 und R9.

 

R12 – R15 werden nicht gesichert. Wenn in der Interruptroutine Fließkommaarithmetik benutzt wird (was nicht empfohlen wird) dann müssen Sie R12 bis R15 selbst sichern und wiederherstellen.

My_Isr:

Push R12 ' Register sichern

Push R13

Push R14

Push R15

 

Single = single + 1 ' Fließkommaarithmetik wird benutzt

 

Pop R15  ' Register wiederherstellen

Pop R14

Pop R13

Pop R12

RETURN

 

 

Notice.jpg
Wenn der Mikrocontroller Extendet IO-Space hat (wie zum Beispiel ATmega48, 88, 168, siehe Datenblatt am Ende: Registersummary) dann benutzt der Compiler R23 für einige Operationen. R23 muss dann auch gesichert/wiederhergestellt werden.

SAVE

Dies ist der Standardwert wenn kein Parameter angegeben wird. Die gebräuchlichsten benutzten Register, SREG und RAMPZ werden gesichert und wiederhergestellt.

Gesichert: SREG , R31 bis R16 und R11 bis R0 mit Ausnahme von R6,R8 und R9.

Wenn RAMPZ vorhanden ist dann wird es auch gesichert und wiederhergestellt.

SAVEALL

Dies sichert alle Register, die auch SAVE sichert und zusätzlich noch R12-R15. Man sollte diese Option benutzen wenn man Gleitkommaarithmetik in der Interruptroutine benutzt.

 

Aus der Interrupt-Routine muss man mit dem RETURN-Befehl zurückkehren

 

Der erste RETURN-Befehl der außerhalb einer Abfrage angetroffen wird generiert eine RETI Instruktion. Man kann nur einen solchen RETURN-Befehl in der ISR haben weil der Compiler die Register wiederherstellt und eine RETI-Instruktion erzeugt wenn es auf das RETURN in der ISR stößt. Alle anderen RETURN-Befehle werden in eine RET-Instruktion umgewandelt

 

Die möglichen Interrupt-Namen können in der Register-Datei des benutzten Mikrocontrollers nachgelesen werden. Die Datei 2313def.dat zeigt zum Beispiel, dass der Name für den Compare-Interrupt den Namen COMPARE1 hat. Siehe am unteren Enede der Datei.

 

 

Wofür gibt es Interrupt Service Routinen?

 

Ein Interrupt unterbricht das Programm und springt zu der angegebenen Routine. MAn kann eine DO..LOOP Schleife schreiben und zum Beispiel den Stus eines Eingabepins abfragen um eine Routine anzuspringen wenn der Zustand des Pins sich ändert.

 

Bei Verwendung eines Interrupts kann man andere Ausgaben ausführen und wenn der Zustand des Pins sich ändert dann wird ein bestimmter Programmteil angesprungen. Wenn man zum Beispiel INPUT "Name ", v benutzt um einen Usernamen über die serielle Schnittstelle einzulesen dann wird gewartet bis ein RETURN empfangen wird. Wenn man eine Interruptroutine hat und der Interrupt tritt ein dann wird der Interrupt-Code ausgeführt und wenn er beendet ist dann wird zu dem Input-Befehl zurückgekehrt und gewartet bis ein RETURN empfangen wird.

 

Vielleicht ist ein Uhrenprogramm ein besseres Beispiel. Man könnte einen Sekundenzähler im Programm hochzählen aber es ist besser, einen Timer zu benutzen und einen Sekundenzähler in der Interruptroutine des Timers hochzuzählen.

 

Es gibt verschiedene Interrupt-Quellen und es hängt vom verwendeten Mikrocontroller ab welche jeweils vorhanden sind.


 

Um Interrupts benutzen zu können muss der globale Interrupt-Schalter mit ENABLE INTERRUPTS eingeschaltet werden. Nur dann können Interrupts benutzt werden. Außerdem müssen die jeweiligen individuellen Interrupt-Schalter eingeschaltet werden.


 

ENABLE TIMER0 zum Beispiel erlaubt es, dass TIMER0 Interrupts auftreten können.

 

Mit dem DISABLE-Befehl können die Schalter ausgeschaltet werden.

 

Wenn der Prozessor einen Interrupt verarbeiten muss dann springt er an eine Adresse am Anfang des Flash-Speichers. Die Adressen stehen in der DAT-Datei.

 

Der Compiler erzeugt normalerweise eine RETI-Instruktion zu diesen Adressen so dass im Falle eines Interrupt-Ereignisses sofort zurückgekehrt wird.

 

Wenn man ON..LABEL benutzt dann erzeugt der Compiler Code, der zu dem angegebenen Label springt. DAS SREG und andere Register werden gesichert und wenn RETURN erreicht wird werde die Register wieder hergestellt und ein RETI erzeugt so dass das Programm dort fortgesetzt wird wo es war als der Interrupt aufgetreten war.

 

Wenn eine Interruptroutine ausgeführt wird dan können keine anderen Interrupts auftreten weil der Prozessor (nicht der Compiler) alles Interrupts DISABLEd indem das MASTER Interrupt Bit gelöscht wird. Nach Abarbeitung der Serviceroutine werden die Interrupts wieder eingeschaltet.

 

Es ist nicht möglich, Interrupts eine Priorität zu vergeben. Der Interrupt mit der niedrigsten Adresse hat die höchste Priorität.


 

 

Zum Schluss ein paar Tipps :

 

  • Wenn Sie einen Timer-Interrupt haben der alle 10 uS auftritt dann stellen Sie sicher, dass der Interrupt-Code in 10 uS ausgeführt werden kann.


 

  • Es ist am besten, in der Interruptroutine nur ein Flag zu setzen und dessen Status im Hauptprogramm abzufragen. Dies ermöglicht die Benutzung der NOSAVE Option die Stack- und Programmplatz spart. Man muss dann nur R24 und SREG sichern und wiederherstellen.

 

  • Weil man ein Hardware-Register nicht PUSHen kann muss man es erst laden:

 

PUSH R24 ; Weil wir R24 benutzen werden sichern wir es lieber

 

IN r24, SREG ; Inhalt von SREG in R24

PUSH R24 ; Man kann ein Register sichern

 

hier steht Ihr Assembler-Code

POP R24 ;Inhalt von SREG zurück

 

OUT SREG, R24 ; In SREG sichern

POP R24 ; r24 zurück

 

Siehe auch

On VALUE

 

 

Teilbeispiel


Enable Interrupts
Enable Int0 'Int0 Interrupt einschalten
On Int0 Label2 Nosave 'Sprung zu label2 wenn INT0 auftritt
Do'Endlosschleife
nop
Loop
End
 
Label2:
Dim A As Byte
If A > 1 Then
Return 'generiert ein RET weil es in der Abfrage ist
End If
Return 'generiert ein RETI weil es das erste RETURN ist
Return 'generiert ein RET weil es das zweite RETURN ist

Languages   English Deutsch  
Personal tools
Namespaces
Variants
Actions
Navigation
In other languages
Language