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

11

Ich benutze 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 funktioniert, 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 bei jedem Interrupt die ISR-Funktion (PCINT2_vect) ausgelöst. Das funktioniert wie ein Zauber. Meine Frage ist, was ist der beste / schnellste Weg, um herauszufinden, welcher Pin ausgelöst wurde?

Ich habe etwas in Re gefunden: Ist es besser, ISR (PCINT2_vect) oder attachInterrupt an den Pins 2, 3 zu verwenden? , aber ich verstehe den Code nicht und es funktioniert nicht sofort. 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 an den Pins zählen. Aber wie kann ich versichern, dass es keine zweimal gezählten gibt?

madc
quelle
In der Elektronik haben wahrscheinlich mehr Leute mit Arduinos und anderen elektronischen Dingen herumgespielt.
Earlz
Wenn Sie denken, die Frage sollte dort drüben sein, markieren Sie sie. Ich habe meine Login-Probleme gelöst.
Madc
3
@Earlz: Dies ist eine Programmierfrage, also zum Thema . Die Tatsache, dass es sich um eine Hobbyplattform handelt, spielt keine Rolle. Weitere Informationen finden Sie in den Hunderten anderer Arduino-Fragen zum Stackoverflow .
BlueRaja - Danny Pflughoeft

Antworten:

4

Ich habe selbst eine erste Lösung, aber ich konnte die Zuverlässigkeit nicht testen, da die Hardware 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 im Moment den ISR 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;
}
madc
quelle
1
Wenn Sie tickCount [] in einem ISR aktualisieren, sollten Sie es mit dem Qualifikationsmerkmal 'volatile' deklarieren.
icarus74
Ich habe den Code in der Antwort aktualisiert. Weitere Informationen finden Sie in der Arduino-Dokumentation: arduino.cc/en/Reference/Volatile
madc