I2Cの低速通信について
by K.I
Index
- マイコンで、簡単な通信をやりたいんだけど、端子が2本しか余っていない。
- UART使えば良いんだけど、通信相手は非常に低速な上に常時通信線の監視が出来ないので、非同期での通信が難しい。
- クロック同期にしたいけど、双方向での通信がしたい→3本必要。
- こんな時に、I2Cのような通信方法が使えないだろうか。。
- I2Cの特徴としては、
- 通信に必要なのは、GND以外、クロックとデータの2本だけ。
- 半2重の双方向通信が可能。
- アドレス指定で複数の相手との通信も可能。
- 素晴らしい!でも問題は低速の相手との通信が可能かということだけど、どうなんだろう。
- ということで、I2Cは詳しくは知らないので調べてみた。
[top]
- 良く分からないんだけど、自分なりに理解したプロトコルを纏めてみた。。
- 非常に低速な相手が、ソフト的にこれを行う場合に、制約になりそうなところを、太字で記述してみる。
- クロックとデータは、外部でPullUpされているので、両方ともH状態になっている。
- この状態が一定時間(規格があるのかは不明)続いていれば、バスは未使用で通信可能と判断出来る。
- 通信を開始するノードを、マスタと呼ぶ。
- マスタは、クロックをHのまま、データをH→Lにする。
- 通信状態では、クロックがLの時のみ、データが変化するので、通常の通信と区別出来る。
- 全ノードは、このスタートコンディションを監視していなければならない。
- マスタは、クロックに同期させて、データを出力する。
- 具体的には、クロックがLの時にデータを変化させて、クロックをHに戻す、を繰返して8ビットのデータを送信する。
- 最初の7ビットがスレーブアドレス、最後の1ビットがRead/Writeの指定。
- 全ノードは、クロック立上がりを監視して、データを取り込む。
- スレーブは、8ビットの最後のデータの次のクロックの立下りを監視して、データをLにする。
- これは、ACK(アクノリッジ)と呼ばれ、これによりスレーブが応答したことをマスタが知ることが出来る。
- マスタ側はクロックの立上がりを監視して、その時データがLならスレーブ有り、データがHならスレーブ無しと判断できる。
- マスタはクロックに同期させて、データを出力する。
- クロックがLのときにデータを変化させて、クロックをHに戻す、を繰り返して8ビットのデータを送信する。
- スレーブは、クロック立上がりを監視して、データを取り込む。
- 8ビットデータを受信したら、アドレス受信時と同様にアクノリッジを返す。
- スレーブは、クロック立下がりを監視して、データを出力する。
- クロックがLの時にデータを変化させて、8ビットデータを送信する。
- マスタは、クロック立上がりを監視して、データを取り込む。
- マスタは単にクロック立上がり時にデータを取り込むだけで良いかもしれない。ちょっと自信なし。
- 8ビットデータを受信したら、マスタ側がアクノリッジを返す。
- マスタはアクノリッジの後に、クロックをLにしてから、データをLにする。
- 次に、クロックをHに戻したら、クロックをHのまま、データをL→Hにする。
- これを、ストップコンディションと呼ぶ。
- 通信状態では、クロックがLの時のみ、データが変化するので、通常の通信と区別出来る。
- 全ノードは、このストップコンディションを監視していなければならない。
- ストップコンディション後は、別のマスタが通信を開始することも出来る。
- I2Cではアドレス送信時に通信方向が決まるので、通信方向を変えるためには再度アドレスを送信する必要がある。
- 続けて送信を行う場合、Stopコンディションを送って、一旦通信を終了してバスを開放。
- 再度、Startコンディションを送って、再度通信を開始しても良いが、別のマスタが送信を開始してしまうかもしれない。
- バスを開放せずに続けて通信を行いたい場合は、Stopコンディションを送らずに、
- Startコンディションから始めることで、続けて通信が可能になっている。
- つまり、スタートコンディション後のデータは、必ずアドレスということになる。
- I2CのクロックSCLは、マスタが送信するので、基本的に通信速度はマスタが決定する。
- でも遅いスレーブの場合、マスタがクロックをHにするタイミングで、スレーブ側がクロックをLに保持することで、マスタ側を待たせることが出来る。
- マスタ側でクロックをHにしても、オープンドレインなので、クロックはLのままになる。
- マスタ側はSCLをHにした後、実際にSCLがHになるまで、ずーっと待つようになっている。
- この仕組みにより、I2Cは低速のスレーブが通信速度をコントロールできる1。
- 2つのノードが、同時にStartコンディションを送信して、通信を開始することが有り得る。
- この場合、スレーブアドレスが違っていれば、うまく調停を行う仕組みがある。
- マスタは自分が送信したアドレスを監視して、そのアドレスが違っていれば、アドレス受信状態に切替わる。
- アドレスが正しければ、そのままマスタとして実行を続ける。アドレスのビットが'L'の方が優先されるということになる。
- スレーブアドレスが違う場合には、このようにマスタの競合を調停出来るが、スレーブアドレスが同じ場合は出来ないので注意。
- つまり、複数のマスタが同時に、同じスレーブにアクセスする様なことは出来ない。
- でも、そんな複雑なシステムをI2C上に組もうなんてことは無いと思うけど。。
- スレーブ側が低速の場合の問題は、Startコンディションの検出と、Stopコンディションの検出。
- 転送速度は、SCLをLに保持することで待たせることが出来る。
- 但し、StartとStopは、他の作業をやっていると見落とす可能性がある。
- スタートを見落とした場合、アドレス後のアクノリッジを返さないことになる。
- マスタは、アクノリッジが無い場合、再度Startコンディションからやり直す必要がある。
- Stopを見落としたことは、マスタには分からない。
- アクノリッジを返しているならば、基本的に問題にはならないと思けれど。
- スレーブ側は、スタートコンディション、アドレスフェーズで、状態の初期化を行った方が良さそう。
- 可能であれば、定期的に初期化した方が良いのかもしれない。
- I2Cのスレーブ側の制御は、ソフト的に行うのはかなり辛いので、
- ハード的に行う方が良いだろう。少なくとも割込み等の処理を行わないとキツイ。
- マスタ側のクロック待ちについては、速度的にはそれほど難しくなさそう。
- またスレーブ側が十分高速ならば、クロック待ちを省略できるかもしれない。
- シングルマスタでは、低速のCPUでもマスタ側のソフト制御は難しくなさそうだ。
- マルチマスタ対応は、スレーブ側と同様なので、マスタ側でもソフト制御は難しいと思われる。
1これは非常に簡単だけど、良く考えられた仕組みだ。
[top]
- I2Cは、基本的にマスタがクロック速度を決めているが、
- 低速のスレーブでも、データを出力するまでクロックをLに保持することで、マスタを待たせることが出来る。
- しかし、Startコンディション、Stopコンディションを取り損ねるとマズイので、
- これは、ハード的或は割込み処理で取りこぼしが無いように注意する必要がある。
[top]
[電子工作関連に戻る]