在Arduino上禁用定时器0中断而不会断开串行

时间:2015-03-28 00:30:18

标签: c++ arduino embedded interrupt

背景:

我需要在Arduino环境中为自己的ISR提供非常可重复的中断执行时序。 Arduino核心库使用Timer0溢出中断来提供millis()。偶尔,在执行Timer0溢出中断时,会遇到触发我的中断的条件。默认情况下,AVR不允许一个中断“中断”另一个中断。请参阅此Nested interrupts question

Timer0 ISR阻止我的ISR执行直到它完成。此延迟可能需要7μs,这在我的应用中是不可接受的。 (我知道!)

我的应用程序中不需要millis(),所以我尝试在void setup()内禁用Timer0溢出中断:

TIMSK0 = 0;

陷阱:不幸的是,这会破坏硬件串行功能。我查看了核心库源代码,但我不明白硬件串行方法如何依赖于Timer 0。

约束:我希望我的草图能够编译并使用标准的Arduino发行版,因此我只能控制草图目录(而不是Arduino目录)中的内容,而Arduino草图隐藏“包含”来自你,所以我不确定我是否可以避免使用“HardwareSerial.h”。

确切问题:

  1. Serial类如何依赖Timer0?
  2. 有没有办法在不修改核心库的情况下再次调用“Serial”类?
  3. 一般来说,我可以重新定义(或整个)其他地方定义的类的方法吗?

1 个答案:

答案 0 :(得分:1)

串行工作虽然你禁用了Timer 0.这个简单的实验得出结论。

#include "avr/pgmspace.h"
#include "avr/io.h"

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))


void setup() {
  Serial.begin(9600);
  cbi (TIMSK0, TOIE0); // disable Timer0 !!! delay() is now not available
}

void loop() {
  if (Serial.available()){
    Serial.write(Serial.read());
  }
  delay(1000);              // this is not working since Timer 0 disabled
}