使用 while 循环时不触发中断 ISR

Interrupt ISR not triggering when using while loop

当数据从外部 ADC 准备就绪时,我正在使用中断将标志变为真。正在触发此中断,但是当我添加时:

while(!dataReady); 

等待中断改变标志为True,中断ISR函数不再触发。 这是我的完整代码:

static volatile bool dataReady = false;

void dataReadyInterrupt()
{
  dataReady = true;
}

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

signed short MCP3464::read()
{
  // wait for interrupt to turn dataReady True before reading next adc conversion
  while(!dataReady);
  dataReady = false;
  // SPI full duplex transfer
  digitalWrite(adcChipSelectPin,LOW); 
  SPI.transfer(readConversionData);
  adcReading = (SPI.transfer(0) << 8);
  adcReading += SPI.transfer(0);
  digitalWrite(adcChipSelectPin, HIGH);

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

  // Write the new ADC channel to multiplexer
  writeData(&muxRegisters[ch][0], 2);

  // Start the next conversion (single conversion mode)
  writeData(&startConversionFastCmd, 1);
  
  return adcReading;
}

非常感谢任何想法。

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

您正在通过 class 构造函数设置中断,对于标准 C++ Class,这完全没问题。但是,对于 Arduino,尽管您没有提到如何以及在何处实例化 Class 实例。但是如果你在 setup() 之前创建一个实例,你的构造函数 运行,并且 Arduino 还没有初始化所有的引脚分配和系统初始化,你可以在 main 函数中看到这一点Arduino 内核。

这就是为什么大多数 Arduino 库使用 begin() 方法来设置库实例,而不是像 Arduino Style Guide for Writing Libraries 建议的那样使用 class 构造函数:

Use begin() to initialize a library instance, usually with some settings. Use end() to stop it.

还有一件事,我注意到您在使用 SPI.transfer() 而没有使用 SPI.beginTransaction()SPI.endTransaction(),这可能适用于单个 SPI 实例,或者如果您只有一个 SPI总线上的设备,但当您有多个 instances/devices 时,您可能会面临 problem/issue。为此,我建议您阅读我对另一个问题的回答 here