使用while循环时未触发中断ISR
Posted
技术标签:
【中文标题】使用while循环时未触发中断ISR【英文标题】:Interrupt ISR not triggering when using while loop 【发布时间】:2022-01-10 12:23:21 【问题描述】:当来自外部 ADC 的数据准备好时,我正在使用中断将标志变为 True。正在触发此中断,但是当我添加时:
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::read()
?我希望不是中断。
我看不出这段代码如何运行而不在 ESP32 上崩溃。 while(!dataReady);
应该触发看门狗定时器并重置 ESP32,如果它在那里停留超过几秒钟。
【参考方案1】:
MCP3464::MCP3464()
ch = 0;
attachInterrupt(digitalPinToInterrupt(dataReadyPin), dataReadyInterrupt, RISING);
您正在通过类构造函数设置中断,对于标准 C++ 类,这非常好。但是,对于 Arduino,尽管您没有提及实例化 Class 实例的方式和位置。但是如果你在setup()
之前创建了一个实例,你的构造函数运行了,而Arduino还没有初始化所有的管脚分配和系统初始化,你可以在Arduino Core的main函数中看到这一点。
这就是为什么大多数 Arduino 库使用 begin()
方法来设置库实例,而不是像 Arduino Style Guide for Writing Libraries 建议的那样使用类构造函数:
使用 begin() 来初始化库实例,通常带有一些设置。使用 end() 停止它。
还有一件事,我注意到您使用的是SPI.transfer()
而没有使用SPI.beginTransaction()
和SPI.endTransaction()
,这可能适用于单一的SPI 实例,或者如果您在总线上只有一个SPI 设备,但您可能当您有多个实例/设备时面临问题/问题。为此,我建议您阅读我对另一个问题的回答 here。
【讨论】:
非常感谢,已解决。这很有意义,很烦人 Arduino 与传统 c++ 相比有细微差别以上是关于使用while循环时未触发中断ISR的主要内容,如果未能解决你的问题,请参考以下文章