PINCHANGE Interrupt Example
 * ein Zähler zählt das obere Nibble von PORTB laufend hoch (0,1...13,14,15,0,1,...)
 * Bei Tastendruck PC0 wird ein Interrupt ausgelöst, der den Startwert 
 * des Zählers neu setzt. Dieser Startwert liegt am unteren Nibble von PORTB an. 

Interruptsystem AVR (ATMEL328p)

Table of Contents

Interruptsystem AVR (ATMEL328p)

Voraussetzungen, dass ein Interrupt ausgelöst wird:

Steuer-Register

Stack

Das Interrupt-System

Interrupt Vector Table (IVT)

Der Request

Externe Interrupts INT0, INT1

Pin Change Interrupt

Software-Interrupt

Programmierung

Arduino

Beispiele

Bsp1

LIBC

Anhang

Interrupt Vector Table

 

Interrupt = automatische Unterbrechung eines laufenden Programmes durch ein Gerät und Fortsetzung nachdem eine Interrupt-Behandlungs-Routine (ISR) abgearbeitet wurde, ohne dass das Hauptprogramm etwas davon merkt. Man kann allerdings über globale Variablen dem Hauptprogramm Informationen schicken.

Die ISR steht auf einer fest eingebauten Adresse (= Interrupt Vector Address) am Beginn des Programmspeichers.

Voraussetzungen, dass ein Interrupt ausgelöst wird:

1. Anfrage (Interrupt Request)

2. Erlaubnis (Interrupt Enable)

3. Priorität (interrupt Prio entweder über einen Controller konfigurierbar oder fix eingebaut)

