Mit Hilfe der externen Interrupts INT0 und INT1 kann ein Interrupt bei einer positiven und/oder negativen Pegeländerung an dem zugehörigen Eingangspin erfolgt. Interrupt INT0 ist mit Pin PD2 (digital Pin 2) und INT1 mit Pin PD3 (digital Pin 3) verknüpft. Damit kann beispielweise ein Interrupt ausgelöst werden, wenn ein angeschlossener Taster betätigt wird.

Überlicherweise ist der jeweilige Pin als Eingang zu deklarieren. Die Interrupts INT0 und INT1 lösen aber auch aus, wenn der PIN als Ausgang deklariert wurde. Somit sind auch durch Software erzeugte Interrupts möglich.

Das External Interrupt Control Register A (EICRA)

Bit 7

Bit 6

Bit 5

Bit 4

Bit 3

Bit 2

Bit 1

Bit 0

 

 

 

 

ISC11

ISC10

ISC01

ISC00

 

 

 

 

für INT1

für INT0

 

Über das External Interrupt Control Register A wird gesteuert, bei welchen Flanken oder Zuständen an den verknüpften Eingangspins ein Interrupt angefordert wird.

INT1 oder INT0

ISCX1

ISCX0

Status für Interrupt

0

0

LOW

0

1

jede Flanke

1

0

fallende Flanke

1

1

steigende Flanke

 

External Interrupt Mask Register (EIMSK)

Bit 7

Bit 6

Bit 5

Bit 4

Bit 3

Bit 2

Bit 1

Bit 0

 

 

 

 

 

 

INT1

INT0

 

 

 

 

 

 

External Interrupt Request 1 Enable

External Interrupt Request 0 Enable

 

In dem External Interrupt Mask Register werden die externen Interrupts (de)aktiviert. Die Interrupts sind aktiviert, wenn das Bit gesetzt ist, und deaktiviert, wenn das Bit gelöscht ist.

 

External Interrupt Flag Register (EIFR)

Bit 7

Bit 6

Bit 5

Bit 4

Bit 3

Bit 2

Bit 1

Bit 0

 

 

 

 

 

 

INTF1

INTF0

 

 

 

 

 

 

External Interrupt Flag 1

External Interrupt Flag 0

 

In dem External Interrupt Flag Register werden die Interrupt-Anforderungen gespeichert. Wenn ein Interrupt durch den Mikrocontroller auf Grund der konfigurierten Flanke am INT0/1-Eingangspin angefordert wird, wird das jeweilige Flag gesetzt. Wenn das Statusbit I ebenfalls gesetzt ist, dann springt das Programm in die jeweilige ISR. Am Ende der ISR wird das Flag automatisch zurückgesetzt.

In den meisten Fällen ist ein Eingreifen in dieses Register durch den Programmierer nicht notwendig. Es kann hier abgefragt werden, ob bereits ein Interrupt auslösendes Ereignis angefallen ist (und noch nicht in die ISR gesprungen wurde - sonst wäre es bereits gelöscht worden).  Bei Bedarf kann das Flag manuell gelöscht werden, und zwar durch Schreiben einer Eins in das Bit.


Programmbeispiel externe Interrupts:

Das folgende Programmbeispiel soll die Verwendung der externen Interrupts verdeutlichen:

Ziel des Programms ist es, eine grüne LED dauerhaft blinken zu lassen und parallel dazu noch LEDs über einen Taster zu schalten. Dies wird mithilfe der externen Interrupt Pins des Microcontrollers realisiert. Die zugehörige Schaltung sieht wie folgt aus:



Abb.: Schaltung zum Beispiel Externe Interrupts; Quelle: BBS2 Wolfsburg

Der Programmcode sieht wie folgt aus:

#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>	
#define LED1 7	
#define LED2 6 
#define LED3 5
#define BUT1 2	// INT0 
#define BUT2 3	// INT1

int main(void)
{
	DDRD |= (1 << LED1) | (1 << LED2) | (1<<LED3); //Ausgänge
	PORTD = (1<<BUT1) | (1<<BUT2); // Pull-Up Widerstände
	
	//Folgender Programmcode funktioniert aufgrund des Delays nicht! Die IF Anweisung wird nur alle 2 Sekunden ausgeführt
	
	/* while (1) 
    {
		PORTD |= (1<<LED1);
		_delay_ms(1000);
		PORTD &= ~(1<<LED1);
		_delay_ms(1000);
		
		if (!(PINB & (1<<BUT)))
		{
			PORTD |= (1<<LED2);
		}
		else
		{
			PORTD &= ~(1<<LED2);
		}
	}
}*/
    // Realisierung mit Externen Interrupts:
	
   EICRA = (1<<ISC11) | (1<<ISC10) | (1<<ISC01) | (1<<ISC00);	// Interrupts werden bei steigender Flanke ausgelöst (siehe EICRA Register im Datenblatt) 
   EIMSK = (1<<INT0) | (1<<INT1);								// Interrupts setzen
   sei();
   
   while(1)
   {
	   //Standard Blinkprogramm:
	   PORTD |= (1<<LED2);
	   _delay_ms(1000);
	   PORTD &= ~(1<<LED2);
	   _delay_ms(1000);		
   }
}

ISR(INT0_vect) //BUT1
{
	if(!(PINB & (1<<BUT1))) //Tasterbetätigung BUT1
	{
		PORTD ^= (1<<LED1);
	}
}

ISR(INT1_vect) //BUT2 analog zu BUT1
{
	if(!(PINB & (1<<BUT2))) //Tasterbetätigung BUT2
	{
		PORTD ^= (1<<LED3);
	}
}

Zuletzt geändert: Montag, 21. Februar 2022, 08:59