erstellt  14.05.2011
Was ist ein Interrupt
Interrupt ( lat. Interruptus) bedeutet Unterbrechung .
In der Elektronik heißt " einen Interrupt auslösen " so viel wie ein laufendes  Programm durch ein Ereignis zu unterbrechen.
Es gibt 2 verschiedene Arten von Interrupts - Interne und Externe .
Externe Interrupts werden erzeugt, wenn an den Pins INT0, INT1 oder INT2 ein auslösendes Ereignis auftritt, selbst dann, wenn der jeweilige Pin als Ausgang geschaltet ist.
Externe Ereignisse können durch Schalter, Taster, Sensoren oder auch andere Mikrocontroller an den unten erwähnten Pins ausgelöst werden.
Die Pins für die Externen Interrupt Anforderungen am Atmega 8  sind INT0 (Pin 4) und INT1 (Pin5)
Am  Atmega 32 ist das der (Pin 16) für INT0 und (Pin17) für  INT1 und (Pin3) für INT2
Interne Interrupts werden durch Ereignisse im Chip ausgelöst (z.B. Timer, USART).
Wenn man komplexere Programme schreibt, ist es fast nicht mehr möglich den Programm-Ablauf sequentiell zu gestalten, weshalb man irgendwann auf Interrupts zurückgreifen muss.
Implementiert man Interrupt-Routinen in den Programm-Code, und tritt bei der Ausführung des Codes ein Ereignis auf, das einen der vorher definierten Interrupts auslöst,
so wird das Hauptprogramm gestoppt, und die entsprechende  ISR ( Interrupt Service Routine) aufgerufen.
Erst nach ihrer Abarbeitung wird zurück in das Hauptprogramm gesprungen.
Die Interrupt Routine hat also eine höhere Priorität als das eigentliche Programm.

Es wird also bei einem externen Ereignis, das laufende Programm sofort unterbrochen egal wo sich das aktuell abgearbeitete Programm gerade befindet,
die Adresse in dem das Programm unterbrochen wird wird in einem Speicher den sogenannten Stack zwischengespeichert,
damit das Programm nach ausführen der Unterroutine anschließend wieder an der alten Stelle fortgeführt werden kann.
Ein Interrupt unterbricht also das laufende Programm sofort , und wartet nicht wie üblich bei z.B. einem Tastendruck,
bis die Programmschleife den Tastendruck gerade mal wieder abfragt.
Im normalen Einschaltzustand des Atmega sind erst einmal standardmäßig alle Interrupt deaktiviert.
Um sie also benutzen zu können, müssen sie erst einmal konfiguriert werden.

Atmega 8
Atmega 32
ISR (Interrupt Service Routinen) sollten  klein und übersichtlich sein, weshalb es zu vermeiden ist aufwendige Berechnung oder Schleifen darin auszuführen.
Packt man in eine ISR zum Beispiel Code, dessen Abarbeitung 1 Sekunde dauert, dann unterbricht auch das Hauptprogramm 1 Sekunde lang .
Außerdem sollte man es unterlassen, andere ISR in einer Interruptverarbeitung aufzurufen.
Die Möglichkeit, einen solchen Code zu schreiben besteht zwar, kann aber zu unerwünschten Nebeneffekten führen.
Während ein Interrupt ausgelöst wurde ist es nicht möglich einen weiteren Interrupt auszulösen , erst muss der ablaufende Interrupt abgeschlossen sein.
Wenn man Interrupts verwendet muss dem Prozessor dies explizit mitgeteilt werden, sonst werden sie nicht im Programm beachtet.
Externer Interrupt
Wenn man einen Interrupt durch einen der Pins INT0, INT1 oder INT2 auslösen will, also einen externen Interrupt, dann muss in der Initialisierung das entsprechende
Interrupt-Enable-Flag (Zeile 5 )gesetzt sein, und es muss festgelegt werden bei welcher Signaländerung am Pin (Zeile 4)der Interrupt ausgelöst werden soll.
Angenommen man hat einen Taster an INT0 angeschlossen, und will einen externen Interrupt auslösen, sobald der Taster gedrückt wird.
Dafür muss in GICR - (General Interrupt Control Register) - INT0 auf 1 gesetzt werden.
Beispiel
Zeile
Code
Beschreibung
1
On INT0 Routine1
Bei ausgelösten Externen Interrupt wird in die ISR mit der Bezeichnung Routine 1 gesprungen.
2
DDRD=&00000000
Interrupt Eingangspin Pd2 wird als Eingang definiert ( nicht zwingend)
3
PORTD=&B00000100
PullDown für Interupt Eingangspin wird gesetzt (Pin 4)
4
MCUCR=&B00000010
Interrupt Eingang reagiert auf Flanke von High nach Low
5
GICR=&B01000000
Interrupt einschalten
6
SREG.7=1
Interrupts Global einschalten
7
Hier kann sich das eigentliche Programm befinden
8
Routine1:
Hierhin wird bei einem ausgelösten Interrupt verzweigt
9
Test Programmcode
Dann der hier befindliche Code ausgeführt
10
Return
Mit Return wird zum Ursprung zurück gekehrt