4. Interruptsystem einschalten (sei(); //set interrupt flag   )

 

Steuer-Register

am Beispiel eines externen Interrupts der durch eine Flanke am Pin PD2 des Prozessors ausgelöst wird:

Anfrage: FLAG Register (EIFR  external int flag reg)

Erlaubnis: MASK Register (EIMSK  ext int mask reg)

Priorität: eingebaut, kein Steuer-Register; je kleiner die Einsprung-Adresse, desto höher die Priorität

Interrupt-System einschalten:  SREG Register (status reg) enthält das I-Flag, wenn es gesetzt ist sind alle Interrupts aktiviert

 

Stack

Der Stack ist ein logischer Speicher der am oberen Ende des internen SRAM angelegt wird. Er wird durch den Stack-Pointer verwaltet.

Der Stack-Pointer zeigt immer an das obere Ende des Stapels wo die nächsten Daten abgelegt bzw. geholt werden können. Nach dem Schreiben auf den Stapel wird die Adresse automatisch weitergestellt, so dass durch aufeinander folgende PUSH Befehle sehr einfach und schnell Daten auf den Stack gelegt werden können. Ein POP Befehl liest die Daten dann in umgekehrter Reihenfolge wieder aus.

Beim Programmstart muss der Stack-Pointer softwaremäßig auf das Speicherende gestellt werden (macht der C-Compiler automatisch).

Das Interrupt-System

C-Compiler

Der C-Compiler übernimmt das Retten der Register des Hauptprogramms

Interrupt Vector Table (IVT)

Der Request

  1. Trigger durch Request-Flag

  1. Trigger ohne Request Flag
    solange die Interrupt-Bedingung erfüllt ist, bleibt die Anfrage, verschwindet der Request vor einem Enable, dann wird kein Interrupt ausgelöst

    z.B: level triggered external interrupt (EICRA: ISC01/ISC00=0/0 The low level Interrupt)

Externe Interrupts INT0, INT1

Pin Change Interrupt

Software-Interrupt

 

Programmierung

Arduino

Eine leere Arduino Anwendung verwendet bereits das Interrupt-System!

 

Achtung! Innerhalb einer Int-Service-Routine funktionieren delay(), micros() und millis() nicht richtig, da diese Funktionen interrupt-basiert sind.

delayMicroseconds() benutzt keine Zähler und wird deshalb normal funktionieren.

 

Beispiele

Bsp1

#include <Arduino.h>

void loop(void );

void isr_INT0();

 

volatile uint8_t num_of_interrupts;

 

void loop(void)

{ setup();

  sei();

  while(1)

  {

    Serial.println(num_of_interrupts, DEC);

    delay(1000);

  }

}

 

void isr_INT0(){

  if (digitalRead(13)==HIGH)

     digitalWrite(13,LOW);

else digitalWrite(13,HIGH);

  num_of_interrupts++;

}

 

void setup(){

  Serial.begin(57600);

  pinMode(13,OUTPUT);

  pinMode(2,INPUT_PULLUP);

  attachInterrupt(digitalPinToInterrupt(INT0),isr_INT0,FALLING); //PIN 2

}

 

 

"Volatile" verhindert, dass die Variable beim Compilieren wegoptimiert wird; dies kann man überprüfen, wenn man das Schlüsselwort volatile entfernt und in der Perspektive "release" compiliert. Man kriegt keine Fehlermeldung, aber die Zählfunktion funktioniert nicht.

 

LIBC

Es wird ein Arduino-Projekt angelegt, um die Lib HardwareSerial zur Verfügung zu haben.

 

#include <avr/io.h>

#include <avr/interrupt.h>

#include <HardwareSerial.h>

#include <util/delay.h>   

 

void setup();

 

uint8_t num_of_interrupts;

 

int main(void)

{

setup();

sei();

while(1)

{

Serial.println(num_of_interrupts, DEC);

//_delay_ms(1000);

}

}

 

ISR(INT0_vect){

num_of_interrupts++;

}

 

void setup(){

Serial.begin(57600);

EIMSK |= _BV(INT0);  //enable

EICRA |= _BV(ISC01); //falling edge

}

 

ISR(BADISR_vect)  … wenn keine ISR vorhanden, dann springe hierher

 

ISR_NAKED  … die Kontrolle über die ISR in der eigenen Hand (SREG und RETI())

 

ISR(INT0_vect, ISR_BLOCK)  // das Gleiche, wie  ISR(INT0_vect) d.h. während der Ausführung ist i-Flag gelöscht und wird beim Aussprung aus der ISR wieder gesetzt.

 

ISR_NOBLOCK .. an den Anfang der ISR wird vom Compiler sei() gesetzt, so dass die ISR unterbrochen werden kann.

 

ISR_ALIAS(INT1_vect, INT0_vect); //beide tun das Gleiche

 

EMPTY_INTERRUPT()   aus dem Schlafmodus aufwecken, aber keine Funktionalität

Anhang

 

Interrupt Vector Table

http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html

 

Vector name

Description

ADC_vect

ADC Conversion Complete

ANALOG_COMP_0_vect

Analog Comparator 0

ANALOG_COMP_1_vect

Analog Comparator 1

ANALOG_COMP_2_vect

Analog Comparator 2

ANALOG_COMP_vect

Analog Comparator

ANA_COMP_vect

Analog Comparator

CANIT_vect

CAN Transfer Complete or Error

EEPROM_READY_vect

 

EE_RDY_vect

EEPROM Ready

EE_READY_vect

EEPROM Ready

EXT_INT0_vect

External Interrupt Request 0

INT0_vect

External Interrupt 0

INT1_vect

External Interrupt Request 1

INT2_vect

External Interrupt Request 2

INT3_vect

External Interrupt Request 3

INT4_vect

External Interrupt Request 4

INT5_vect

External Interrupt Request 5

INT6_vect

External Interrupt Request 6

INT7_vect

External Interrupt Request 7

IO_PINS_vect

External Interrupt Request 0

LCD_vect

LCD Start of Frame

LOWLEVEL_IO_PINS_vect

Low-level Input on Port B

OVRIT_vect

CAN Timer Overrun

PCINT0_vect

Pin Change Interrupt Request 0

PCINT1_vect

Pin Change Interrupt Request 1

PCINT2_vect

Pin Change Interrupt Request 2

PCINT3_vect

Pin Change Interrupt Request 3

PCINT_vect

 

PSC0_CAPT_vect

PSC0 Capture Event

PSC0_EC_vect

PSC0 End Cycle

PSC1_CAPT_vect

PSC1 Capture Event

PSC1_EC_vect

PSC1 End Cycle

PSC2_CAPT_vect

PSC2 Capture Event

PSC2_EC_vect

PSC2 End Cycle

SPI_STC_vect

Serial Transfer Complete

SPM_RDY_vect

Store Program Memory Ready

SPM_READY_vect

Store Program Memory Read

TIM0_COMPA_vect

Timer/Counter Compare Match A

TIM0_COMPB_vect

Timer/Counter Compare Match B

TIM0_OVF_vect

Timer/Counter0 Overflow

TIM1_CAPT_vect

Timer/Counter1 Capture Event

TIM1_COMPA_vect

Timer/Counter1 Compare Match A

TIM1_COMPB_vect

Timer/Counter1 Compare Match B

TIM1_OVF_vect

Timer/Counter1 Overflow

TIMER0_CAPT_vect

ADC Conversion Complete

TIMER0_COMPA_vect

TimerCounter0 Compare Match A

TIMER0_COMPB_vect

Timer Counter 0 Compare Match B

TIMER0_COMP_A_vect

Timer/Counter0 Compare Match A

TIMER0_COMP_vect

Timer/Counter0 Compare Match

TIMER0_OVF0_vect

Timer/Counter0 Overflow

TIMER0_OVF_vect

Timer/Counter0 Overflow

TIMER1_CAPT1_vect

Timer/Counter1 Capture Event

TIMER1_CAPT_vect

Timer/Counter Capture Event

TIMER1_CMPA_vect

Timer/Counter1 Compare Match 1A

TIMER1_CMPB_vect

Timer/Counter1 Compare Match 1B

TIMER1_COMP1_vect

Timer/Counter1 Compare Match

TIMER1_COMPA_vect

Timer/Counter1 Compare Match A

TIMER1_COMPB_vect

Timer/Counter1 Compare MatchB

TIMER1_COMPC_vect

Timer/Counter1 Compare Match C

TIMER1_COMPD_vect

Timer/Counter1 Compare Match D

TIMER1_COMP_vect

Timer/Counter1 Compare Match

TIMER1_OVF1_vect

Timer/Counter1 Overflow

TIMER1_OVF_vect

Timer/Counter1 Overflow

TIMER2_COMPA_vect

Timer/Counter2 Compare Match A

TIMER2_COMPB_vect

Timer/Counter2 Compare Match A

TIMER2_COMP_vect

Timer/Counter2 Compare Match

TIMER2_OVF_vect

Timer/Counter2 Overflow

TIMER3_CAPT_vect

Timer/Counter3 Capture Event

TIMER3_COMPA_vect

Timer/Counter3 Compare Match A

TIMER3_COMPB_vect

Timer/Counter3 Compare Match B

TIMER3_COMPC_vect

Timer/Counter3 Compare Match C

TIMER3_OVF_vect

Timer/Counter3 Overflow

TIMER4_CAPT_vect

Timer/Counter4 Capture Event

TIMER4_COMPA_vect

Timer/Counter4 Compare Match A

TIMER4_COMPB_vect

Timer/Counter4 Compare Match B

TIMER4_COMPC_vect

Timer/Counter4 Compare Match C

TIMER4_OVF_vect

Timer/Counter4 Overflow

TIMER5_CAPT_vect

Timer/Counter5 Capture Event

TIMER5_COMPA_vect

Timer/Counter5 Compare Match A

TIMER5_COMPB_vect

Timer/Counter5 Compare Match B

TIMER5_COMPC_vect

Timer/Counter5 Compare Match C

TIMER5_OVF_vect

Timer/Counter5 Overflow

TWI_vect

2-wire Serial Interface

TXDONE_vect

Transmission Done, Bit Timer Flag 2 Interrupt

TXEMPTY_vect

Transmit Buffer Empty, Bit Itmer Flag 0 Interrupt

UART0_RX_vect

UART0, Rx Complete

UART0_TX_vect

UART0, Tx Complete

UART0_UDRE_vect

UART0 Data Register Empty

UART1_RX_vect

UART1, Rx Complete

UART1_TX_vect

UART1, Tx Complete

UART1_UDRE_vect

UART1 Data Register Empty

UART_RX_vect

UART, Rx Complete

UART_TX_vect

UART, Tx Complete

UART_UDRE_vect

UART Data Register Empty

USART0_RXC_vect

USART0, Rx Complete

USART0_RX_vect

USART0, Rx Complete

USART0_TXC_vect

USART0, Tx Complete

USART0_TX_vect

USART0, Tx Complete

USART0_UDRE_vect

USART0 Data Register Empty

USART1_RXC_vect

USART1, Rx Complete

USART1_RX_vect

USART1, Rx Complete

USART1_TXC_vect

USART1, Tx Complete

USART1_TX_vect

USART1, Tx Complete

USART1_UDRE_vect

USART1, Data Register Empty

USART2_RX_vect

USART2, Rx Complete

USART2_TX_vect

USART2, Tx Complete

USART2_UDRE_vect

USART2 Data register Empty

USART3_RX_vect

USART3, Rx Complete

USART3_TX_vect

USART3, Tx Complete

USART3_UDRE_vect

USART3 Data register Empty

USART_RXC_vect

USART, Rx Complete

USART_RX_vect

USART, Rx Complete

USART_TXC_vect

USART, Tx Complete

USART_TX_vect

USART, Tx Complete

USART_UDRE_vect

USART Data Register Empty

USI_OVERFLOW_vect

USI Overflow

USI_OVF_vect

USI Overflow

USI_START_vect

USI Start Condition

USI_STRT_vect

USI Start

USI_STR_vect

USI START

WATCHDOG_vect

Watchdog Time-out

WDT_OVERFLOW_vect

Watchdog Timer Overflow

WDT_vect

Watchdog Timeout Interrupt