I2Cがうまくいかない2
I2Cがうまくいかない2
はてなグループの終了日を2020年1月31日(金)に決定しました - はてなグループ日記 - 機能変更、お知らせなど からの続き。
ATtiny85でやってたUSIなI2CスレーブのプロジェクトからI2Cの通信部分だけをATtiny2313に持ってきて試してみました。マスタにはArduinoのWire関数を使ったものを使用。
AVR312をWinAVRに修整したしたもので、デバイスの定義名とか割り込みまわりとかベクタ名とか直して、動かしてみたら、SCLが変;
5μsec(100kHz通信時のクロックのパルス幅)よりもはるかに狭い棘状のパルスが出ていたり、
というのはあいかわらずだったので、AVR312中で、SCLのポートが出力になっているのを止めたところ波形の棘状パルスはなくなりました。
とりあえずAVR312のサンプルと同じ、
- 1byte受信して送信し返す
というのはうまくいきましたエコーバックは通信の基本?
もう少しスレーブをいじって、
- 1byte受信して、特定のデータだったら数バイト送信し返す
というのもうまくいきました、マスタとスレーブでやり取りするバイト数は合わせておいて。
しかしながら
- 1byte受信して、特定のデータだったらさらなる数バイト(固定長)を受信する。全部受信したら送信し返す
というのがうまくいきません。
マスタ側動作は、
Wire.beginTransmission(TEST); Wire.send(0xAA); Wire.send(0x01); Wire.send(0x02); Wire.send(0x03); Wire.send(0x04); Wire.endTransmission(); Wire.requestFrom(TEST, 5);
みたいな感じで書いているんですが、オシロでバスを見ると、
[SLA+W] [0xAA] [SLA+R] SDAがLOW・SCLクロックなしで通信途絶
という感じ。0xAAのときクロックパルス数は8発でACK/NACKが授受されているのか不明。0x01/0x02/0x03/0x04の送信はどうした、マスタ。[SLA+R]が発行されてもスレーブはデータバッファが空なのでスタートコンディション待ちにリセットされています。互いにREAD待ち待ち状態でデッドロック。
ちなみに1バイト Wire.sendのたびごとに beginTransmission, endTransmission で閉じたらうまくいきました。データをバッファにつめて Wire.send(tbuf, 5) みたいに送っても、ACK/NACKを見ないで1バイト目のあと[SLA+R]を発行するマスタ。
なんでそんなところで[SLA+R]が発行されるのかしら。Wireライブラリのコードを読まなきゃだめかなぁ。
と、書いているうちに 通信途絶についてはスレーブがSDA(のポート)を握ったままになっているのかもという気がしてきました、おそらくは0xAA の ACK/NACK用パルスが来ない時点で。また診てみようと思います。
追記
0xAAのところでACK/NACKを見ていないんじゃないかの件、マスタがSCLの立ち上がりエッジで取るなら問題ないのだと理解しました。『マイコンの1線2線3線インターフェース活用入門』にもそういう波形が出ていました。