使用 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。
当数据从外部 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。