05 Sep

Interrupts für Anfänger in C

In manchen Fällen muss das Programm wegen eines Ereignisses unterbrochen werden. Davor wurde die Interuptsteuerung eingeführt. Hiermit können unvorhersehbare, äußere Ereignisse erfasst werden und sofort verarbeitet. Dafür wird das Hauptprogramm kurzzeitig unterbrochen und der Interupt-Befehl ausgeführt. Danach läuft das Hauptprogramm wieder weiter.
In diesem Artikel behandele ich folgende Themenfelder:

  • Polling vs. Interrupt
  • Funktionen der Interrupts (ATmega)
  • Implementierung eines Interrupt (ATmega)
  • Interrupt-Indexierung bei ATmega
  • Pegel und Flankensteuerung (kommt noch…)
  • Interruptsteuerung eines Kaffeautomaten (kommt noch…)

Beim Polling wird im Programmcode der Zustand des Ergebnisses immer und immer wieder erneut abgefragt.  Hier wird synchron zum Code gearbeitet. Dieses Verfahren benötigt Speicher und Rechenleistung . Jedes mal wird erneut abgefragt, ob der Zustand nun  – endlich – eingetroffen ist. Auch bei einem negativen Ergebnis der Abfrage wird Rechenleistung für die Abfrage benötigt. Bei hoher Taktung der Abfrage wird das Programm unnötig verlangsamt. Allerdings können Fehler bei direkter Implementierung schneller gefunden werden.

Ein Interupt hingegen arbeitet asynchron zum Programmcode. Hier wird ein Nebenläufiger Prozess implementiert, welcher bei negativer Abfrage keine Rechenleistung verbraucht. Denn der Interupt wird,sobald der gewollte Zustand positiv ist, „angestoßen“ und führt den vorgesehenen Programmcode aus. Hierfür wird das Programm direkt vor dem nächsten Maschinenbefehl pausiert, die Register zwischengespeichert und nach dem Interrupt wieder fortgesetzt. Durch diesen „ruckhaften“ Eingriff ist die Fehleranalyse sehr viel aufwendiger.
Sie sehen: bei korrekter Implementierung ist ein Interupt komfortabler und genauer.

Funktionen der Interrupts (ATmega)

Ein Interrupt ist ein vordefinierter Vorfall. Er kann nicht verändert werden. Allerdings gibt die Tabelle eine reichliche Auswahl:

AdresseBezeichnungBeschreibung
0x000RESETReset
0x001INT0Externer Interrupt 0
0x002INT1Externer Interrupt 1
0x030TIMER2_COMPTimer Compare Match
0x004TIMER2_OVFTimer Overflow
0x0005TIMER1_CAPTTimer Capture Event
0x006TIMER1_COMPATimer Compare
0x007TIMER1_COMPBTimer Compare
0x008TIMER1_OVFTimer Overflow
0x009TIMER0_OVFTimer Overflow
0x00ASPI_STCSPI-Übertragung abgeschlossen
0x00BUSART_RXUSART-Empfang abgeschlossen
0x00CUSART_UDREUSART-Datenregister leer
0x00DUSART_TXUSART-Sendung abgeschlossen
0x00EADCAD-Wandlung abgeschlossen
0x00FEE_RDYEEPROM bereit
0x010ANA_COMPAnalogkomparator
0x011TWITwo-Wire Interface
0x012SPM_RDYStore Program Memory Ready

Implementierung eines Interrupt (ATmega)

Schritt 1: die IQR-Anweisung

Bei Eintritt des Interrupt wird das Hauptprogramm beendet und die Interrupt-Service-Routine wird aufgerufen. Diese wird zunächst geschrieben:

 

In der wird zunächst eine Hilfsmethode zur Initialisierung aufgerufen. Danach wird durch „sei()“ die Verwendung der Interrupts freigeschaltet. Mit cli() können die Interrupts wiederum ausgeschaltet werden. Mittels cli()…sei() Konstruktionen können somit bestimmte Programmbereiche von den Interrupts befreit werden. Interrupts, welche im Laufe der sperre Auftreten werden nach dem Schlüsselwort sei() bearbeitet. Eine systemgegebene Priorisierung liegt vor.

Schritt 2: Initialisierung des Interrupts

In einer Hilfsmethode (oder in der main) wird die Interuptsteuerung initialisiert. Die Indexierung hängt von dem jeweiligen Interrupt ab (siehe Indexierung).

 

Schritt 3: Problembehebung 

Bei vielen Anwendungen (zB: Kaffeeautomat) wird nur auf ein außerordentliches Ereignis gewartet. In der Zwischenzeit wird keine Rechenleistung benötigt. Der Mikrocontroller kann in den Stromsparmodus gehen. 

!Achtung! Interrupts unterbrechen ein Programm an einer x-beliebigen Stelle. Dies kann zu Problemen führen:
Lost-WakeUp

Das Programm erwacht nach dem Energiesparmodus nicht mehr. Die Befehle sei(), cli() und sleep() werden atomar ausgeführt. Das heißt die Befehle werden in einem Maschinenschritt verarbeitet. Dadurch kann das Lost-WakeUp Problem behoben werden. So kann dann eine Wait-Funktion aussehen:

Für eine erfolgreiche Synchronisation mittels Interrupts sollten folgende Punkte beachtet werden:

  • Verwende im Interrupt nur volatile-Variablen !
  • Die Fehler-Anomalien werden durch Testen des Programmes nicht auffallen. Das Programm sollte vor Verwendung nochmals durchdacht werden.
  • Interrupts können bei langen Interruptsperren verloren gehen.

Interrupt-Indexierung bei ATmega

Über die Steuerregister EIMSK und EICRA werden die Interupts INT0 und INT1 geschalten.

ISC11ISC10Beschreibung
00niedriger Pegel generiert Interrupt
01jede digitale Pegel-Veränderung generiert ein Interrupt
10fallende Flanke generiert ein Interrupt
11steigende Flanke generiert ein Interrupt

 

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.