arduino中带有noInterrupts()的void loop()预期不会表现出来

时间:2013-12-19 04:20:47

标签: 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
  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
...
...
100
code's here

输出我得到:

1
2
3
...
...
98
99
10

所以我的Serial.println("code's here")无效。我不明白为什么。实际上我的void循环中没有任何东西可以工作,而我这样编码。这noInterrupts实际上做了什么?

请给我一个解释。任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:0)

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

请注意,您最初得到的“10”是100的前两位数。将波特率提高到115200并获得整数100.因为串行ISR发生得更快。

您提到将上述代码更改为以下内容时修复了该问题。因为只有定时器中断停止,允许串行中断和其他继续打开。

void loop()
{
  if (index == 100)
  {
    Serial.println("code's here");
    //noInterrupts();
    TIMSK1 &= ~(1 << OCIE1A);
    while(1);
  }
}

故事的寓意是停止并具体开始。因为你可能不知道背景中究竟发生了什么。