Wie viele Interrupt-Pins kann ein Uno verarbeiten?

Ich möchte einen 7-Kanal-RC-Empfänger mit dem Arduino Uno R3 verwenden. In der Dokumentation werden maximal 2 Interrupt-Pins erwähnt, während in bestimmten anderen Blogs erwähnt wurde, dass bis zu 20 Pins als Interrupts mit der PinChangeInt-Bibliothek verwendet werden. Wie viele Interrupts kann der Arduino nativ verarbeiten? Und unterscheidet sich dies davon, wie viele mit Software-Support wie PinChangeInt verarbeitet werden können?

Antwort

Es gibt zwei Arten von “ Pinwechsel „Typ Interrupts. Die externen Interrupts, von denen es zwei auf dem Uno gibt. Sie heißen 0 und 1, beziehen sich jedoch auf die digitalen Pins 2 und 3 auf der Platine. Diese können so konfiguriert werden, dass sie steigen, fallen, sich ändern (steigend oder fallen) oder NIEDRIG.

Darüber hinaus gibt es „Pinwechsel“ -Interrupts, die eine Änderung des Pin-Zustands in einem der 20 Pins (A0 bis A5 und D0 bis D13) erkennen. Diese Pinwechsel-Interrupts sind auch hardwarebasiert und an sich so schnell wie die externen Interrupts.

Beide Typen sind auf Registerebene etwas umständlich zu verwenden, aber die Standard-IDE enthält AttachInterrupt (n) und DetachInterrupt (n), was die Schnittstelle zu externen Interrupts vereinfacht. Sie können auch die Pin-Änderungsbibliothek verwenden, um die Pin-Wechsel-Interrupts zu vereinfachen.

Wir halten uns jedoch für eine Minute von der Bibliothek fern kann feststellen, dass Pinwechsel-Interrupts genauso schnell oder schneller sein können als externe Interrupts. Zum einen müssen Sie nicht den gesamten Stapel aktivieren, obwohl Pinwechsel-Interrupts für Pin-Stapel funktionieren. Wenn Sie beispielsweise Änderungen an Pin D4 erkennen möchten, reicht dies aus:

Beispiel Skizze:

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

Meine Tests haben ergeben, dass der „Test 1,6 µs gedauert hat „Pin (Pin 5), um auf eine Änderung am Interrupt-Pin (Pin 4) zu reagieren.


Wenn Sie nun den einfachen (faulen?) Ansatz wählen und attachInterrupt () verwenden, finden Sie den Die Ergebnisse sind langsamer und nicht schneller.

Beispielcode:

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

Das Ändern des Test-Pins dauert 3,7 µs, viel mehr als die oben genannten 1,6 µs. Warum? Weil der Code, den der Compiler für den „generischen“ Interrupt-Handler generieren muss, jedes denkbare Register speichern (aufschieben) muss Geben Sie den ISR ein und stellen Sie sie vor der Rückkehr wieder her (Pop). Außerdem entsteht der Overhead eines weiteren Funktionsaufrufs.


Jetzt können wir das umgehen, indem wir attachInterrupt () vermeiden und es selbst tun:

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

Das ist mit 1,52 µs der schnellste von allen – es sieht so aus, als ob irgendwo ein Taktzyklus gespeichert wurde.


Es gibt jedoch eine Einschränkung für Pin-Change-Interrupts. Sie sind gestapelt. Wenn Sie also Interrupts an vielen Pins haben möchten, müssen Sie innerhalb des Interrupts testen, den geändert hat . Sie können dies tun, indem Sie den vorherigen Pin-Status speichern und mit dem neuen Pin-Status vergleichen. Dies ist nicht unbedingt besonders langsam, aber je mehr Pins Sie überprüfen müssen, desto langsamer ist es.

Die Stapel sind:

  • A0 bis A5
  • D0 bis D7
  • D8 bis D13

Wenn Sie nur ein paar weitere Interrupt-Pins wünschen, können Sie Tests vermeiden, indem Sie einfach Pins von verschiedenen verwenden Stapel (z. B. D4 und D8).


Weitere Informationen unter http://www.gammon.com.au/interrupts

Antwort

Es gibt zwei Arten von Interrupts. Was der Arduino-Spielplatz sagte:

Der Prozessor im Herzen eines Arduino verfügt über zwei verschiedene Arten von Interrupts: „extern“ und „Pinwechsel“. Es gibt nur zwei externe Interrupt-Pins am ATmega168 / 328 (dh im Arduino Uno / Nano / Duemilanove), INT0 und INT1, und sie sind den Arduino-Pins 2 und 3 zugeordnet. Diese Interrupts können so eingestellt werden, dass sie bei RISING oder ausgelöst werden FALLENDE Signalflanken oder auf niedrigem Pegel. Die Trigger werden von der Hardware interpretiert und der Interrupt ist sehr schnell. Das Arduino Mega verfügt über einige weitere externe Interrupt-Pins.

Andererseits können die Pin-Wechsel-Interrupts für viele weitere Pins aktiviert werden. Für ATmega168 / 328-basierte Arduinos können sie an einem oder allen 20 Signalpins des Arduino aktiviert werden; bei ATmega-basierten Arduinos können sie an 24 Pins aktiviert werden. Sie werden gleichermaßen an RISING- oder FALLING-Signalflanken ausgelöst. Es liegt also am Interrupt-Code, die richtigen Pins für den Empfang von Interrupts festzulegen, zu bestimmen, was passiert ist (welcher Pin? … ist das Signal gestiegen oder gefallen?) und es richtig zu handhaben.Darüber hinaus sind die Pinwechsel-Interrupts in 3 „Ports“ auf der MCU gruppiert, sodass nur 3 Interrupt-Vektoren (Subroutinen) für den gesamten Pin-Körper vorhanden sind. Dies macht das Auflösen der Aktion für einen einzelnen Interrupt noch komplizierter.

Grundsätzlich sind die externen Interrupts extrem schnell, da sie alle hardwarebasiert sind Es gibt jedoch auch die Pin-Wechsel-Interrupts, die jedoch viel langsamer zu sein scheinen, da sie größtenteils softwarebasiert sind.

tl; dr: Die 20 Interrupt-Pins zusammen sind viel langsamer. Die 2 Interrupt-Pins sind die schnellsten und effizientesten.


EDIT: Ich habe mir gerade das Datenblatt angesehen und es heißt, dass für alle der ausgewählten Pins ohne Angabe von ein Pinwechsel-Interrupt ausgelöst wird Welcher Pin hat sich geändert (obwohl er in drei Interrupt-Vektoren aufgeteilt ist).

  • Bei externen Interrupts wird angezeigt, dass Pin 3 gerade geändert wurde

li> Zum Ändern der PIN wird angezeigt, dass eine PIN geändert wurde, die Sie überwacht haben!

Der Pin-Wechsel-Interrupt fügt dem ISR viel Overhead hinzu, den Sie bewältigen müssen, indem Sie frühere Zustände speichern und prüfen, ob es sich um den Pin handelt, um den Sie sich Sorgen machen. Für einen Schlafzustand mag es in Ordnung sein, aber es ist besser, die externen Interrupts zu verwenden.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.