Externen Interrupt benutzen



Manchmal soll der "normale" Ablauf eines Programmes unterbrochen werden, um irgendwas anderes zu tun.
Und manchmal soll diese Unterbrechung auch sofort bzw. ohne bemerkbare Zeitverzögerung geschehen.


Beispiel:

Ein kleiner auf Rädern fahrender Roboter erkennt vor sich ein Hindernis.

Seine Vor-mir-ist-ein-Hindernis-Routine setzt sich in Gang: Anhalten, 20cm rückwärts fahren, ein Stück nach links drehen und dann wieder Vorwärts bis ein Hindernis kommt. Nun gut. Vielleicht soll Dein Roboter aber noch mehr können als nur diese Routine abzuarbeiten. Vielleicht soll er ja ruckartig stehen bleiben, wenn jemand das Licht im Zimmer ausschaltet. Oder er soll ruckartig stehen bleiben, wenn jemand pfeift.

Hier bietet sich das Arbeiten mit externen Interrupts an.

Auf unserem Experimentierboard 2 ist der externe Interrupt INT0 als Anschluß (im Bild oben rechts) auf einen Stecklötstift (oder was auch immer Du dahin gelötet hast) nach außen geführt.

 


Unser Beispielprogramm macht folgendes:

  • Ein 10-Kanal-Lauflicht läuft und läuft und läuft ( while-Schleife in der main-Funktion) bis Du INT0 mit GND verbindest. Dann hält das Lauflicht ruckartig an und es wird die Interrupt-Service-Routine abgearbeitet - es blinkt LED1.

  • Wird von INT0 das GND-Signal wieder weggenommen, setzt unser Lauflicht sein Laufen an der unterbrochenen Stelle fort.


Schau Dir den Code an:

//********************************************************************

#include <avr/io.h>
#include <avr/interrupt.h>

#define F_CPU 1000000UL      // 1 MHz
#include <util/delay.h>

#include "leds.h"


//********************************************************************

// Interruptserviceroutine

ISR (INT0_vect) {

    led1on; _delay_ms(100); led1off;_delay_ms(100);


//********************************************************************

int main(void){
   
    DDRB = 193; DDRD = 251;            //Aus- und Eingänge festlegen
    PORTD |= _BV(PD2);                 //Pull Up an PD2 = INT0 aktivieren
    GICR |=(1<<INT0);                  //Ext. Interrupt an INT0
    MCUCR |=(0<<ISC01) | (0<<ISC00);   //Interrupt, wenn INT0 = GND
    sei();                             //Interrupts erlauben
   
   
    while(1){
         
        led1on; _delay_ms(100); led1off;
        led2on; _delay_ms(100); led2off;
        led3on; _delay_ms(100); led3off;
        led4on; _delay_ms(100); led4off;
        led5on; _delay_ms(100); led5off;
        led6on; _delay_ms(100); led6off;
        led7on; _delay_ms(100); led7off;
        led8on; _delay_ms(100); led8off;
        led9on; _delay_ms(100); led9off;
        led10on; _delay_ms(100); led10off;
       
    }
 

    return 0;
}
//********************************************************************

Hier gibt's den Code-Ordner zum Runterladen.



Anmerkungen:

  • ISR steht für Interrupt Service Routine. Hier springt die Abarbeitung des Programmes hin, wenn der Interrupt ausgelöst wurde.

  • Mehr zu Interrupts findest Du auf der Mikrocontrollerspielwiese hier.

  • Näheres wie immer im Datenblatt.