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.
|