Timer arduino中带有noInterrupts()的void循环()的行为不符合预期

Timer arduino中带有noInterrupts()的void循环()的行为不符合预期,timer,arduino,interrupt,interrupt-handling,Timer,Arduino,Interrupt,Interrupt Handling,为了描述我的问题,我在这里与arduino共享一个简短的代码: int index=0; void setup() { Serial.begin(9600); noInterrupts(); TCCR1A=0; // RESET TCCR1B=0; //RESET TCNT1=0; TCCR1B |= (1<<CS12); // clk/256 prescaling TCCR1B |=(1<<WGM12); // ctc mode

为了描述我的问题,我在这里与arduino共享一个简短的代码:

int index=0;

void setup()
{
  Serial.begin(9600);
  noInterrupts();
  TCCR1A=0; // RESET
  TCCR1B=0; //RESET
  TCNT1=0;

  TCCR1B |= (1<<CS12);  // clk/256 prescaling
  TCCR1B |=(1<<WGM12);  // ctc mode
  OCR1A= 6250;          // 10 Hz
  TIMSK1 |=(1<<OCIE1A);
  interrupts();
}

ISR(TIMER1_COMPA_vect)
{
  index++;
  Serial.println(index);
}

void loop()
{
  if (index == 100)
  {
    Serial.println("code's here");
    noInterrupts();

  }
}
我得到的输出:

1
2
3
...
...
98
99
10
所以我的
Serial.println(“代码在这里”)
不起作用。我不明白为什么。事实上,我的void循环中没有任何东西可以工作,而我是这样编码的。这个
noInterrupts
实际上是做什么的


请给我一个解释。非常感谢您的帮助。

您使用的是硬件串行,而硬件串行又使用中断进行传输。Serial.print填充一个缓冲区,然后启用发送器空中断,以便在代码继续运行时,每次中断都会在后台发送每个字符。因此,仅在Serial.print之后noInterrupts()立即停止所有中断,没有时间开始变送器中断。因此你什么也得不到

请注意,您最初在末尾得到的“10”是100的前两位数字。把波特率提高到115200,你就得到了整个100。因为串行ISR发生得更快

其中,正如您所提到的,将上述代码更改为以下代码可以修复此问题。只有定时器中断停止,允许串行中断和其他中断继续

void loop()
{
  if (index == 100)
  {
    Serial.println("code's here");
    //noInterrupts();
    TIMSK1 &= ~(1 << OCIE1A);
    while(1);
  }
}
void循环()
{
如果(索引==100)
{
Serial.println(“代码在这里”);
//无中断();

TIMSK1&=~(1)然后发布你的答案?为什么你会说你只是解决了问题而没有给出解决方案?如果其他人也提出了同样的问题怎么办?alryt我刚刚找到了一种解决方法,我必须包括“TIMSK1&=~(1”#define noInterrupts()cli()“正如在\hardware\arduino\cores\arduino\arduino.h中找到的。因此它没有什么特别之处。只需禁用所有中断。同样地,“#define interrupts()sei()”将它们重新打开。
void loop()
{
  if (index == 100)
  {
    Serial.println("code's here");
    //noInterrupts();
    TIMSK1 &= ~(1 << OCIE1A);
    while(1);
  }
}