Hány megszakító csapot tud kezelni egy Uno?

Egy 7 csatornás RC vevő használatát vizsgálom az Arduino Uno R3 készülékkel. A dokumentációban legfeljebb 2 megszakító érintkezõ van megemlítve, míg bizonyos más blogokban már említettem, hogy akár 20 csapot is megszakításként használnak a PinChangeInt könyvtárral. Szóval, hány megszakítást tud natívan kezelni az Arduino? És ez különbözik attól, hogy mennyit lehet kezelni olyan szoftveres támogatással, mint a PinChangeInt?

Válasz

Kétféle ” csapváltás “típusú megszakítja. A külső megszakítások, amelyek közül kettő van az Uno-n. 0-nak és 1-nek hívják őket, azonban a táblán lévő 2 és 3 digitális csapokra utalnak. Ezek konfigurálhatók az emelkedés, zuhanás, változás (emelkedő vagy zuhanás) vagy LOW észlelésére.

Ezen felül vannak a “csapváltás” megszakítások, amelyek észlelik a csap állapotának változását a 20 érintkező bármelyikében (A0-tól A5-ig, és D0-tól D13-ig). Ezek a csapváltó megszakítások szintén hardver alapúak , tehát önmagukban olyan gyorsak lesznek, mint a külső megszakítások.

Mindkét típust kissé furcsán lehet használni a regiszter szintjén, de a szabványos IDE tartalmazza az attachInterrupt (n) és a detachInterrupt (n) elemeket, amelyek leegyszerűsítik az interfészt a külső megszakításokkal. Használhatja a Tűcsere könyvtárat a csapváltás megszakításának egyszerűsítésére.

Ha azonban egy percre el akarjuk távolítani a könyvtárat, megállapíthatja, hogy a tűcsere megszakítások ugyanolyan gyorsak vagy gyorsabbak, mint a külső megszakítások. Egyrészt, bár a csapváltás megszakítja a csapok kötegeinek működését, nem kell engedélyeznie a teljes köteget. Például, ha a D4 tűn észlelni szeretné a változásokat, ez elég lesz:

