Pin Change InterruptはPORTごとに割り込みベクタが分かれているので、ロータリーエンコーダー用のポートとスイッチの列のポートを分けられれば少しは話は簡単になりそうだが、製作中のシーケンス入力用のデバイスは配線の都合で贅沢にポートを分けている余裕がない。
Pin Change Interrupt以外に普通の外部割込み(INT0、INT1)を使うことも一瞬考えたが、これはPD2、PD3に割り当てられていてPORTDはスイッチの列の入力に使う予定なのでこれもやめることにした。
しかたなくポーリングで処理することにした。(どうしても割り込みでというならタイマー・カウンターという手も残されているが・・・)
ブレッドボード図
表記はATMega168になっているがATMega88Vを使用。
ロータリーエンコーダーのABはPB2、PB3に、軸の押し下げのSWはPB1につないだ。
PD0..PD7につないだLEDでロータリーエンコーダーで入力した8bitの値を表示する。PC2、PC3につないだLED(左上あたりの2個)は割り込みごとにトグル表示する等デバッグ用に使った。
PB5につないだ黄色LEDはロータリーエンコーダーの軸の押し下げのSWでトグル表示する。
Atmel StudioのプロジェクトはGithubにあげました。
https://github.com/ryood/Rotary_Encoder_Debounce_Test
ロータリーエンコーダーのプラス・マイナスの読み取り値で、8bitのカウンタの値を増減して赤色LEDx8でそのまま表示している。
ロータリーエンコーダーの軸の押し下げスイッチで黄色LEDがトグル表示される。
PC2、PC3につないだLEDはそれぞれpin change interruptとTimer0オーバー・フロー割り込みでトグル動作するので、2chオシロで位相差を見ればチャタリング防止用のディレイ・タイムが確認できる。
Timer0とTimer2のプリスケーラ-
またいらんことでハマってしまった。Timer0とTimer2のプリスケーラーの値はTCCR0B/TCCR2BのCS20..CS22 bitで設定するが、設定する値が違う。
Timer2では0b111で1/1024になるが、Timer0で0b111を設定するとクロック・ソースを外部から与える設定になる。
最初Timer2でやっていて、Timer0に変更したらTimerが起動しなくなって相当悩んでしまった(^q^;;;
「AVRのPin Change Interruptとチャタリング対策」で設定したTimerの遅延時間の設定も間違えてた。忘れなかったら直します。
あとADCを割り込みで処理するテストをしたら、基板を作っていきたいと思う。
回路図
基板図
プリント基板なら2層でおさまりそうだが、手配線する予定なので変な感じの図になっています。
I2Cでの本体側とのやりとりは下記のようなものを想定中。
ロータリーエンコーダーは基本的にトラック切り替え(kick、snare、hihat等)に使う予定だが、軸の押し下げSWの切り替えでロータリーエンコーダーをどういう動作に変更するか考え中。
0 件のコメント:
コメントを投稿