Interrupt



Folgendes Problem war zu lösen: 

Nur eine Taste soll das Blinken (SOS-Morse-Signal) der LED13 einschalten und auch wieder ausschalten können.

Also:

  • Taste kurz drücken: es wird SOS "gefunkt"

  • Taste nochmals kurz drücken: SOS wird zuende "gefunkt". Danach bleibt die LED aus.

  • ... von vorn





Interrupt:

Interrupt bedeutet Unterbrechung.
Unterbrochen wird der normale Programmablauf.

Wozu ist das nützlich?

Die folgenden zwei Beispiele sollen Dir das erläutern:


Beispiel 1


Ein Tastendruck von einer Taste, die an einem Interrupteingang des Mikrocontrollers angeschlossen ist, soll ein laufendes Programm sofort unterbrechen. 

Dann realisiert man das am besten mit einem externen Interrupt.

Beachte den Unterschied:

  • eine Taste an einem normalen digitalen Eingang des Mikrocontrollers wird immer erst dann abgefragt, wenn der Programmablauf gerade an der Tastenabfrage "vorbeikommt"

  • eine Taste an einem Interrupteingang des Mikrocontrollers unterbricht sofort den Programmablauf.


Beispiel 2


Im Hauptprogramm macht der Mikrocontroller etwas zeitunabhängiges - z. B. steuert er einen kleinen Roboter, der fröhlich im Zimmmer herumfährt und Hindernissen ausweicht. Exakt jede Minute soll er aber "Piep" sagen, und dabei ist es völlig egal, womit er gerade beschäftigt ist. Seine "normale" Tätigkeit wird unterbrochen und er sagt pünktlich "Piep".

Schau Dir folgenden Pseudocode an:

setup-funktion {
    irgendwas einstellen;
}

loop-funktion {
    fahre ewig herum und weiche Hindernissen aus;
}

interrupt-funktion(exakt jede Minute) {
    sage "Piep";
}

Stell Dir einfach zwei kleine Männchen im Gehirn dieses Roboters vor:

  • Der Fahrer fährt mit dem Roboter, wie mit einem Auto herum und passt darauf auf, nirgends anzustoßen.
    Er sitzt am Lenkrad, betätigt Gas, Kupplung und Bremse und hält Ausschau nach Hindernissen.

  • Exakt jede Minute hält ihm sein Beifahrer die Augen zu, schiebt ihm vom Lenkrad weg und hupt!
    Egal, was der Fahrer gerade tut, der Beifahrer unterbricht ihn einfach dabei.

Für solcherart Interrupts (exakt jede Minute) kann man einen im Mikrocontroller vorhandenen Timer benutzen. Das wäre ein Timerinterrupt.



Schaltung für unser Problem:



Der 10k-Widerstand sorgt dafür, dass 5V am Interrupt-Eingang anliegen wenn die Taste ungedrückt ist.
Er ist ein sog. Pull-Up-Widerstand.




Code für unser Problem:

      
int kurz = 250;
int lang = 800;

volatile int status = LOW; // blinken oder nicht
 
void setup()
{
  pinMode(13, OUTPUT); // Board-LED
  attachInterrupt(1, tastenBetaetigung, FALLING); // Interrupt 1 liegt an Pin 3
}
 

void loop () {

  if (status==HIGH){
  
    s();
    o(); 
    s();
    delay(lang); delay(lang);
  }
   
   
}

// Die folgende Interrupt Service Routine wird 
// bei jeder Buttonbetätigung aufgerufen
void tastenBetaetigung() {
  status = !status; // Status umkehren
}



void s(){
  did(); did(); did(); delay(kurz);
}

void o(){
  da(); da(); da(); delay(kurz);
}


void did(){
  digitalWrite(13, HIGH); delay(kurz);
  digitalWrite(13, LOW);  delay(kurz);
}

void da(){
  digitalWrite(13, HIGH); delay(lang);
  digitalWrite(13, LOW);  delay(kurz);
}


      
      

Untersuchen wir einmal ein paar Zeilen:

attachInterrupt(1, tastenBetaetigung, FALLING);

1: Der Interrupt 1 wird benutzt werden (er liegt am Pin 3).

tastenBetaetigung: Das ist der Name der Funktion, die bei dem Interrupt ausgeführt wird.

FALLING: Auf Deutsch: "FALLEND" - wenn am Interrupt-Eingang der Zustand von HIGH zu LOW wechselt.


status = !status; // Status umkehren

!: Das Ausrufezeichen ist ein logischer Operator. Er macht aus einem HIGH ein LOW und umgekehrt.
   Diesen Vorgang nennt man Negieren oder Invertieren.






  • Eine Simulation dieses Experimentes findest Du hier.

  • Ein ähnliches Experiment -aber ohne Interrupt- findest Du hier.