This is an old revision of the document!


Interrupts

Interrupts im AVR können durch Zähler, Kommunikations-Interfaces, Analog-zu-Digital Konverter, Komparator, spezielle Input-Output Pins und viele andere Funktionen, je nach Controller. Jeder Interrupt kann von der Einheit die ihn generiert, entweder erlaubt oder nicht erlaubt werden. Egal ob der Interrupt erlaubt oder nicht erlaubt ist, gibt es ein 1-Bit Feld (Interrupt Flag) in der dazugehörigen Einheit im Controller, welcher mit “true” markiert wird, wenn die Interrupt-Bedingung erfüllt ist. Wenn die Interrupt-Flag auf “true” geändert wird und der Interrupt erlaubt ist, dann wird der Controller den Code ausführen, der für den Interrupt gedacht ist.

Jeder Interrupt in dem AVR Microcontroller ist zu einem bestimmten Ereignis gebunden. Jedes Ereignis hat einen Flag-Bit im Status-Register, welcher das vorkommen des Ereignis markiert. Ereignisse sind auch an die Interrupt-Masken Register und die dazugehörigen Bits gebunden. Wenn das Interruptbit des Ereignisses unmaskiert ist und ein Ereigniss stattfindet, stoppt der Prozessor die Ausführung des laufenden Programms für einige Arbeitszyklen und führt das Interrupt-Programm aus. Nachdem das Interrupt-Programm ausgeführt wurde, fährt der Prozessor mit seinem pausierten Hauptprogramm fort.

Example

Um Interrupts mit der AVR LibC Bibliothek zu nutzen, ist es notwendig interrupt.h mit einzubinden. Der Code der ausgeführt wird, wenn der Interrupt stattfindet, wird nach einem “ISR”-Keyword geschrieben. Der Text zwischen den Klammern nach “ISR” ist der Name des Interrupts. Ein Beispiel in C-Sprache:

#include <avr/interrupt.h>
 
ISR(XXX_vect)
{
	// Do something
}

Das globale Erlauben aller Interrupts wird vom Control- und Statusregister SREG konfiguriert. Die Option um alle Interrupts auf einmal zu erlauben oder zu verbieten existiert um Daten zu schützen. Da Interrupts das Ausführen eines Programms unterbrechen, könnten einige Daten im Hauptprogramm dabei gestört oder korrumpiert werden. Solche Situationen können einfach vermieden werden, wenn man alle Interrupts verbietet, bevor man mit heiklen Daten arbeitet. Das generelle Verbieten von Interrupts ist einfach, da man einfach nur ein Register (SREG) ändern muss. Nachdem der kritische Teil des Programms ausgeführt wurde, können Interrupts einfach wieder erlaubt werden und alle Interrupts die ausgeführt worden wären, werden dann ausgeführt.

 

Example

Angenommen es ist eine 16-Bit Variable in Gebrauch in diesem Programm, welche sowohl von dem Hauptprogramm, als auch vom Interrupt geändert wird und er Wert dieser Variable später einer anderen Variable gegeben wird.

#include <avr/interrupt.h>
 
// Globale 16-Bit Variable x und y
unsigned short x, y;
 
// Ein zufälliger Interrupt der den Wert von x ändert.
ISR(XXX_vect)
{
	x = 0x3333;
}
 
int main()
{
	// Gibt x einen Wert
	x = 0x1111;
 
	// Erlaubt Interrupts global
	sei();
 
	// Gibt y den Wert von x
	y = x;	
}

Das Programm ist sehr einfach - zuerst bekommt die Variable x den Wert 0x1111 und später wird der Wert an y weitergegeben. Wenn ein Interrupt zwischen beiden Operationen vorkommt, bekommt x einen Wert von 0x3333. Logisch gesehen kann y somit zwei mögliche Werte am Ende des Programms haben, aber bei einem 8-Bit AVR gibt es noch eine dritte Möglichkeit. Diese entsteht, weil die 8-Bit Architektur 2 Taktzyklen brauch um 16-Bit Daten zu verarbeiten, daher kann durch schlechtes Timing ein Interrupt die Integrität dieser Daten korrumpieren. Dadurch kann y am Ende des Programms 0x1111 oder 0x3333, aber auch 0x3311 als Wert haben Um den dritten und ungewollten Wert zu verhindern, sollten alle Interrupts temporär verboten werden wenn eine Operation mehr als ein Taktzyklus braucht.

Im folgenden Beispiel wird eine sichere Methode benutzt um y den Wert von x zu geben:

	// Verbietet global alle Interrupts
	cli();
 
	// Gibt y den Wert von x
	y = x;
 
	// Erlaubt alle Interrupts wieder
	sei();
de/avr/interrupts.1287136164.txt.gz · Last modified: 2020/07/20 09:00 (external edit)
CC Attribution-Share Alike 4.0 International
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0