Példa vázlat:

 ISR (PCINT2_vect) { // handle pin change interrupt for D0 to D7 here if (PIND & bit (4)) // if it was high PORTD |= bit (5); // turn on D5 else PORTD &= ~bit (5); // turn off D5 } // end of PCINT2_vect void setup () { // pin change interrupt (example for D4) PCMSK2 |= bit (PCINT20); // want pin 4 PCIFR |= bit (PCIF2); // clear any outstanding interrupts PCICR |= bit (PCIE2); // enable pin change interrupts for D0 to D7 pinMode (4, INPUT_PULLUP); pinMode (5, OUTPUT); } // end of setup void loop () { }  

Tesztelésem szerint 1,6 µs kellett a “teszthez” “pin (5. tű), hogy reagáljon a megszakító csap (4. tű) változására.


Most, ha az egyszerű (lusta?) megközelítést alkalmazza, és az attachInterrupt () parancsot használja, megtalálja a az eredmények lassabbak, nem gyorsabbak.

Példa kód:

 void myInterrupt () { if (PIND & bit (2)) // if it was high PORTD |= bit (5); // turn on D5 else PORTD &= ~bit (5); // turn off D5 } // end of myInterrupt void setup () { attachInterrupt (0, myInterrupt, CHANGE); pinMode (2, INPUT_PULLUP); pinMode (5, OUTPUT); } // end of setup void loop () { }  

A tesztcsap megváltoztatása 3,7 µs-ig tart, sokkal több, mint a fenti 1,6 µs. Miért? Mivel a kódnak, amelyet a fordítónak generálnia kell az “általános” megszakításkezelőhöz, minden elképzelhető regisztert el kell mentenie (tovább kell nyomnia) belépés az ISR-be, majd a visszatérés előtt állítsa vissza (állítsa be) őket. Ráadásul egy másik függvényhívás rezsije van.


Most meg tudjuk oldani ezt úgy, hogy elkerüljük a attachInterrupt () használatát, és magunk csináljuk meg:

 ISR (INT0_vect) { if (PIND & bit (2)) // if it was high PORTD |= bit (5); // turn on D5 else PORTD &= ~bit (5); // turn off D5 } // end of INT0_vect void setup () { // activate external interrupt 0 EICRA &= ~(bit(ISC00) | bit (ISC01)); // clear existing flags EICRA |= bit (ISC00); // set wanted flags (any change interrupt) EIFR = bit (INTF0); // clear flag for interrupt 0 EIMSK |= bit (INT0); // enable it pinMode (2, INPUT_PULLUP); pinMode (5, OUTPUT); } // end of setup void loop () { }  

Ez mind közül a leggyorsabb 1,52 µs sebességgel – úgy tűnik, hogy egy óra ciklus mentésre került valahova.


Van azonban egy figyelmeztetés a tűcserélő megszakításokra. Kötegeltek, így ha meg akarja szakítani a sok csapot, tesztelnie kell a megszakításon belül , hogy melyik változott . Ezt megteheti úgy, hogy elmenti az előző PIN-állapotot, és összehasonlítja az új PIN-kóddal. Ez nem feltétlenül különösebben lassú, de minél több csapot kell ellenőriznie, annál lassabb lenne.

A kötegek a következők:

  • A0 – A5
  • D0-tól D7-ig
  • D8-tól D13-ig

Ha csak még pár megszakító csapra vágyik, elkerülheti a tesztelést, ha csak különböző csapok használatát választja kötegek (pl. D4 és D8).


További részletek: http://www.gammon.com.au/interrupts

Válasz

Kétféle megszakítás létezik. Mit mondott a Arduino játszótér :

Az Arduino középpontjában álló processzornak kétféle megszakítása van: „külső” és „tűcsere”. Az ATmega168 / 328-on (azaz az Arduino Uno / Nano / Duemilanove-ban) csak két külső megszakító tüske van, az INT0 és az INT1, és ezek az Arduino 2. és 3. csapjához vannak hozzárendelve. Ezek a megszakítások beállíthatók RISING vagy FALLING jel élek, vagy alacsony szinten. A kiváltókat hardver értelmezi, és a megszakítás nagyon gyors. Az Arduino Mega még néhány külső megszakítótűvel rendelkezik.

Másrészt a csapváltás megszakításai még sok csapon engedélyezhetők. Az ATmega168 / 328 alapú Arduinos esetében engedélyezhetők az Arduino bármelyik vagy mind a 20 jelérzékelőjén, vagy az ATmega alapú Arduinoson 24 érintkezőn. Egyformán aktiválódhatnak a FELMERÜLŐ vagy a FALLING jelszéleken, tehát a megszakítási kódon múlik, hogy beállítsa-e a megfelelő csapokat a megszakítások fogadására, meghatározza, hogy mi történt (melyik tű?Ezenkívül a csapváltó megszakítások az MCU 3 „portjába” vannak csoportosítva, így csak 3 megszakító vektor (szubrutin) van a csapok teljes testére. Ez még bonyolultabbá teszi a művelet egyetlen megszakítással történő megoldását.

Alapvetően a külső megszakítások rendkívül gyorsak, mivel minden hardver alapúak . Vannak azonban a csapváltás megszakításai is, de ezek sokkal lassabbnak tűnnek, mert többnyire szoftver alapúak.

tl; dr: a 20 megszakító tüske együtt sokkal lassabb. A 2 megszakító csap a leggyorsabb és leghatékonyabb.


SZERKESZTÉS: Most néztem meg az adatlapot, és azt mondja, hogy a kijelölt csapok bármelyik hez egy csapváltás megszakítása vált ki, jelzés nélkül melyik tű megváltozott (bár három megszakítási vektorra van felosztva).

  • Külső megszakítások esetén “megmondja, hogy a 3. tű éppen megváltozott
  • A csapok cseréjéhez “megmondom, hogy egy megváltozott tű, amelyet figyeltél!

Mint láthatod, a csapváltás megszakítása sok általános költséget jelent az ISR-ben, amelyet kezelnie kell azáltal, hogy tárolja az előző állapotokat, és megnézi, hogy ez-e az a tű, amiért aggódik. Lehet, hogy alvási állapotban rendben van, de jobb a külső megszakításokat használni.

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük