発振器を作る―第3回
発振器を作る―第3回
引き続きATtiny85版を検討した。
前回の、
しかしながら今回の用途にはこのポーリングが良くないようだ。1クロック命令と2クロック命令とのハザマで、タイマの割り込みが256ステップになったり257ステップになったり。 はてなグループの終了日を2020年1月31日(金)に決定しました - はてなグループ日記 - 機能変更、お知らせなど
という問題に対して、通常はメインで単純ループにしておいて、I2Cの通信が始まったらポーリングする世界に飛ばせばいいのではないか。複数の割り込みを組み合わせて使う技で(細かい話は後述)。
その中でピンチェンジ割り込みを使うのだけど、シミュレーションしてみたらうまくいかなかった。ていうかそれ以外のも意図したとおり動かない。マニュアルを読んだら、ATtiny25/45/85では AVR Studioに入っているうちで AVR Simulator2 を使えという。それでもうまくいかなかったところ新版のAVR Studioが出ているということだったのでバージョンアップ。
4.14だったものを4.15にしてみたらうまくいった。
しかしながらリセットピン機能が有効なときには同居のPCINT5ピンのピンチェンジは検知できなくて、未使用予定のPCINT4を使うことにしてようやく複合割り込み芸をマスターした。
I2Cの制御仕様を考えて、次はそろそろ実チップに焼いて実験しようか…
ところで前回、
試してみたところではけっこうぎりぎりかも。
と書いていた部分は処理の書き方を変えることで大幅短縮できるようになった(これも細かい話は後述)。
(つづく)
発端
足跡
- はてなグループの終了日を2020年1月31日(金)に決定しました - はてなグループ日記 - 機能変更、お知らせなど
- はてなグループの終了日を2020年1月31日(金)に決定しました - はてなグループ日記 - 機能変更、お知らせなど
おまけの細かい話
複合割り込み芸
ATMELのAVR312を一部改造する。
- TWI Start Conditionの割り込みがきたらその中でPCINT割り込みを起こす
- これでメインループに戻ってもすぐにPCINT割り込みサービスルーチン(ISR)に飛ぶ
- PCINT ISRでは多重割り込み可にしておいて、
- サンプルレート出力の timer0割り込みを止める
- 出力値もニュートラルに落としておいたほうがいいかも
- PCINT ISR中でループで回し、TWI受信バッファのポーリングを行い、値があったらバッファに積む
- TWI Stop Condition を検知したらループから脱出する
- TWIで受信したデータを処理する
- timer0割り込みの再開処理をしてPCINT ISRから抜ける
- サンプルレート出力の timer0割り込みを止める
短縮の件
ptr = Osc.acc>>20; OCR1A = pgm_read_byte(&tblSine[ptr]); Osc.acc += Osc.ph;
の1行目。20ビットシフトで書くよりも
tmp = Osc.acc / 65536; ptr = tmp>>4;
と書いたほうがステップ数が少なかった。Osc.accはuint32_t型、ptr, tmp はuint16_t型。