Întreruperile sunt o caracteristică puternică a microcontrolerelor care vă permit să gestionați evenimentele asincron. Spre deosebire de sondaj, care verifică continuu evenimentele, întreruperile răspund imediat atunci când are loc un eveniment specific, cum ar fi o apăsare a butonului sau o revărsare a cronometrului. Acest tutorial vă va ghida prin înțelegerea și utilizarea întreruperilor cu Arduino.
Ce vei avea nevoie
- Arduino UNO (sau o placă compatibilă)
- Buton de apăsare
- Rezistență de 10k-ohm (pentru configurarea derulantă)
- Rezistență LED și 220-ohm (opțional)
- Tablă de pâine și jumper
- Arduino IDE instalat pe computer
Pasul 1: Ce sunt întreruperile?
O întrerupere a întreruperii temporar a execuției programului principal pentru a gestiona un eveniment specific. Odată ce evenimentul este procesat, programul reia acolo unde a plecat. Întreruperile sunt gestionate folosind funcții speciale numite Rutine de serviciu de întrerupere (ISR).
Tipuri de întreruperi în Arduino
- Întreruperi externe: Declanșat de evenimente pe pini specifici (de exemplu, pinul 2 sau 3 pe Arduino Uno).
- Întreruperea schimbării pinului: Declanșat de o schimbare pe orice pin digital.
- Întreruperea cronometrului: Declanșat de revărsări de cronometru sau comparați meciurile.
Pasul 2: Utilizarea întreruperilor externe
Arduino Uno acceptă întreruperi externe pe pinii 2 și 3. Puteți configura aceste întreruperi pentru a declanșa:
- Rising: Semnalul merge de la scăzut la mare.
- Cădere: Semnalul merge de la mare la scăzut.
- SCHIMBA: Semnalul modifică starea (scăzută până la mare sau mare până la scăzută).
- SCĂZUT: Semnalul rămâne scăzut.
Exemplu de cod: detectarea unui buton Apăsați
Acest exemplu comută un LED când este apăsat un buton conectat la PIN 2.
#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
}
Explicaţie
-
attachInterrupt(digitalPinToInterrupt(pin), ISR, mode)
: Configurează întreruperea.-
pin
: Pinul de întrerupere (de exemplu, pinul 2 sau 3 pe Arduino Uno). -
ISR
: Rutina serviciului de întrerupere pentru a executa. -
mode
: Starea de declanșare (RISING
,FALLING
,CHANGE
, sauLOW
).
-
-
digitalPinToInterrupt(pin)
: Convertește un număr PIN în numărul său de întrerupere.
Pasul 3: Utilizarea întreruperilor de schimbare a pinului
Întreruperile de schimbare a pinului vă permit să detectați modificări pe orice pin digital. Aceasta necesită biblioteci suplimentare, cum ar fi Activați întreruperea.
Exemplu de cod: întreruperea modificării pinului
#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
}
Instalarea bibliotecii
Pentru a utiliza întreruperea schimbărilor PIN, instalați Activați întreruperea Biblioteca prin Managerul Bibliotecii Arduino.
Pasul 4: întreruperea cronometrului
Întreruperile de cronometru sunt utile pentru programarea sarcinilor la intervale precise. Consultați la Tutorialul Timer Arduino Pentru detalii despre configurarea întreruperilor de cronometru.
Exemplu: clipirea unui LED cu întreruperea 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
}
Pasul 5: Cele mai bune practici pentru utilizarea întreruperilor
- Păstrați ISRS scurt: Evitați întârzierile sau calculele complexe în ISR -uri pentru a asigura un răspuns rapid.
- Evitați comunicarea în serie în ISRS: Este posibil ca funcțiile seriale să nu funcționeze în mod fiabil în interiorul unui ISR.
-
Utilizare
volatile
Pentru variabilele partajate: Marcați variabilele împărtășite între ISR și programul principal cavolatile
pentru a preveni problemele de optimizare a compilatorului. - Debunerea intrărilor: Manevrați logica de debutare în software sau hardware pentru semnale zgomotoase, cum ar fi apăsări de butoane.
-
Dezactivați întreruperea în timpul secțiunilor critice: Utilizare
noInterrupts()
şiinterrupts()
Pentru a proteja secțiunile de cod critice.
Aplicații de întreruperi
- Butonul de manipulare apasă fără votare
- Citirea codificatoarelor rotative
- Evenimente critice de sincronizare (de exemplu, control precis al motorului)
- Programarea sarcinilor periodice
- Reacționarea la semnale externe (de exemplu, senzori, evenimente de comunicare)
Depanare
- Întrerupe nu declanșarea: Asigurați -vă că sunt configurate pinul și modul corect.
- Comportament instabil: Debuneți semnalele zgomotoase și evitați ISR -urile lungi.
- Conflicte cu bibliotecile: Unele biblioteci folosesc întreruperi interne (de exemplu, Servo, PWM). Nu asigurați niciun conflict cu codul dvs.
Concluzie
Întreruperile permit gestionarea receptivă și eficientă a evenimentelor în proiectele Arduino. Învățând să utilizați întreruperi externe, PIN SCHIMBARE și TIMER, puteți crea aplicații robuste și precise. Experimentați cu diferite tipuri de întreruperi pentru a vă îmbunătăți proiectele și a optimiza performanța!