次の例(Arduino IDE 0022、Ubuntu 11.04、Arduino AtMEGA 2560で試してみました)を検討してください。ここでは、タイマー/カウンター割り込みを開始Serial
し、同時にArduinoクラスを使用しようとしています。
volatile uint8_t sreg;
// Timer 0 interrupt routine
ISR(TIMER0_COMPA_vect, ISR_NAKED)
{
sreg = SREG; /* Save global interrupt flag */
cli(); /* Disable interrupts */
digitalWrite(34, not((bool)digitalRead(34)));
SREG = sreg; /* Restore global interrupt flag */
reti(); // must for ISR: return and enable interrupt
}
void setup() {
pinMode(13, OUTPUT);
pinMode(34, OUTPUT);
Serial.begin(115200);
Serial.println("Hello from setup");
delay(200);
}
void loop() {
digitalWrite(13, HIGH);
Serial.println("Hello from loop: A");
digitalWrite(13, LOW);
delay(200);
digitalWrite(13, HIGH);
#if 1 // register update part
cli(); // disable interrupts
GTCCR = 0b10000011; // halt timers
// set up Timer/Counter 0
TCCR0A = 0b00000010; // CTC; normal mode (don't use output pin)
TCCR0B = 0b00000101; // no force output; CTC; ... and clock select: prescale 1024
TCNT0 = 0; // init the actual counter variable
TIMSK0 = 0b00000010; // enable (only) Compare Match A Interrupt
OCR0A = 125; //the top value, to which the running counter is compared to
GTCCR = 0b00000000;
sei(); // Enable interrupts once registers have been updated
digitalWrite(13, LOW);
delay(200);
#endif
digitalWrite(13, HIGH);
Serial.println("Hello from loop: B");
digitalWrite(13, LOW);
delay(200);
}
例のように、シリアルによる印刷は次のようになります。
Hello from setup
Hello from loop: A
Hello from loop: B
Hello from loop: A
Hello from loop: B
...その後、すべての処理が停止します(LEDピン13と34の両方にアクションがないことで示されます)。おそらく、これはチップの世界ではBSODと呼ばれるものです:)表面的には、ISRルーチンが初めて開始されるとすぐに停止が発生します。
「レジスタ更新部分」を取り出すと、シリアルプリントアウトは予想どおりに永久に実行されます。また(予想どおり)、ISRは実行されません。ただし、「レジスタ更新部分」が残っていて、Serial.println(...
代わりに2つの「」行がコメント化されている場合(プログラムは「Hellofrom setup」のみを出力します)、割り込みは実行されます(ピン34のパルスによって証明されます)。
これは、ATMega2560でタイマーISRとUARTを同時に実行することはできないことを示しているようです。これは、以前にATMega328で同じ種類のアプローチを使用して成功したことを考えると、ばかげています。
だから、私がやりたいこと(シリアルプリントアウトとピンパルスの両方を持っている)がこのアーキテクチャでは基本的に不可能かどうか迷っています-それともセットアップに何かが欠けているだけですか?
よろしくお願いします、乾杯!
(このSerialクラスは実際にはArduino IDEパッケージのHardwareSerial.cppのクラス定義で動作し、このクラスは受信USART割り込みルーチンを定義します。これが問題になる可能性があると考えましたが、同じアプローチを使用しました。私がそれが機能するのを見たATMega328で..)