https://github.com/ryood/RhythmMachine/blob/master/Atmel%20Stduio/Sequencer_I2C_Slave/Sequencer_I2C_Slave/Sequencer_I2C_Slave.c
ブレッドボード図
※AVRはATMega88Vです。
チャタリング対策
タクトスイッチとロータリーエンコーダーの軸の押し下げのスイッチは、タイマーを使って20m秒後の状態と比較して変化がなければチャタリングではないと判断しているが、時々読みこぼすことがあるみたいなのでオシロで動作状態を見てみた。
スイッチの状態を読み取ったあと、Timer0をオーバー・フロー割り込みさせるモードでワンショットで起動している。
// Timer0を起動TCNT0が255を超えたときオーバー・フロー割り込みがかかるので、TCNT0=0だと
TCCR0B = 0x05; // プリスケーラ-:1024, 1/(8MHz/1024)=128us
TCNT0 = 100; // 128us*(256-100)=19.968ms
128us * (256 - 0) = 32.768msTCNT0 = 255だと
128us * (256 - 255) = 0.128msになる。(実際はその他の処理が入るのでもう少し長くなる)
TCNT0 = 0の場合
赤色はLEDの列の一番左、黄色はPD0(タクトスイッチの一番左)
黄色がH->Lの変化する地点から、赤色がL→Hに変化する地点の差を目盛りで読み取ると、だいたい32ms
TCNT0 = 255の場合
同様に差を読み取るとだいたい200us=0.2msだ。
Timer0による遅延は想定通り動いているようだ。
読みこぼしの原因は、コードのその他の部分に何かバグがあるかもしれないし、スイッチ自体の動作不良かも?
I2Cの送信データ
No. | Sign | Size(bit) | Name | 説明 | 備考 |
---|---|---|---|---|---|
1 | unsigned | 16 | SEQUENCE | Sequence 1..16 | 1バイト目のLSBがシーケンス1 2バイト目のLSBがシーケンス9 |
2 | unsigned | 8 | POT1 | Pot1のADC読み取り値 | 0..255 |
3 | unsigned | 8 | POT2 | Pot2のADC読み取り値 | 0..255 |
4 | unsigned | 8 | RE | ロータリーエンコーダーの値 | 0..255 |
5 | unsigned | 8 | RE_SW | ロータリーエンコーダーのSWの押し下げ状態。 | 0: 開放 1:押し下げ |
Masterから送信要求があれば、毎回上記6バイトを送信する。
基板上で入力した値は、基板上で視認できるようにしたつもりだ。(POTはつまみの位置で)
はんだ付けはとても疲れるのでぼちぼち進めたいとおもいます。
割り込みとRTOS
今回ぐらいの規模なら割込みを逐一処理しても大丈夫だったが(と言って、ロータリーエンコーダーの処理はポーリングで行っていますが)、これ以上複雑になってくるとRTOSを使った方が良さそうな気もする。
スイッチの押し下げ状態の割込みにはAVRのPin Change Interruptを使ったが、これもTimer割込みで処理しようとすると割込みルーチンの中の処理がかなり複雑になってくる。
FreeRTOSという無償のRTOSがあって、ちょっと調べた感じではスケジューリングに特化していて軽量コンパクトな作りになっているようだ。
音源の波形生成みたいなタイミングにシビアなシステムには使いにくいが、UIの制御みたいなのにはありかも。もっと複雑なことをしたくなった場合は考えてみようと思います。
0 件のコメント:
コメントを投稿