es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

La interrupción ISR no se activa cuando se utiliza un bucle while.

Estoy utilizando una interrupción para cambiar una bandera a Verdadero cuando los datos estén disponibles desde un ADC externo. Esta interrupción se está activando, sin embargo, cuando agrego:

“`c++
while(!dataReady);

<pre><code><br />para esperar a que la interrupción cambie la bandera a Verdadero, la función de interrupción ISR ya no se activa.
Aquí está mi código completo:
“`c++
static volatile bool dataReady = false;

void dataReadyInterrupt()
{
dataReady = true;
}

MCP3464::MCP3464()
{
ch = 0;
attachInterrupt(digitalPinToInterrupt(dataReadyPin), dataReadyInterrupt, RISING);
}

signed short MCP3464::read()
{
// Esperar a que la interrupción cambie dataReady a Verdadero antes de leer la siguiente conversión del ADC
while(!dataReady);
dataReady = false;
// Transferencia SPI full duplex
digitalWrite(adcChipSelectPin,LOW);
SPI.transfer(readConversionData);
adcReading = (SPI.transfer(0) << 8);
adcReading += SPI.transfer(0);
digitalWrite(adcChipSelectPin, HIGH);

ch++;

if (ch >= numOfCh)
{
ch = 0;
}

// Escribir el nuevo canal del ADC en el multiplexor
writeData(&muxRegisters[ch][0], 2);

// Iniciar la siguiente conversión (modo de conversión única)
writeData(&startConversionFastCmd, 1);

return adcReading;
}

Cualquier idea es muy apreciada.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Parece que el bucle while que espera a que la bandera dataReady se vuelva verdadera está evitando que la interrupción se active. Una posible solución es usar un semáforo en lugar de una simple bandera booleana. Un semáforo es una variable que se utiliza para señalar entre diferentes hilos o procesos, indicando la disponibilidad de un recurso. En este caso, el recurso es los datos del ADC externo.

    Para implementar un semáforo, podrías usar una variable contador que se incrementa cuando se activa la interrupción y se decrementa cuando los datos se leen. El bucle while que espera los datos puede verificar entonces el valor del contador en lugar de la bandera dataReady. Aquí tienes una versión modificada del código con un semáforo:

    static volatile int dataCounter = 0;
    
    void dataReadyInterrupt()
    {
      dataCounter++;
    }
    
    MCP3464::MCP3464()
    {
      ch = 0;
      attachInterrupt(digitalPinToInterrupt(dataReadyPin), dataReadyInterrupt, RISING); 
    }
    
    signed short MCP3464::read()
    {
      // esperar a que la interrupción incremente dataCounter antes de leer la siguiente conversión del adc
      while(dataCounter == 0);
      dataCounter--;
    
      // transferencia full duplex SPI
      digitalWrite(adcChipSelectPin,LOW); 
      SPI.transfer(readConversionData);
      adcReading = (SPI.transfer(0) << 8);
      adcReading += SPI.transfer(0);
      digitalWrite(adcChipSelectPin, HIGH);
    
      ch++;
    
      if (ch >= numOfCh)
      {
        ch = 0;
      }
    
      // Escribir el nuevo canal del ADC al multiplexor
      writeData(&muxRegisters[ch][0], 2);
    
      // Iniciar la siguiente conversión (modo de conversión única)
      writeData(&startConversionFastCmd, 1);
    
      return adcReading;
    }
    

    Este código debería permitir que la interrupción se active mientras se espera que los datos estén disponibles. ¡Avísame si tienes alguna otra pregunta!

Comments are closed.