I2C

概要

I2C(I squared C)はフィリップス社で開発されたシリアルバス。正式な呼称はInter-Integrated Circuitの略で表記はI2Cと上付きが本来とのこと。

マスターに対して1つ以上のスレーブを繋ぐことができて、接続はクロック線(SCL)とデータ線(SDA)の2本だけで済む。マスターからスレーブを指定して、Read/Write信号によりデータを書き込んだり読み込んだりすることができる。

原理(マスターからスレーブへの書き込み)

ビットデータの転送

データはクロック信号に同期してビット情報を転送。SCLの立ち上がり開始から立ち下がり開始までの間にデータを転送する。データを変更(H ⇔ L)する場合には、SCLがLの間にSDAを変更する。

スタートコンディション/ストップコンディション

データ転送のためSCLがHの間にSDAは変化させないが、この間にSDAが変化した場合は不正・無効ではなく、スタートコンディション/ストップコンディションの意味を持つ。

SDAがH→Lに変化した場合はスタートコンディションで、SCLがH→LになったあとLの間に最初のビットの準備をする。

SDAがL→Hに変化した場合はストップコンディションで、その前にSCLがLの間にSDAをLにしてストップコンディションの準備をする。

バイトデータの転送

データはバイト単位で転送される。

マスターからスレーブへの書き込みの場合、フォーマットは以下の様になる(スレーブアドレスが7ビットの場合)。

  1. マスターからスタートコンディション、スレーブアドレス7ビット、RW = 0を送信
  2. 指定されたアドレスのスレーブからACK送信→マスターで受信
  3. マスターから1バイトのデータを送信
  4. スレーブがデータ受信後、ACK送信→マスターで受信
  5. 以降、必要バイト数を送信
  6. 送信終了後、マスターからストップコンディション送信

マスターがスレーブのデータを読み込む場合には、フォーマットは以下の様になる。

  1. マスターからスタートコンディション、スレーブアドレス7ビット、RW = 1を送信
  2. 指定されたアドレスのスレーブからACK送信→マスターで受信
  3. スレーブから1バイトのデータを送信
  4. マスターが受信後、ACK送信→スレーブで受信
  5. 以降、必要バイト数を受信
  6. 受信終了後、マスターからストップコンディション送信

スレーブアドレス送信とRW

マスターからスレーブに対してスタートコンディションを送信し、各スレーブが受信体勢に入る。その後マスターからスレーブアドレスを送信する。

スレーブアドレスが7ビットの場合、MSBから順に7ビット送り、最後にRWを1ビットで送る。RW=1のときマスター側が読み取り、RW=0のときマスターからスレーブへ書き込み。

ACK

I2Cのデータは8ビット単位で転送され、その後にACK/NACKが返される。マスターからスレーブへの書き込みの場合ACKはスレーブからバスに発信され、マスターがスレーブから読み出す場合はマスターから発信される。

スレーブアドレス指定の際、選択されたスレーブはACK信号を1ビットのLで返す。選択されなかったスレーブはストップコンディションを待機。何らかの理由でスレーブ側がデータを受け取れなかったときはNAK信号を1ビットのHで返す。

マスターからスレーブへデータを書き込む場合、8ビット目の送信後にSCLをLにし、スレーブからACKを受け取ってから次のデータの送信を開始する。

マスターがスレーブからデータを読み込む場合、アドレスは上記と同じだが、データについてはマスターがデータ受信後にACKを送る。

ただしスレーブ側で次のクロックサイクルに合わせてデータを送るのに間に合わない場合、スレーブ側でSCLを強制的にLにして、マスターでのデータ読み込みを抑制する(クロックストレッチ)。スレーブの準備完了後にクロックストレッチは解除され、データの読み込みが再開される。

I2Cの有効化

Raspberry PiでI2Cを有効化する手順。

  1. コマンドラインでsudo raspi-configを実行
  2. 画面が変わるので、5 Interfacing Optionsを選択
  3. P5 I2Cを選択

I2Cツール

LinuxベースのRaspberry Piで利用可能なツール。

i2cdetect

sudo i2cdetect ...で実行。Raspberry Piで管理者権限を持っているなら、sudoなしでもok。

i2cdetect -V

バージョン確認。

i2cdetect -l

利用可能なバスの一覧を表示。

i2c-1'1'がバス番号になる。

i2cdetect -F [bus]

指定したバスで利用可能な機能の一覧を表示。

i2cdetect -y [bus]

指定したバスのデバイスアドレスを表示する。

各行の2桁目がアドレスの上位桁、各列がアドレスの下位桁を表していて、ここではデバイスアドレスが1つ(0x27)確認できる。

ライブラリー

Raspberry PiとPythonでI2Cを扱うためのライブラリーsmbus2について(ドキュメントはこちら)。

sudo pip install smbus2でインストール。SMBusはSystem Management Busの略でI2Cのプロトコルと概ね同じ。

smbus2モジュールのSMBusクラスでバスへアクセスするインスタンスを取得。コンストラクターの引数にはバス番号を指定。バス番号はsudo i2cdetectで確認されたバス番号。

以降、read_bytewrite_byteなど、このインスタンスのメソッドを使う。

 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です