Linke Tabelle zeigt ein Beispiel für einen Taster der am Pin 4 des Atmega 8 gegen Masse angeschlossen einen Interrupt
bei einen Wechsel von 1 nach 0 auslöst.
Also es wird der Tastendruck beim betätigen der Taste registriert,und nicht beim loslassen der Taste.
Nach erfassen des Interrupt Ereignis wird zur Zeile 8 gesprungen,von an an das Programm bis zur Zeile 10
abgearbeitet und dann wieder zurück dorthin wo das eigentliche Programm unterbrochen wurde.


Zeile
Beispiel
1
On INT0 Routine1
2
Config Portd.4=1
3
Portd.4=1
4
Config INT0 = FALLING
5
Enable Int0
6
Enable Global Interrupt
7
Hier kann sich das eigentliche Programm befinden
8
Routine1:
9
Test Programmcode
10
Return

Linke Tabelle zeigt ein Beispiel nur in Bascom Statment, das Ergebnis ist gleich mit der obere Tabelle.
MCUCR Register
Möglickeiten für Register MCUCR
MCUCR=&B00000000
INT0
solange L Pegel
MCUCR=&B00000001 INT0
bei Wechsel von H zu L oder L zu H
MCUCR=&B00000010 INT0
bei Wechsel von H zu L
MCUCR=&B00000011 INT0
bei Wechsel von L zu H
MCUCR=&B00000000 INT1
solange L Pegel
MCUCR=&B00000100 INT1
bei Wechsel von H zu L oder L zu H
MCUCR=&B00001000 INT1
bei Wechsel von H zu L
MCUCR=&B00001100 INT1
bei Wechsel von L zu H

Wird der Taster einmal gedrückt kommt es (wenn man ihn entprellt hat) auf jeden Fall zu 2 Zustandsänderungen -
also zwei Flankenwechseln.
Wann der Interrupt dann ausgelöst werden soll, wird im MCUCR - MCU Control Register festgelegt


GICR Register
Möglichkeiten für GICR
GICR=&B01000000
INT0 einschalten
GICR=&B10000000 INT1 einschalten
GICR=&B11000000
INT0 und INT1 einschalten

GICR = General Interrupt Control Register bei einigen Atmegas auch unter der Bezeichnung GIMSK zu finden ,
 hier können die Interrupts eingeschaltet und natürlich bei Bedarf auch ausgeschaltet werden.
Es ist auch möglich die Externen Interrupts über die Software intern zu steuern, dazu muss der INT Pin als Ausgang deklariert sein, dann kann man den Pin
über die Software auf High setzen mit Portd2=1 damit ist der Interrupt Flag gesetzt und wenn man ihn denn auswerten möchte wird er freigegeben
mit Enable Int0 und ausgewertet.

Sobald ein Interrupt ausgelöst wurde, werden alle andere möglichen Interrupts deaktiviert bis der erste beendet wurde.
Die anderen bis dahin eingetroffenen möglichen Interrupts gehen aber nicht verloren , sondern werden als Merker festgehalten
und anschließend in der zuvor eingetroffenen Reihenfolge nacheinander abgearbeitet.
Aktualisiert 11.03.2020
Copyright by MS 2009