I2Cバスを見える化
■絶妙なプロトコルと思えるI2C
- SCL クロック
- SDA データ
この2本でシリアル・データ通信を行います。クロックはいつも一定ではなくLow時間を引き延ばしたりできる柔軟な規格です。ArduinoではWireライブラリを使ってセンサやLCDと通信を行います。
●スタートとストップがひとかたまり
SDAとSCLの信号線は、電源へプルアップされています。したがって、常にHigh状態です。マスタ(Arduino)がI2Cの通信を始めようとすると、次の一連のやり取りをします。
- SCLがHighのときにSDAをLowにする。スタート・コンディションと呼ぶ
- マスタは、MSBから順に通信したいスレーブ・デバイスのアドレスを7ビットで送る(0x3e)。最後に1ビットWrite ('1')を付け加える
- ずっと自分のアドレスが送られてくるのを待っているLCDが自分のアドレスだと認識し、ACK(Low)を1ビット出す
- マスタは、スレーブが反応したので、最初の1バイト(0x00)を送る
- スレーブのLCDはデータを受け取ったとACKを返す
- マスタは、続いて1バイト(0x01)を送る
- スレーブのLCDはデータを受け取ったとACKを返す
- マスタは、必要な2バイトをLCDへ送ったので、SCLがHighのときにSDAをLowからHighにする。これがストップ・コンディションで、一連の通信が終わる
上記の2バイトを送る動作を繰り返し、最終的に、下記のデータをLCDが受け取ります。下の段はASCIIコードに変換したデータです。
00 01 40 54 40 65 40 6D 40 70 40 3D 40 31 40 36 40 27 40 43 T e m p = 1 6 ' C |
最初の00はLCDへのコマンド、01は画面クリアです。以降、40はデータを送るというコマンドです。
上記はLCDとの通信でした。センサなどでは、次の手順が多いです。
①スリープしているのを起こしたり、デフォルトではないモードに切り替えたいために、1ビットもしくは2バイトのコマンドをスレーブに送る。送らなくてもよいデバイスもある。
②スレーブの温度などのデータの保存されているレジスタを1バイトもしくは2バイトで指定して、データを、1バイトもしくは2バイト、それ以上読み出す。
フォローしませんか?