Arduino e interrupciones: forma rápida de obtener valores de pin

11

Utilizo un Uno Arduino y ya configurarlo para que el trabajo con las interrupciones en los pines digitales 2, 3, 4 y 5 de acuerdo con una explicación 1 he encontrado.

void setup() contiene el siguiente código para configurar las interrupciones.

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

Y ahora, la función ISR (PCINT2_vect) se activa en cada interrupción. Eso funciona como un encanto. Mi pregunta es, ¿cuál es la mejor / más rápida forma de averiguar qué pin se activó?

Encontré algo en Re: ¿Es mejor usar ISR (PCINT2_vect) o attachInterrupt en los pines 2, 3? , pero no entiendo el código y no funciona de fábrica. Pero se ve impresionante ...

¿Cuál es la solución?

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

Editar:

En este momento, estoy leyendo el estado del pin del registro de pin de entrada:

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

Al final, quiero contar las interrupciones en los pines. Pero, ¿cómo puedo asegurar que no se cuentan dos veces?

madc
fuente
En electrónica, es probable que más personas hayan jugado con Arduinos y otras cosas electrónicas.
Earlz
Si piensa, la pregunta debería estar allí, márquela. Resolví mis problemas de inicio de sesión.
madc
3
@Earlz: Esta es una pregunta de programación, por lo que es sobre el tema . El hecho de que sea para una plataforma de aficionados es irrelevante; vea las cientos de otras preguntas de arduino en stackoverflow como referencia.
BlueRaja - Danny Pflughoeft

Respuestas:

4

Tengo una primera solución, pero no pude probar la fiabilidad ya que el hardware no está terminado.

Primero agregué oldPins y tickCount como variables globales:

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

Y así es como resolví el ISR en este momento. Mejores soluciones son más que bienvenidas.

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
fuente
1
Si está actualizando tickCount [] en un ISR, debería declararlo con el calificador de tipo 'volátil'.
icarus74
Actualicé el código dentro de la respuesta. Para obtener más información, consulte la documentación de arduino: arduino.cc/en/Reference/Volatile
madc