2.4 Interrupts

2.4.1 Allgemeines

Interrupts sind Unterbrechungen des normalen Programmablaufs, die durch externe Ereignisse ausgelöst werden. Sie ermöglichen es, auf Ereignisse zu reagieren, ohne ständig auf sie prüfen zu müssen (Vergleich polling). Ein Interrupt kann allgemein durch Hardware oder Software ausgelöst werden. Hardware-Interrupts werden durch externe Ereignisse wie z.B. Tastendrücke, Überlauf eines Zählers, Empfang eines Zeichens über eine Schnittstelle etc. ausgelöst. Software-Interrupts werden durch spezielle Befehle im Programmcode ausgelöst. Der Mikrocontroller kann auf einen Interrupt reagieren, indem er den normalen Programmablauf unterbricht und eine spezielle Interrupt-Service-Routine (ISR) ausführt. Nachdem die ISR abgearbeitet wurde, wird der normale Programmablauf fortgesetzt.

2.4.2 Nested Interrupts

Nested Interrupts (dt: verschachtelte Interrupts) treten auf, wenn während der Abarbeitung einer ISR ein weiterer Interrupt auftritt. In diesem Fall wird der zweite Interrupt erst nach Beendigung der ersten ISR abgearbeitet.

2.4.3 Implementierung beim ATmega16

Interruptquellen

Der ATmega16 verfügt über 21 verschiedene Interruptquellen:

Priorität

Dabei ist die Reihung der Interruptquellen in der Tabelle gleichzeitig auch die Priorität der Interrupts. Für den ATmega16 bedeutet das, dass ein Interrupt mit einer niedrigeren Nummer einen höheren Rang hat als ein Interrupt mit einer höheren Nummer.

Global Interrupt Enable

Der ATmega16 verfügt über ein Statusregister (SREG), in dem sich u.a. das I-Bit (Interrupt Enable) befindet. Dieses Bit wird verwendet, um die Interrupts global zu aktivieren oder zu deaktivieren. Wird das I-Bit auf 0 gesetzt, so sind alle Interrupts deaktiviert. Wird es auf 1 gesetzt, so sind alle Interrupts aktiviert.

Die Aktivierung und Deaktivierung der globalen Interrupts erfolgt durch die Befehle sei(); (Set Enable Interrupt) und cli(); (Clear Interrupt).

Externer Interrupt INT0/INT1

Bei den Interruptquellen INT0 und INT1 handelt es sich um externe Interrupts, die durch Pegelwechsel am entsprechenden Pin ausgelöst werden. Der ATmega16 verfügt über zwei externe Interruptpins, die auf die Pins PD2 (INT0) und PD3 (INT1) gelegt sind. Es gibt auch INT2, welcher sich auf den Pin PB2 befindet, jedoch wird dieser hier nicht weiter behandelt.

Das Verhalten der Interrupts kann durch die Bits ISC01 und ISC00 (INT0) bzw. ISC11 und ISC10 (INT1) im MCUCR-Register (MCU Control Register) eingestellt werden:

MCUCR

Aktiviert kann der externe Interrupt durch Setzen des entsprechenden Bits im GICR-Register (General Interrupt Control Register) werden (Achtung: nicht zu verwechseln mit dem SREG-Register!):

GICR

Durch Setzen der Bits gemäß nachfolgender Tabelle wird festgelegt, wodurch der Interrupt ausgelöst wird (die Tabellen sind inhaltlich für INT0 und INT1 identisch, dargestellt ist nur INT0):

ISC01 bzw. ISC11 ISC00 bzw. ISC10 Beschreibung
0 0 Low Level
0 1 Any Logical Change
1 0 Falling Edge
1 1 Rising Edge

Beispiel

Es soll ein Programm erstellt werden, das auf eine fallende Flanke an PD2 reagiert. Dazu wird der externe Interrupt INT0 verwendet. Das Programm soll beim Erkennen der fallenden Flanke an PD2 die LED7 für 200 ms einschalten.