chottoshitahanashi’s diary

基本的に間違ったことばかり書いてるブログ。検索ひっかかるな

delay(), SoftwareSerial, ウォッチドッグ, ATTiny85

ATtiny ウォッチドッグタイマ割込みでLEDチカチカ | 東京お気楽カメラ。こちらのコードに手を加えてソフトウェアシリアル追加すると通信はできたんだけどdelay()を使うと急に動かなくなった。delay()のコード内部見てもクロック数が合うように適当なダミーの計算してるだけで特にタイマーを使ってるようには見えない。なんでだ?LED点滅もしないんでどうもdelay()で止まってるように見える。


loop()の最後にあるこのコードでdelay()のコメントを一つでも外すと通信ができなくなる。

  cli();
  mySerial.println("HELLO from ATTiny85");
  sei();
  // delay(10);
  cli();
  mySerial.println("a");
  sei();
  // delay(10);
  cli();
  mySerial.println("b");
  sei();
  // delay(10);
  cli();
  mySerial.println("c");
  sei();


あーわかった。delay()がmicros()を読んでてmicros()がタイマを使ってて、元のコードが電力削減のため

PRR = 15;

セットしているためだった。データシート見るとPRRは

● ビット3 - PRTIM1 : タイマ/カウンタ1電力削減 (Power Reduction Timer/Counter1)
このビットへの1書き込みはタイマ/カウンタ1部を停止します。タイマ/カウンタ1が許可されると、停止前と同様に動作は継続します。
● ビット2 - PRTIM0 : タイマ/カウンタ0電力削減 (Power Reduction Timer/Counter0)
このビットへの1書き込みはタイマ/カウンタ0部を停止します。タイマ/カウンタ0が許可されると、停止前と同様に動作は継続します。

そりゃ駄目だ。


他にもシリアル通信に成功したり失敗したりするバグがあったけどLED消灯のコード

    PORTB = 0;

のせいだった。

    PORTB &= ~_BV(LED_PIN);

に替えて解決。