I2C(アイ・スクエア・シー)バスは、電子機器やマイコンの間で通信を行うための標準的な規格の一つです。そのシンプルな設計と効率的な通信方式から、多くのデバイスで採用されています。本記事では、初心者にもわかりやすくI2Cバスの仕組みや使い方、注意点について解説します。
I2Cバスとは?基本概念を理解しよう
I2C(Inter-Integrated Circuit)は、1982年にフィリップス(現NXPセミコンダクターズ)によって開発されました。この通信方式は、マスターとスレーブの構成を基本としており、1本のデータ線(SDA)と1本のクロック線(SCL)を使用して複数のデバイスを接続します。
I2C、IICとも記述されることがあります。本稿では「I2C」と呼びます。
誤解されがちですが、「バス」というのは接続形態のことで、パラレル(複数信号線)通信のことではありません。
主な特徴は次のとおりです。
- 2本の配線で通信可能:SDAとSCLのみ。
- マルチマスター対応:複数のマスターが存在可能。
- クロック同期通信:マスターがクロックを提供。
- アドレス指定型通信:各デバイスに固有のアドレスが割り当てられる。
マスターはいわば親、スレーブが子のようなイメージです。マルチマスターというのは文字通り、バス上に複数のマスターが存在できることです。ただし同時にはただ1つのデバイスのみがマスターになることができます。詳細は後述します。
I2Cバスの通信速度
I2Cバスでは次の3種類の速度が規定されていますが、厳密に合わせる必要はありません。極端な話、ソフトウェアでクロックのHi/Lo、データのHi/Loを切り替える処理を作っても問題なく通信できます。
- 標準:100kbps
- ファストモード:400kbps
- ファストモードプラス:1Mbps
- ハイスピードモード:3.4Mbps
- ウルトラファストモード:5Mbps
ただし1Mbps以上の速度を出したい場合はハード的な工夫が必要になったり、特にウルトラファストモードではマスターからスレーブへの送信しかできない等の制約が出てくることに注意してください。
I2Cバスの仕組み:SDAとSCLの役割
I2Cバスでは先述の通りわずか2本の配線で通信を実現しています。その2本を駆使してマスター権の取得、通信の開始・終了、アクノリッジ(ACKと書きます。対義語はネガティブ・アクノリッジで、NAKと書きます。)を表現します。
ACK/NAKは、OK/NGと同じような意味と考えていただいて構いません。
2本の信号線の詳細は次のとおりです。
- SDA(Serial Data Line):データの送受信に使用。
- SCL(Serial Clock Line):クロック信号を提供。マスターが駆動する。
配線(トポロジー)
いずれの信号線も、オープンドレイン駆動されます。そのため、配線のどこかでプルアップする必要があります。
オープンドレイン、プルアップについては別記事にて解説します。
これのおかげで、誰も信号線を駆動しない場合は信号レベルがHiになり、NAK検出が可能となります。また、バスにはオープンドレイン駆動のデバイスしか接続されないため、信号線を完全に共有できます。
I2Cのデバイスアドレスと通信フレーム
I2C通信では、各デバイスが固有のアドレスを持つことで、複数のデバイスが同一バス上に接続可能になります。同じメーカー、同じICの場合でも、アドレスを決定するためのピンが用意されていれば、同一のバス上に接続できます。
デバイスアドレスの構造
デバイスアドレス(スレーブアドレスともいいます)は、標準的なもので7bit、特別な場合は10bitで表現されます。
I2Cは通信フレームが8bit単位なので、10bitアドレスの場合は2回に分けて指定します。1回目のアドレス送信時に7bitアドレスと区別できるよう、最初の5bitは固定値(2進数で11110)です。最初に送るアドレスは7bitになっていますが、これはWrite/Readを区別するためのビットが1bit付記されるからです。(後述)
また、いくつかのアドレスは予約されており、特別な意味を持っています。以下に一覧を示します。(XはDon't care)
アドレス(2進) | 意味 |
---|---|
0000 000 | Write時:ジェネラルコードアドレス、Read時:スタートバイト |
0000 XXX | 使用禁止(過去に意味を持っていたので、互換のため) |
1111 1XX | 使用禁止(過去に意味を持っていたので、互換のため) |
1111 0XX | 10bitアドレス指定(XXにアドレスの上位2ビットを入れる) |
ジェネラルコードアドレスやスタートバイトは特殊な用途のため、本稿での解説は省略します。
フレームの構成
データは8bitずつ区切られます。それに加えて、ACK/NAKを示すビットが1bit必ずあり、9bitが1フレームになります。1フレームの通信に必要なクロック信号はマスターの責任で生成されます。基本的にデータを送る側がSDAを駆動しますが、ACK/NAKビットは受ける側がSDAを駆動します。
この挙動がややこしく、CPUのUSART機能を使うとACK/NAKビットに対応できないことに注意が必要です。
したがって、I2C通信は専用のCPU機能を用いるか、ソフトウェアでGPIOを制御して実現します。
送信(Write)か受信(Read)かの区別
アドレス指定のフレームで、最下位ビットに1を指定すると受信(Read)、0を指定すると送信(Write)となります。10bitアドレスのときは、最初のフレームで指定します。
I2Cのプロトコル
1つのフレームは8bitのデータとACK/NAKの1bitの計9bitで構成されることは先述のとおりです。そして、SCLはマスター側に駆動責任があります。
しかしSDAに関しては、ReadなのかWriteなのか、アドレス指定なのか、ACK/NAKビットなのかによって駆動する「担当」が替わり、大変ややこしいです。さらに、マスター側の責任として「スタートコンディション」「ストップコンディション」というものも存在します。これらについて解説していきます。
スタートコンディション
SCLがHiのとき、つまり誰も駆動していない時にSDAをHiからLoに変化させることを「スタートコンディション」といい、それを行ったデバイスがマスターになります。これが通信開始の合図であり、バスマスターの決定を示します。
マスター権の獲得はバスアービトレーションと呼ばれ、厳密にはもう少しややこしいのですが、ここでは省略します。
この動作を「スタートコンディションの発行」と言います。
以後、ストップコンディションが発生するまでは他のデバイスはマスターになることができません。
スタートコンディションはフレームの通信中は発行できませんが、フレーム間に再度発行することは可能です。これを「リピートスタートコンディション」あるいは「コンティニュアススタートコンディション」といいます。これの発行後は再びスレーブアドレスを指定する必要があります。
ストップコンディション
SCLがHiのとき、つまり誰も駆動していない時にSDAをLoからHiに変化させることを「ストップコンディション」といいます。
この動作を「ストップコンディションの発行」と言い、一連の通信の終了を意味しています。
ストップコンディションの発行をもってマスターはSCLの駆動責任がなくなり、次にスタートコンディションを発行するまでマスターは決まらず、通信も発生しません。
データ送受信
ACK/NAKを含めたデータ送受信中、送信側はSCLがLoのときにしかSDAを駆動してはいけないことになっています。受信側はSCLがLoからHiになったときにSDAを読み取ります。
通信の手順
基本的な手順は、次のとおりです。Write時は手順3,4、Read時は手順5,6を経ます。
- スタートコンディションの発行(マスター決定)
- スレーブアドレス+Read/Write区別をマスターが送信(スレーブ決定)、該当スレーブがACKを返す
- Write時、マスターが8bitデータ送信する度にスレーブがACK/NAKを返す
- No.3を必要バイト数分繰り返す→No.7へ
- Read時、スレーブが8bitデータ送信する度にマスターがACK/NAKを返す
- No.5を必要バイト数分繰り返す
- マスターがストップコンディションを発行(マスターもスレーブも通信をやめる)
ReadかWriteかはスレーブアドレス指定時にしか切り替えられません。
通常、途中でNAKが検出された場合はストップコンディションを発行して通信を中断します。I2Cでのエラーリトライは、スタートコンディションからのやり直しを意味します。(途中復帰しても意味がないことが多いため)
コマンド応答が必要なデバイスや、EEPROM等のようにアドレス指定してデータを読み書きするデバイスは、ストップコンディションを発行する前にリピートスタートコンディションを使います。アドレス指定はスタートコンディション直後にしかできないので、このような手続きが必要になるのです。
具体的な手順
いくつかのケースについて、手順を具体的に見てみましょう。(ACK/NAKは省略しています)。単純なやりとりについては先述のとおりなので、少しややこしいケースを取り上げます。
10bitアドレス指定の例
- スタートコンディション
- 固定値(1111 10)+アドレス上位2bit+Write/Read区別をマスターが送信
- アドレス下位8bitをマスターが送信(ここでスレーブが決定)
- (ここは普通のWrite/Readと同じ)
- ストップコンディション
手順2のACKは該当する全てのデバイスが反応します。
EEPROMのアドレス指定読み出しの例(スレーブ7bitアドレス)
- スタートコンディション
- スレーブアドレス+Write指定をマスターが送信
- EEPROMのアドレス指定(多バイト必要ならその分をマスターが送信)
- リピートスタートコンディション
- スレーブアドレス(No.2と同じもの)+Read指定をマスターが送信
- EEPROMからデータ読み出し(多バイト必要ならその分をマスターが受信)
- ストップコンディション
「マスターからスレーブに送りたいデータ」と「マスターがスレーブから受け取りたいデータ」が1セットになっているようなケースです。それぞれをリピートスタートコンディションで切り替えています。
まとめ
I2Cバスはわずか2本の配線で様々なことができる、非常に便利な規格です。とはいえ、配線が少ないがゆえのややこしさがあることも事実です。
通信速度が遅いケースが多いため、動作確認にはオシロスコープを使うことが多いので、オシロスコープを扱えることになっておくと良いでしょう。
ハードウェア的な知識が求められる規格なので、ソフトウェアしか学んでこなかった方も、データシートをよく理解する必要があり難易度は高めかと思います。
本記事が、I2Cバスを扱う方々の一助となれば幸いです。