Arduino und Interrupts: Schneller Weg, um Pin-Werte zu erhalten

Ich verwende ein Arduino Uno und habe es bereits so eingerichtet, dass es mit Interrupts an den digitalen Pins 2, 3, 4 und 5 gemäß einer Erklärung 1 arbeitet , die ich gefunden habe.

void setup()enthält den folgenden Code zum Einrichten der Interrupts.

  //Endable Interrupts for PCIE2 Arduino Pins (D0-7)
  PCICR |= (1<<PCIE2);

  //Setup pins 2,3,4,5
  PCMSK2 |= (1<<PCINT18);
  PCMSK2 |= (1<<PCINT19);
  PCMSK2 |= (1<<PCINT20);
  PCMSK2 |= (1<<PCINT21);

  //Trigger Interrupt on rising edge
  MCUCR = (1<<ISC01) | (1<<ISC01);

Und jetzt wird die ISR(PCINT2_vect)-Funktion bei jedem Interrupt ausgelöst. Das funktioniert wie ein Zauber. Meine Frage ist, wie finde ich am besten/schnellsten heraus, welcher Pin ausgelöst wurde?

Ich habe etwas in Re gefunden: Ist es besser, ISR (PCINT2_vect) zu verwenden oder Interrupt an den Pins 2, 3 anzubringen? , aber ich verstehe den Code nicht und er funktioniert nicht out of the box. Aber es sieht beeindruckend aus...

Was ist die Lösung?

[2] http://arduino.cc/forum/index.php/topic,72496.15.html#lastPost

Bearbeiten:

Im Moment lese ich den Pin-Status aus dem Eingangs-Pin-Register:

  if (PIND & 0b00000100)
    Serial.println( "PIN 2" );
  if (PIND & 0b00001000)
    Serial.println( "PIN 3" );
  if (PIND & 0b00010000)
    Serial.println( "PIN 4" );
  if (PIND & 0b00100000)
    Serial.println( "PIN 5" );

Am Ende möchte ich die Interrupts auf den Pins zählen. Aber wie kann ich sicherstellen, dass keine doppelt gezählt werden?

Bei der Elektronik haben wahrscheinlich mehr Leute mit Arduinos und anderen elektronischen Dingen herumgespielt.
Wenn Sie der Meinung sind, dass die Frage dort drüben stehen sollte, markieren Sie sie. Ich habe meine Anmeldeprobleme gelöst.
@Earlz: Dies ist eine Programmierfrage, also ist es themenbezogen . Die Tatsache, dass es sich um eine Bastlerplattform handelt, ist irrelevant; Sehen Sie sich die Hunderte anderer Arduino-Fragen zu Stackoverflow als Referenz an.

Antworten (1)

Ich habe selbst eine erste Lösung, aber ich konnte die Zuverlässigkeit nicht testen, da die Hardware noch nicht fertig ist.

Zuerst habe ich oldPins und tickCount als globale Variablen hinzugefügt:

static byte oldPins = 0;
volatile unsigned int tickCount[4] = { 0, 0, 0, 0 };

Und so habe ich die ISR im Moment gelöst. Bessere Lösungen sind mehr als willkommen.

ISR( PCINT2_vect ) {
  //Read values from digital pins 2 to 7
  const byte actPins = PIND;
  //Match this values agaist the oldPins bitmask (XOR and AND for raising edge)
  const byte setPins = (oldPins ^ actPins) & actPins;

  if (setPins & 0b00000100)
    tickCount[0]++;
  if (setPins & 0b00001000)
    tickCount[1]++;
  if (setPins & 0b00010000)
    tickCount[2]++;
  if (setPins & 0b00100000)
    tickCount[3]++;

  oldPins = actPins;
}
Wenn Sie tickCount[] in einem ISR aktualisieren, sollten Sie es mit dem Qualifikationsmerkmal „flüchtig“ deklarieren.
Ich habe den Code in der Antwort aktualisiert. Weitere Informationen finden Sie in der Arduino-Dokumentation: arduino.cc/en/Reference/Volatile