Kolik kolíků přerušení zvládne Uno?

Dívám se na použití 7kanálového RC přijímače s Arduino Uno R3. V dokumentaci jsou zmínky o maximálně 2 pinech přerušení, zatímco na některých jiných blogech jsem viděl zmínky o použití až 20 pinů jako přerušení s knihovnou PinChangeInt. Kolik přerušení tedy může Arduino nativně zvládnout? A liší se to od toho, kolik lze zvládnout pomocí softwarové podpory, jako je PinChangeInt?

Odpověď

Existují dva typy “ přerušení typu „změna PINu“. Vnější přerušení, z nichž na Uno jsou dvě. Nazývají se 0 a 1, ale odkazují na digitální piny 2 a 3 na desce. Lze je nakonfigurovat tak, aby detekovaly vzestup, pokles, změnu (vzestup nebo klesání) nebo LOW.

Kromě toho jsou to přerušení „změny pinů“, která detekují změnu stavu pinů v kterémkoli z 20 pinů (A0 až A5 a D0 až D13). Tato přerušení pinů jsou také hardwarově založená , takže sama o sobě bude stejně rychlá jako externí přerušení.

Oba typy jsou mírně fiddly pro použití na úrovni registru, ale standardní IDE zahrnuje attachInterrupt (n) a detachInterrupt (n), což zjednodušuje rozhraní pro externí přerušení. Můžete také použít Knihovnu změn kolíků a zjednodušit tak přerušení změn kolíků.

Když se však na minutu vyhýbáme knihovně, může zjistit, že přerušení výměny kolíků mohou být stejně rychlá nebo rychlejší než externí přerušení. Za prvé, i když změna pinů přeruší práci na dávkách pinů, nemusíte povolit celou dávku. Například pokud chcete detekovat změny na pin D4, bude to stačit:

Příklad skica:

 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 () { }  

Moje testování naznačuje, že u testu trvalo 1,6 s „kolík (kolík 5), aby reagoval na změnu přerušovacího kolíku (kolík 4).


Nyní, pokud použijete jednoduchý (líný?) přístup a použijete attachInterrupt (), najdete výsledky jsou pomalejší, ne rychlejší.

Příklad kódu:

 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 () { }  

Změna zkušebního kolíku zabere 3,7 µs, mnohem více než 1,6 µs výše. Proč? Protože kód, který musí kompilátor vygenerovat pro „obecný“ obslužný program přerušení, musí uložit každý myslitelný registr (odeslat jej) na vstup na ISR a poté je před návratem obnovit (vyskakovat). Navíc je zde režie dalšího volání funkce.


Nyní to můžeme obejít tak, že se vyhneme attachInterrupt () a uděláme to sami:

 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 () { }  

To je nejrychlejší ze všech za 1,52 µs – vypadá to, že se někde uložil jeden hodinový cyklus.


Existuje však jedno upozornění na přerušení pinů. Jsou dávkovány, takže pokud chcete mít přerušení na mnoha pinech, musíte otestovat uvnitř přerušení které se změnilo . Můžete to udělat uložením stavu předchozího kolíku a porovnáním se stavem nového kolíku. To nemusí být nutně zvlášť pomalé, ale čím více pinů musíte zkontrolovat, tím pomalejší by to bylo.

Dávky jsou:

  • A0 až A5
  • D0 až D7
  • D8 až D13

Pokud chcete jen několik dalších přerušovacích kolíků, můžete se vyhnout jakémukoli testování pouhým výběrem použití kolíků z různých dávky (např. D4 a D8).


Více podrobností na http://www.gammon.com.au/interrupts

Odpověď

Existují dva typy přerušení. Co říkalo hřiště Arduino :

Procesor v srdci jakéhokoli Arduina má dva různé druhy přerušení: „externí“ a „změna PINu“. Na ATmega168 / 328 (tj. V Arduino Uno / Nano / Duemilanove), INT0 a INT1 jsou pouze dva externí piny přerušení a jsou mapovány na piny Arduino 2 a 3. Tyto přerušení lze nastavit tak, aby se spouštěly na RISING nebo PADÁNÍ hran signálu nebo na nízké úrovni. Spouštěče jsou interpretovány hardwarem a přerušení je velmi rychlé. Arduino Mega má k dispozici několik dalších externích pinů přerušení.

Na druhou stranu lze přerušení pinů povolit na mnoha dalších pinech. U Arduin založených na ATmega168 / 328 mohou být povoleny na kterémkoli nebo všech 20 signálních pinech Arduina; na Arduinech založených na ATmega mohou být povoleny na 24 pinech. Jsou spouštěny stejně na hranách signálu RISING nebo FALLING, je tedy na kódu přerušení, aby nastavil správné piny pro příjem přerušení, určil, co se stalo (který pin? … vzrostl nebo klesl signál?), a aby s ním správně zacházel.Přerušení výměny pinů jsou dále seskupena do 3 „portů“ na MCU, takže existují pouze 3 vektory přerušení (podprogramy) pro celé tělo pinů. Díky tomu je práce na vyřešení akce u jednoho přerušení ještě komplikovanější.

Externí přerušení jsou v zásadě extrémně rychlá, protože jsou založena na hardwaru . Existují však také přerušení pinů, ale zdá se, že jsou mnohem pomalejší, protože jsou většinou softwarová.

tl; dr: 20 přerušovacích kolíků dohromady je mnohem pomalejší. 2 kolíky přerušení jsou nejrychlejší a nejúčinnější.


EDIT: Právě jsem se podíval na datový list a říká, že přerušení změny PIN je spuštěno pro jakýkoli z vybraných pinů bez indikace který pin se změnil (i když je rozdělen na tři vektory přerušení).

  • U externích přerušení vám řeknu pin 3 se právě změnil
  • Pro změnu PINu vám řeknu PIN změněný, který jste sledovali!

Jak vidíte, Přerušení výměny kolíku přidá do ISR spoustu režie, kterou musíte zvládnout, tím, že uložíte předchozí stavy a uvidíte, jestli je to kolík, kterého se obáváte. Pro režim spánku to může být v pořádku, ale je lepší použít externí přerušení.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *