Leírás
A megszakítások használata az Arduino programozói környezetben.
attachInterrupt()
Az első dolog, amit az attachInterrupt() számára meg kell adni az az, hogy melyik lábon figyelje a megszakítást. Normál esetben a digitalPinToInterrupt(pin)-t kell használnia a digitális láb hozzáadására. Például, ha a 3. lábhoz szeretne beállíani megszakítást, akkor a digitalPinToInterrupt(3) parancsot kell használnia.
Alaplap | megszakításhoz használható lábak |
---|---|
Uno, Nano, Mini, egyéb 328-alapú |
2, 3 |
Uno WiFi Rev.2 |
összes digitális láb |
Mega, Mega2560, MegaADK |
2, 3, 18, 19, 20, 21 |
Micro, Leonardo, egyéb 32u4-alapú |
0, 1, 2, 3, 7 |
Zero |
összes digitális láb, kivéve a 4. |
MKR család alaplapjai |
0, 1, 4, 5, 6, 7, 8, 9, A1, A2 |
Due |
összes digitális láb |
101 |
összes digitális láb (Only pins 2, 5, 7, 8, 10, 11, 12, 13 csak CHANGE mód) |
Megjegyzések és figyelmeztetések
Megjegyzés
A megszakítás közben a késleltetés [delay()] nem működik, és a millis() által visszaadott érték nem növekszik. A megszakítás végrehajtása közben a soros portra érkező adatok elveszhetnek. Valamennyi változót, amelyet módosítani szeretne a megszakításban, volatile-ként kell definiálnia. További információt az ISR-ekről szóló szakaszban talál.
Megszakítások használata
A megszakítások hasznosak ahhoz, hogy bizonyos dolgokat automatizáljunk a programban, és segíthetnek az időzítési problémák megoldásában. Célszerű megszakítást használni egy encoder jeleinek a feldolgozásához, vagy bizonyos bemenetek figyelésére.
Ha szeretne leprogramozni egy encoder kezelését úgy, hogy egyetlen impulzusról se maradjon le, akkor azt nagyon bonyolult lenne a megszakítások használata nélkül megtenni, mert a programnak állandóan a bemeneteket kellene figyelnie. Ehhez hasonlóan nehéz leprogramozni olyan jeladókat, amik rövid jeleket generálhatnak, például egy mikrofon vagy egy infrakapu. Az ilyen jellegű bemeneti eszközök használata esetén a megszakítások használata jelentősen lecsökkenti a mikrovezérlőnél a bemenetek figyelésére fordított erőforrásait.
Megszakítási rutin (Interrupt Service Routines, ISR)
Az ISR-ek olyan speciális típusú funkciók, amelyeknek vannak bizonyos egyedi korlátozásai (ami a legtöbb funkciónak nincs). Az ISR-nek nem lehet paramétere, és nem adhatnak vissza semmit. Általában az ISR-nek a lehető legrövidebbnek és gyorsabbnak kell lennie. Ha a vázlat több ISR-t használ, egyszerre csak egy futtatható, a többi megszakítás akkor kerül végrehajtásra, miután az aktuális befejeződött (prioritási sorrendben hajtódik végre, lásd lejjebb). A millis() funkció szintén egy megszakítás, így soha nem növekszik az ISR-ben. Mivel a delay() megszakításokat igényel a működéshez, ez sem fog működni, ha egy ISR-ben hívják. A micros() kezdetben működik, de 1-2 ms után hibásan viselkedik. A delayMicroseconds() nem használ számlálót, tehát normál módon fog működni.
Általában a globális változókat használják az adatok továbbítására az ISR és a fő program között. Annak biztosítása érdekében, hogy az ISR és a fő program között megosztott változók helyesen legyenek frissítve, volatile-ként kell deklarálni.
A megszakításokkal kapcsolatos további információkért lásd Nick Gammon jegyzeteit.
Az atmega328 megszakításai, prioritási sorrendben:
1 Reset
2 External Interrupt Request 0 (pin D2) (INT0_vect)
3 External Interrupt Request 1 (pin D3) (INT1_vect)
4 Pin Change Interrupt Request 0 (pins D8 to D13) (PCINT0_vect)
5 Pin Change Interrupt Request 1 (pins A0 to A5) (PCINT1_vect)
6 Pin Change Interrupt Request 2 (pins D0 to D7) (PCINT2_vect)
7 Watchdog Time-out Interrupt (WDT_vect)
8 Timer/Counter2 Compare Match A (TIMER2_COMPA_vect)
9 Timer/Counter2 Compare Match B (TIMER2_COMPB_vect)
10 Timer/Counter2 Overflow (TIMER2_OVF_vect)
11 Timer/Counter1 Capture Event (TIMER1_CAPT_vect)
12 Timer/Counter1 Compare Match A (TIMER1_COMPA_vect)
13 Timer/Counter1 Compare Match B (TIMER1_COMPB_vect)
14 Timer/Counter1 Overflow (TIMER1_OVF_vect)
15 Timer/Counter0 Compare Match A (TIMER0_COMPA_vect)
16 Timer/Counter0 Compare Match B (TIMER0_COMPB_vect)
17 Timer/Counter0 Overflow (TIMER0_OVF_vect)
18 SPI Serial Transfer Complete (SPI_STC_vect)
19 USART Rx Complete (USART_RX_vect)
20 USART, Data Register Empty (USART_UDRE_vect)
21 USART, Tx Complete (USART_TX_vect)
22 ADC Conversion Complete (ADC_vect)
23 EEPROM Ready (EE_READY_vect)
24 Analog Comparator (ANALOG_COMP_vect)
25 2-wire Serial Interface (I2C) (TWI_vect)
26 Store Program Memory Ready (SPM_READY_vect)
Szintaxis
attachInterrupt(digitalPinToInterrupt(pin), ISR, mód) (ajánlott)
attachInterrupt(megszakítás, ISR, mód) (nem ajánlott)
attachInterrupt(pin, ISR, mód) (Nem ajánlott. Ezenkívül ez a szintaxis csak az Arduino SAMD alaplapokon, az Uno WiFi Rev2, a Due és a 101-en működik.)
paraméterek
megszakítás: a megszakítás száma. Megengedett adattípusok: int.
pin: az Arduino lábának a száma.
ISR: az a rutin, amelyik végrehajtásra kerül
mód: meghatározza, hogy mikor kell megszakítani.
- LOW, akkor hajtódik végre, a a láb logikai alacsony szinten van,
- CHANGE, akkor halytódik végre, ha a láb logikai szintje megváltozik
- RISING, akkor hajtódik végre, ha a láb logikai szintje alacsonyról magasra vált
- FALLING, akkor hajtódik végre, ha a láb logikai szintje magasról alacsonyra vált
A Due, Zero és MKR1000 táblák szintén lehetővé teszik:
- HIGH, akkor hajtódik végre, ha a láb logikai magas állapotban van
Eredmény
nincs
Példakód
Megszakításos bemenetek száma
Normál esetben használja a digitalPinToInterrupt(pin) funkciót, ahelyett, hogy a megszakítás számát közvetlenül a vázlatba írná. A megszakításokkal kapcsolatos konkrét lábak és a megszakítások száma az egyes típusú alaplapoknál eltérő. A megszakítás számának közvetlen használata egyszerűnek tűnhet, de kompatibilitási problémákat okozhat, ha a vázlatot másik alaplapra szeretné lefordítani.
A régebbi vázlatok azonban gyakran közvetlen megszakítási számmal rendelkeznek. Gyakran a 0-t (a 2. digitális láb) vagy az 1. (a 3. digitális láb) használták. Az alábbi táblázat a rendelkezésre álló megszakításokat mutatja különböző alaplapok esetében.
Vegye figyelembe, hogy az alábbi táblázatban a megszakítási számok arra a számra vonatkoznak, amelyet át kell adni az attachInterrupt()-nak. Történelmi okokból ez a számozás nem mindig felel meg közvetlenül az ATmega chip megszakításának számozának (például az int.0 megfelel az INT4 az ATmega2560 chipen).
Alaplap | INT.0 | INT.1 | INT.2 | INT.3 | INT.4 | INT.5 |
---|---|---|---|---|---|---|
Uno, Ethernet |
2 |
3 |
||||
Mega2560 |
2 |
3 |
21 |
20 |
19 |
18 |
32u4 based (e.g Leonardo, Micro) |
3 |
2 |
0 |
1 |
7 |
Az Uno WiFiRev.2, Due, Zero, MKR Family és 101 táblák esetén a megszakítási szám = a láb száma.