Arduino and Interrupts: Szybki sposób na uzyskanie wartości pinów

11

Używam Arduino Uno i już skonfigurowałem go do pracy z przerwaniami na pinach cyfrowych 2, 3, 4 i 5 zgodnie z wyjaśnieniem 1 , które znalazłem.

void setup() zawiera następujący kod do ustawienia przerwań.

  //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);

A teraz funkcja ISR (PCINT2_vect) jest uruchamiana przy każdym przerwaniu. To działa jak urok. Moje pytanie brzmi: jaki jest najlepszy / najszybszy sposób, aby dowiedzieć się, który pin został wyzwolony?

Znalazłem coś w Re: Czy lepiej użyć ISR (PCINT2_vect) lub dołączyć Przerwanie na pinach 2, 3? , ale nie rozumiem kodu i nie działa on od razu po wyjęciu z pudełka. Ale wygląda imponująco ...

Jakie jest rozwiązanie?

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

Edytować:

W tej chwili czytam stan pinów z wejściowego rejestru pinów:

  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" );

Na koniec chcę policzyć przerwania na pinach. Ale jak mogę zapewnić, że nie ma dwóch liczonych?

madc
źródło
W elektronice coraz więcej osób prawdopodobnie bawiło się Arduinos i innymi elektronicznymi rzeczami.
Earlz
Jeśli uważasz, że pytanie powinno tam być, oflaguj je. Rozwiązałem problemy z logowaniem.
madc
3
@Ellz: To jest pytanie programistyczne, więc jest na temat . Fakt, że jest to platforma dla hobbystów, nie ma znaczenia; zobacz setki innych arduino pytań dotyczących stackoverflow w celach informacyjnych.
BlueRaja - Danny Pflughoeft

Odpowiedzi:

4

Sam mam pierwsze rozwiązanie, ale nie mogłem przetestować niezawodności, ponieważ sprzęt nie jest skończony.

Najpierw dodałem oldPins i tickCount jako zmienne globalne:

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

I tak w tej chwili rozwiązałem ISR. Lepsze rozwiązania są mile widziane.

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
źródło
1
Jeśli aktualizujesz tickCount [] w ISR, powinieneś zadeklarować go za pomocą kwalifikatora typu „niestabilnego”.
icarus74,
Zaktualizowałem kod w odpowiedzi. Aby uzyskać więcej informacji, zobacz dokumentację arduino
madc