2

次の例(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で..)

編集:Avr-gccへの再投稿:UARTと競合するタイマー/カウンター割り込み?-Arduinoフォーラム

4

1 に答える 1

0

OK、ATMega168とATMega328で同じコードを再実行しました。期待どおりに機能します(メインループSerial.writeとISRルーチンの両方が実行されています)。したがって、これはATMEGA2560固有の問題である必要があり、プログラミング全般の問題ではありません...

編集:簡単な答えは-Timer0はすでにArduino APIによって使用されているため、別のタイマーを使用してください。

詳細については、Arduinoフォーラムの再投稿を参照してください)。

乾杯!

于 2011-08-10T16:41:43.907 に答える