Interrupts

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

Jeder Interrupt des AVR Microcontrollers ist an ein bestimmtes Ereignis gebunden. Jedes Ereignis hat einen Flag-Bit im Status-Register, welcher den Eintritt des Ereignisses markiert. Ereignisse sind ebenfalls an die Register der Interrupt-Masken sowie die dazugehörigen Bits gebunden. Wenn das Interrupt-Bit 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 einzubinden. Der Code der ausgeführt wird, wenn der Interrupt stattfindet, wird nach einem „ISR“-Keyword geschrieben. Der Text innerhalb der Klammern nach „ISR“ kennzeichnet den Namen des Interrupts. Ein Beispiel in C:

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

Die generelle Erlaubnis sämtlicher Interrupts wird vom Control- und Statusregister SREG konfiguriert. Die Option, alle Interrupts sofort zu erlauben oder zu verbieten existiert zum Schutz von Daten. Da Interrupts das Ausführen eines Programms unterbrechen, könnten einige Daten im Hauptprogramm dabei zerstört oder beschädigt werden. Solche Situationen können einfach vermieden werden, wenn man alle Interrupts verbietet, bevor man mit empfindlichen Daten arbeitet. Das generelle Verbot von Interrupts ist einfach, da hierzu lediglich ein Register (SREG) geändert werden muss. Nachdem der kritische Teil des Programms ausgeführt wurde, können Interrupts einfach wieder zugelassen werden wodurch dann sämtliche Interrupts die zurückgehalten wurden, ausgeführt werden.

 

Example

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

#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()
{
	// x einen Wert geben
	x = 0x1111;
 
	// Interrupts generell erlauben
	sei();
 
	// y erhält Wert von x
	y = x;	
}

Das Programm selbst ist sehr einfach - zuerst bekommt die Variable x den Wert 0x1111 und später wird dieser an y weitergegeben. Wenn ein Interrupt zwischen diesen beiden Operationen auftritt, bekommt x einen Wert von 0x3333. Logisch gesehen kann y somit zwei mögliche Werte am Ende des Programms haben, allerdings existiert bei einem 8-Bit AVR noch eine dritte Möglichkeit. Hierzu kommt es, da die 8-Bit Architektur zur Verarbeitung von 16-Bit Daten 2 Taktzyklen braucht. Daher kann ein Interrupt durch schlechtes Timing die Integrität dieser Daten beschädigen. Dadurch kann y am Ende des Programms den Wert 0x1111 oder 0x3333, aber auch 0x3311 haben Um den dritten und ungewollten Wert zu verhindern, sollten alle Interrupts temporär verboten werden wenn eine Operation mehr als einen Taktzyklus umfasst.

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

	// Interrupts generell verbieten
	cli();
 
	// y erhält Wert von x
	y = x;
 
	// Sämtliche Interrupts wieder zulassen
	sei();
de/avr/interrupts.txt · Last modified: 2020/07/20 09:00 by 127.0.0.1
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