Etsin 7-kanavaisen RC-vastaanottimen käyttöä Arduino Uno R3: n kanssa. Asiakirjoissa mainitaan enintään 2 keskeytysnastaa, kun taas joissakin muissa blogeissa olen maininnut jopa 20 nastan käyttämisen keskeytyksinä PinChangeInt-kirjaston kanssa. Joten kuinka monta keskeytystä Arduino pystyy käsittelemään natiivisti? Ja onko tämä erilainen kuin monien ohjelmistojen tuki, kuten PinChangeInt?
Vastaus
On olemassa kahdenlaisia ” pin change ”-tyyppinen keskeytys. Ulkoiset keskeytykset, joista Unossa on kaksi. Niitä kutsutaan 0 ja 1, mutta ne viittaavat taulussa oleviin digitaalisiin nastoihin 2 ja 3. Nämä voidaan määrittää havaitsemaan nousun, putoamisen, muutoksen (nousun tai putoamisen) tai LOW-arvon.
Sen lisäksi ovat ”tapinvaihdon” keskeytykset, jotka havaitsevat muutoksen tapitilaan missä tahansa 20 nastasta (A0 – A5 ja D0 – D13). Nämä pin-vaihtokeskeytykset ovat myös laitteistopohjaisia , joten ne ovat sinänsä yhtä nopeita kuin ulkoiset keskeytykset.
Molempia tyyppejä on helppo käyttää rekisteritasolla, mutta tavallinen IDE sisältää attachInterrupt (n) ja detachInterrupt (n), jotka yksinkertaistavat käyttöliittymän ulkoisiin keskeytyksiin. Voit myös käyttää nastanvaihtokirjastoa yksinkertaistaaksesi nastanvaihdon keskeytyksiä.
Ohjaamme kuitenkin kirjastosta hetkeksi, voi todeta, että pin-vaihdon keskeytykset voivat olla yhtä nopeita tai nopeampia kuin ulkoiset keskeytykset. Ensinnäkin, vaikka tapinvaihto keskeyttää nastaryhmien työn, sinun ei tarvitse ottaa koko erää käyttöön. Esimerkiksi, jos haluat havaita muutokset tapissa D4, tämä riittää:
Esimerkki luonnos:
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 () { }
Testaukseni osoitti, että testiin kului 1,6 µs ”tappi (tappi 5) reagoimaan keskeytystapin muutokseen (tappi 4).
Jos valitset yksinkertaisen (laiska?) lähestymistavan ja käytät attachInterrupt () -linkkiä, löydät tulokset ovat hitaampia, eivät nopeita.
Esimerkkikoodi:
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 () { }
Testinastan vaihtaminen vie 3,7 µs, paljon enemmän kuin yllä oleva 1,6 µs. Miksi? Koska koodin, jonka kääntäjän on luotava ”yleiselle” keskeytyskäsittelijälle, on tallennettava kaikki mahdolliset rekisterit (työnnettävä ne) päälle pääsy ISR: ään ja palauta ne sitten (palauta ne) ennen paluuta. Lisäksi siellä on toisen funktiokutsun yleiskustannukset.
Nyt voimme kiertää välttämällä attachInterrupt () ja tekemällä sen itse:
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 () { }
Se on nopein niistä kaikista nopeudella 1,52 µs – näyttää siltä, että yksi kellojakso on tallennettu jonnekin.
Siellä on kuitenkin yksi huomautus pin-vaihdon keskeytyksille. Ne ovat eräajoitettuja, joten jos haluat keskeyttää useita nastoja, sinun on testattava keskeytyksen sisällä mikä muuttui . Voit tehdä sen tallentamalla edellisen nastatilan ja vertaamalla sitä uuteen nastatilaan. Tämä ei välttämättä ole erityisen hidasta, mutta mitä enemmän nastoja sinun on tarkistettava, sitä hitaampi se olisi.
Erät ovat:
- A0 – A5
- D0 – D7
- D8 – D13
Jos haluat vain pari lisää keskeytysnastoja, voit välttää testauksen valitsemalla vain käyttämään eri nastoja erät (esim. D4 ja D8).
Lisätietoja: http://www.gammon.com.au/interrupts
Vastaa
Keskeytyksiä on kahdenlaisia. Mitä Arduino Playground sanoi:
Minkä tahansa Arduinon ytimessä olevalla prosessorilla on kaksi erilaista keskeytystä: ”ulkoinen” ja ”nastan vaihto”. ATmega168 / 328: ssa (eli Arduino Unossa / Nano / Duemilanovessa) on vain kaksi ulkoista keskeytysnastaa, INT0 ja INT1, ja ne on yhdistetty Arduino-nastoihin 2 ja 3. Nämä keskeytykset voidaan asettaa laukaisemaan RISING tai FALLING-signaalin reunat tai matalalla tasolla. Laitteisto tulkitsee laukaisimet ja keskeytys on erittäin nopea. Arduino Megalla on vielä muutama ulkoinen keskeytysnasta käytettävissä.
Toisaalta nastanvaihdon keskeytykset voidaan ottaa käyttöön monilla muilla nastoilla. ATmega168 / 328-pohjaisille Arduinoille ne voidaan ottaa käyttöön missä tahansa tai kaikissa 20 Arduinon signaalipidikkeessä; ATmega-pohjaisissa Arduinosissa ne voidaan ottaa käyttöön 24 nastassa. Ne laukaistaan tasaisesti RISING- tai FALLING-signaalin reunoilla, Joten keskeytyskoodin tehtävänä on asettaa oikeat nastat vastaanottamaan keskeytyksiä, määrittää mitä tapahtui (mikä nasta? … nousi tai laski signaali?), ja käsitellä sitä oikein.Lisäksi tapinvaihdon keskeytykset on ryhmitelty MCU: n 3 ”porttiin”, joten koko nastarungolle on vain 3 keskeytysvektoria (alirutiinia). Tämä tekee toiminnan ratkaisemisesta yhdellä keskeytyksellä vielä monimutkaisemman.
Ulkoiset keskeytykset ovat periaatteessa erittäin nopeita, koska ne ovat kaikki laitteistopohjaisia . Siellä on kuitenkin myös tapinvaihdon keskeytyksiä, mutta ne näyttävät olevan paljon hitaampia, koska ne ovat enimmäkseen ohjelmistopohjaisia.
tl; dr: 20 keskeytysnastaa yhdessä ovat paljon hitaampia. 2 keskeytysnastaa ovat nopeimmat ja tehokkaimmat.
MUOKKAA: Katsoin juuri datalehteä ja siinä sanotaan, että tapinvaihdon keskeytys laukaistaan mille tahansa valitulle nastalle ilman viitteitä mikä nasta on muuttunut (vaikka se onkin jaettu kolmeen keskeytysvektoriin).
- Ulkoisille keskeytyksille se ”kertoo sinulle nasta 3 juuri muuttunut
- Jos haluat vaihtaa neulan, se kertoo sinulle nastan, jota vaihdit, jota seurasit!
Kuten näette, nastanvaihdon keskeytys lisää paljon yleiskustannuksia ISR: ään, jota sinun on käsiteltävä tallentamalla edelliset tilat ja katsomalla, onko se tappi, josta olet huolissasi. Se voi olla hyvä nukkumistilassa, mutta on parempi käyttää ulkoisia keskeytyksiä.