Przerwanie są potężną cechą mikrokontrolerów, które pozwalają asynchronicznie obsługiwać zdarzenia. W przeciwieństwie do ankiet, które stale sprawdzają zdarzenia, przerwania reagują natychmiast, gdy nastąpi określone zdarzenie, takie jak naciśnięcie przycisku lub przepełnienie czasu. Ten samouczek poprowadzi Cię przez zrozumienie i korzystanie z przerw z Arduino.
Czego będziesz potrzebować
- Arduino UNO (lub kompatybilna płyta)
- Przycisk
- Rezystor 10K-OHM (do konfiguracji rozciągnięcia)
- LED i rezystor 220-OHM (opcjonalnie)
- Druty chleba i skoczków
- Arduino IDE zainstalowane na komputerze
Krok 1: Co to są przerwania?
Przerwanie tymczasowo zatrzymuje wykonanie głównego programu w celu obsługi określonego zdarzenia. Po przetworzeniu zdarzenia program wznawia tam, gdzie się skończył. Przerwania są zarządzane przy użyciu specjalnych funkcji o nazwie Procedury usług przerwania (ISR).
Rodzaje przerwań w Arduino
- Zewnętrzne przerwania: Wyzwalane przez zdarzenia na określonych pinach (np. Pin 2 lub 3 na Arduino Uno).
- Zmiana pinów przerwa: Wyzwalane przez zmianę dowolnego cyfrowego szpilki.
- Timer przerywa: Wywołane przez przelewanie czasu lub porównaj dopasowania.
Krok 2: Korzystanie z zewnętrznych przerwań
Arduino UNO obsługuje zewnętrzne przerwy na pinach 2 i 3. Możesz skonfigurować te przerwania, aby uruchomić:
- ROSNĄCY: Sygnał przechodzi od niskiego do wysokiego.
- SPADAJĄCY: Sygnał przechodzi od wysokiego do niskiego.
- ZMIANA: Zmiany sygnału stanu (niskie do wysokiego lub wysokiego do niskiego).
- NISKI: Sygnał pozostaje niski.
Przykładowy kod: Wykrywanie przycisku Naciśnij
Ten przykład przełącza diodę LED, gdy przycisk podłączony do pin 2 jest naciśnięty.
#define buttonPin 2 // Interrupt pin
#define ledPin 13 // Built-in LED
volatile bool ledState = false; // Shared variable between ISR and main code
void handleInterrupt() {
ledState = !ledState; // Toggle LED state
digitalWrite(ledPin, ledState);
}
void setup() {
pinMode(buttonPin, INPUT_PULLUP); // Enable internal pull-up resistor
pinMode(ledPin, OUTPUT);
attachInterrupt(digitalPinToInterrupt(buttonPin), handleInterrupt, FALLING); // Trigger on button press
}
void loop() {
// Main loop does nothing; interrupt handles the LED
}
Wyjaśnienie
-
attachInterrupt(digitalPinToInterrupt(pin), ISR, mode)
: Konfiguruje przerwanie.-
pin
: Pin przerywający (np. Pin 2 lub 3 na Arduino Uno). -
ISR
: Procedura usługi przerwania do wykonania. -
mode
: Warunek wyzwalający (RISING
,FALLING
,CHANGE
, LubLOW
).
-
-
digitalPinToInterrupt(pin)
: Konwertuje numer PIN na numer przerwania.
Krok 3: Za pomocą zmiany pinu przerwa
Przerwanie zmiany pinu pozwalają wykrywać zmiany dowolnego cyfrowego pinu. Wymaga to dodatkowych bibliotek, takich jak WłączIntrut.
Przykładowy kod: Zmiana pinu przerwanie
#include <EnableInterrupt.h>
#define pin 4 // Pin to monitor
void handlePinChange() {
Serial.println("Pin state changed!");
}
void setup() {
Serial.begin(9600);
enableInterrupt(pin, handlePinChange, CHANGE); // Trigger on any state change
}
void loop() {
// Main loop does nothing; interrupt handles the event
}
Instalacja biblioteki
Aby użyć przerwania zmiany pinu, zainstaluj WłączIntrut Biblioteka za pośrednictwem menedżera biblioteki Arduino.
Krok 4: Timer przerywa
Przerwanie timera są przydatne do planowania zadań w precyzyjnych odstępach czasu. Patrz Samouczek Timer Arduino Szczegółowe informacje na temat konfigurowania przerwań timera.
Przykład: miga diody LED z przerwaniem Timer1
#define ledPin 13
void setup() {
pinMode(ledPin, OUTPUT);
// Configure Timer1
noInterrupts(); // Disable interrupts during setup
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
OCR1A = 15624; // Compare match value for 1Hz (1-second interval)
TCCR1B |= (1 << WGM12); // CTC mode
TCCR1B |= (1 << CS12) | (1 << CS10); // 1024 prescaler
TIMSK1 |= (1 << OCIE1A); // Enable Timer1 compare interrupt
interrupts(); // Enable interrupts
}
ISR(TIMER1_COMPA_vect) {
digitalWrite(ledPin, !digitalRead(ledPin)); // Toggle LED
}
void loop() {
// Main loop does nothing; Timer1 handles the LED
}
Krok 5: Najlepsze praktyki stosowania przerwań
- Skróć ISR: Unikaj opóźnień lub złożonych obliczeń w ISR, aby zapewnić szybką reakcję.
- Unikaj seryjnej komunikacji w ISR: Funkcje szeregowe mogą nie działać niezawodnie w ISR.
-
Używać
volatile
dla wspólnych zmiennych: Zmienne Mark udostępnione między ISR i programem głównym jakovolatile
Aby zapobiec problemom optymalizacji kompilatora. - Wejścia debuncia: Obsługuj logikę debuncji w oprogramowaniu lub sprzętu dla hałaśliwych sygnałów, takich jak przyciski przycisków.
-
Wyłącz przerwy podczas krytycznych sekcji: Używać
noInterrupts()
Iinterrupts()
w celu ochrony krytycznych sekcji kodów.
Zastosowania przerwań
- Przycisk obchodzenia się naciska bez głosowania
- Czytanie enkoderów obrotowych
- Zdarzenia krytyczne (np. Precyzyjne sterowanie silnikiem)
- Planowanie zadań okresowych
- Reakcja na sygnały zewnętrzne (np. Czujniki, zdarzenia komunikacyjne)
Rozwiązywanie problemów
- Przerwanie nie wyzwala się: Upewnij się, że skonfigurowane są prawidłowe pin i tryb.
- Niestabilne zachowanie: Dezakuj hałaśliwe sygnały i unikaj długich ISR.
- Konflikty z bibliotekami: Niektóre biblioteki używają przerwań wewnętrznie (np. Servo, PWM). Nie upewnij się, że nie ma konfliktu z kodem.
Wniosek
Przerwanie umożliwiają responsywne i skuteczne obsługę wydarzeń w projektach Arduino. Ucząc się korzystać z zewnętrznych, zmiany pinów i przerwań zegarowych, możesz tworzyć solidne i precyzyjne aplikacje. Eksperymentuj z różnymi rodzajami przerwań, aby ulepszyć swoje projekty i zoptymalizować wydajność!