我有一个Arduino Mega应用程序,我可以在各种占空比下读取低频脉冲(约10Hz)的时序。
我使用外部中断捕捉脉冲,将信号更改时间信息添加到我完成时读回的16位数组[320]中。
我通过将第一个上行更改的时间设置为时间0来标准化时间。 请参阅附加简化代码段(使用Arduino Mega进行工作测试,引脚D2)。
问题:复位后的第一个完整周期按预期读取时序,而每个后续周期只有第一个脉冲正常,而所有下一个脉冲的时序随机移动。
我已经测试过,并尝试了很多选项,包括volatile和只在变化上中断,但总是得到相同的结果:第一次运行是OK,下一次运行被移位。
任何想法将不胜感激。ATMega AVR外部中断
/*Program reads input pulses at D2 and builds timing array of the up and
down going signals, using change interrupts on pin D2 of Mega
To run, send array size in hex.
by Sam Tal [email protected] Nov 9, 2017
*/
#define interruptPin 2
unsigned int dataArraySize;
unsigned int timeData[320];
volatile byte state = LOW;
unsigned int counts = 0 ; //Changes counter
unsigned long startTime; //The first up going interrupt time.
//==========================================================
void setup()
{
Serial.begin(115200);
pinMode(interruptPin, INPUT);
}
//=========================================================
void loop()
{
if (Serial.available())
{
dataArraySize = Serial.read();
StartCycle();
}
}
//========================================================
void StartCycle(void)
{
Serial.println("Starting cycle...");
//Reset the time array;
memset (timeData, 0, dataArraySize);
counts = 0 ;
state = LOW;
attachInterrupt(digitalPinToInterrupt(interruptPin), Step, RISING);
}
//========================================================
void Step()
{
detachInterrupt (digitalPinToInterrupt (interruptPin));
if (counts == 0)
{
startTime = millis(); // Start time of the first rising change.
}
if (counts < dataArraySize)
{
timeData[counts] = millis() - startTime ;
counts++;
attachInterrupt(digitalPinToInterrupt(interruptPin), Step, CHANGE);
}
else
{
detachInterrupt (digitalPinToInterrupt (interruptPin));
SendData(timeData, dataArraySize);
}
}
//===========================================================
void SendData(unsigned int data[] , unsigned int arraysize)
{
int f;
for (f = 0; f < arraysize ; f++)
{
Serial.print(f);
Serial.print(",") ;
Serial.println(data[f]);
}
}
Simillar to @aMike我也会从我个人的经验中推荐不要在中断处理程序中使用Serial.print()。通常,串行打印语句需要几毫秒才能执行。所以如果你运行时间约束算法,不要在中断处理程序中打印。 – Sma
在这种情况下,中断处理程序(ISR)是Step()函数。该功能内没有打印。此外,每次输入ISR时都会禁止中断。 为什么你声称在ISR中有打印命令? – samtal