1. Folgende zusätzliche Includeanweisung muss der Programmcode haben:
    #include <avr/interrupt.h>
  2. Globale Variablen werden als "volatile" (flüchtig) angelegt,
    so dass auf sie auch in der ISR zugegriffen werden kann.

  3. In der main()-Funktion sollte dann der jeweilige Interrupt konfiguriert werden. Für einen Timerinterrupt muss der Timer konfiguriert werden (siehe Kapitel TIMER), für einen externen Interrupt muss dieser ebenso konfiguriert werden (siehe nachfolgende Abschnitte)
  4. Aktivierung des einzelnen Interrupts über das jeweilige Interrupt Control Register
  5. Globale Aktivierung der Interrupts durch sei();
  6. Schreiben des im Interrupt-Fall auszuführenden Codes:
    ISR(auslösender Vektor)
    {
       //Programmcode
    }

So sollte dann z.B. der Programmcode aussehen:

#include <avr/io.h>
#define F_CPU 16000000UL
#include <util/delay.h>
#include <avr/interrupt.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
volatile int zaehler;


ISR(INT1_vect)
{
	zaehler++;
}


int main(void)
{
	DDRB |= (1<<2) | (1<<1);
	DDRD &= ~(1<<3);
	DDRD |= (1 << 7) | (1 << 6) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0);
	
	PORTD |= (1<<PORTD3);
	
	EICRA |= (1<<ISC11) | (1<<ISC10);
	EIMSK |= (1<<INT1);
	sei();
	
	int i = 0;
	
	
	while (1)
	{
		void zeigeZaeler();
	}
	
	void zeigeZaeler()
	{
		switch(zaehler)
		{
			case 0:
			PORTD = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 4) | (1 << 5) | (1 << 7)   | ( 1<< 3) ;
			break;
			case 1:
			PORTD = (1 << 1) | (1 << 2)     | ( 1<< 3);
			break;
			case 2:
			PORTD = (1 << 0) | (1 << 1)  | (1 << 4) | (1 << 5) | (1 << 6)     | ( 1<< 3);
			break;
			case 3:
			PORTD = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 4)  | (1 << 6)      | ( 1<< 3);
			break;
			case 4:
			PORTD = (1 << 1) | (1 << 2)   | (1 << 7) | ( 1 << 6)   | ( 1<< 3);
			break;
			case 5:
			PORTD = (1 << 0)  | (1 << 2) | (1 << 4) | (1 << 7) | ( 1 << 6)    | ( 1<< 3);
			break;
			case 6:
			PORTD = (1 << 0)  | (1 << 2) | (1 << 4) | (1 << 5) | (1 << 7) | ( 1 << 6)    | ( 1<< 3);
			break;
			case 7:
			PORTD = (1 << 0) | (1 << 1) | (1 << 2)     | ( 1<< 3);
			break;
			case 8:
			PORTD = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 4) | (1 << 5) | (1 << 7) | ( 1 << 6)     | ( 1<< 3);
			break;
			case 9:
			PORTD = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 4)  | (1 << 7) | ( 1 << 6)    | ( 1<< 3) ;
			break;
			default:
			zaehler = 0;
			break;
		}
	}

In dem Programmbeispiel wird die Variable "zaehler" bei jeder Tasterbetätigung um 1 hochgezählt. In der vom Hauptprogramm aus aufgerufenen Funktion "zeigeZaehler" wird der Zählerstand auf einer 7-Segment-Anzeige ausgegeben, bis der maximale Zählerstand von 9 erreicht ist.

Bei der Ausführung des Programms auf dem Controller wird in den meisten Fällen deutlich werden, dass der Taster noch nicht entprellt ist. Denn beim einmaligen Drücken steigt der Zählerwert um mehr als 1. Dies kommt daher, dass der Zähler auf die steigende Flanke des Taster reagiert, welche trotz einmaliger Betätigung des Tasters mehrmals erzeugt wird.

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