Przerwania - dlaczego jest to proste

Zbiór tutoriali związanych z Arduino.
ODPOWIEDZ
Awatar użytkownika
Marhef
Złota rączka
Posty: 1075
Rejestracja: 18 lis 2011, 02:18

Przerwania - dlaczego jest to proste

Post autor: Marhef » 28 maja 2013, 23:38

Ponieważ na forum pojawia się wiele tematów związanych z problemami przy używaniu przerwań, postanowiłem napisac ten krótki poradnik.
Jest to luźne tłumaczenie opisu funkcji związanych z przerwaniami ze strony http://arduino.cc plus własne komentarze.

Na początek krótkie wyjaśnienie, co to jest przerwanie. Jeżeli w trakcie wykonywania programu wystąpi zdarzenie, na które kontroler musi zareagować natychmiast, kończy się wykonywać rozpoczęte polecenie, jego wynik zostaje zapisany w pamięci (słyszałem sformułowanie "na stosie"), uruchamiany jest program obsługi przerwania, po czym kontroler wraca do wykonywania kolejnych kroków programu.

W zależności od typu arduino dostępna jest różna ilość przerwań. Standardowo są to dwa przerwania, o nazwach int.0 oraz int.1, które są wywoływane zmianą stanu na pinach, odpowiednio, 2 oraz 3.
Arduino Mega2560 oferuje 6 przerwań (nazwy od int.0 do int.5) na pinach 2, 3, 21, 20, 19, 18.
Arduino Leonardo - 5 przerwań (int.0 do int.4) na pinach 3(!), 2(!), 0, 1, 7 (odwrotne wyprowadzenia dla dwóch pierwszych).
Arduino Due umożliwia obsługę przerwań na każdym dostępnym wyprowadzeniu (składnia funkcji dla tej wersji zostanie przedstawiona dodatkowo)

Arduino IDE pozwala na użycie czterech funkcji związanych z przerwaniami (ang. interrupt - przerwać, wyłączyć)
attachInterrupt
detachInterrupt
interrupts
noIntrerrupts

Funkcje interrupts() oraz noInterrupts() określają miejsca w programie, w których można używać przerwań.
Funkcja interrupts() włącza obsługę przerwań, funkcja noInterrupts() - wyłącza. Jeżeli zależy nam, żeby jakiś fragment programu został wykonany bez przerywania go, polecenia należy umieścić pomiędzy linijkami noInterrupts() oraz interrupts(), jak pokazano w przykładzie:

Kod: Zaznacz cały

void setup() {}

void loop()
{
  noInterrupts();
  // polecenia, w trakcie wykonywania których przerwania nie będą obsługiwane
  interrupts();
  // pozostałe polecenia
}
Funkcja detachInterrupt() wyłącza wybrane przerwanie.
Składnia funkcji:

Kod: Zaznacz cały

detachInterrupt(interrupt) 
detachInterrupt(pin)
Drugie polecenie - tylko dla Arduino Due
Parametry:
interrupt - numer przerwania do wyłączenia
pin - numer pinu, na którym wyłączamy obsługę przerwania

Funkcja attachInterrupt() definiuje sposób obsługi przerwania. Po wystąpieniu zmiany stanu wejścia odpowiadającego za dane przerwanie (co określa parametr mode) uruchamiana jest funkcja, określona przez parametr function
Składnia funkcji:

Kod: Zaznacz cały

attachInterrupt(interrupt, function, mode) 
 attachInterrupt(pin, function, mode)
Jak w przypadku funkcji detachInterrupt(), druga wersja jest tylko dla Arduino Due
Parametry:
interrupt - numer przerwania
pin - numer wyprowadzenia
function - funkcja uruchamiana, gdy nastąpi przerwanie; funkcja ta nie może mieć parametrów i nie może zwracać żadnej wartości. Jest nazywana funkcją obsługi przerwania
mode - określa, kiedy przerwanie ma być wyzwolone. Możliwe są cztery warianty (plus piąty dostępny tylko dla Arduino Due):
LOW - przerwanie wywołane, gdy stan wejścia jest w stanie LOW (0V)
CHANGE - przerwanie wywołane przy zmianie stanu wejścia
RISING - przerwanie wywołane przy zmianie stanu z niskiego (0V) na wysoki (5V)
FALLING - przerwanie wywołane przy zmianie stanu wejścia z wysokiego (5V) na niski (0V).
Dla Arduino Due dostępna jest piąta możliwość:
HIGH - wywołanie przerwania, jeśli stan wejścia jest wysoki (5V)

Ważne jest, że w trakcie wykonywania programu obsługi przerwania nie działa funkcja delay(), a wartość funkcji millis() nie jest zmieniana (nie odliczany jest czas)

Na koniec przykład, bo "nic tak nie zaciemnia sprawy jak dobry przykład"

Kod: Zaznacz cały

int pin = 13;
 volatile int state = LOW;

void setup()
{
   pinMode(pin, OUTPUT);                        //pin 13 jest traktowany jako wyjście
   attachInterrupt(0, blink, CHANGE);         //deklaracja przerwania: funkcja blink() zostaje wywołana przy zmianie stanu (CHANGE) wejścia 2 
                                                          //(bo do przerwania int.0 przypisany jest pin 2)
}

void loop()
{
   digitalWrite(pin, state);                        //zapisanie wartości state (LOW) do wyjścia 13 (określonego jako pin)
}

void blink()                                            //funkcja obsługi przerwania. Nie posiada parametrów i nie zwraca żadnej wartości
{
   state = !state;                                   //zanegowanie zmiennej state
}
I to wszystko w tym odcinku :) na wszelkie pytania chętnie odpowiem, konstruktywna krytyka będzie mile widziana

Co miesiąc do wygrania nagrody o wartości ponad 1600 zł!


ODPOWIEDZ

Strony partnerskie: