I2Cバスをご存知でしょうか。
I2Cはデータ線:SDAとクロック線:SCLで双方向通信ができる、とても低コストな信号規格です。
(正確にはもともとのI2Cの規格をきっちり守ったわけではない「なんちゃってI2C」ばかりですが、まぁ、I2Cです)
信号線が少ないだけでなく、「バス」なので複数のデバイスをつなげます。
つまり、CPUから伸びる配線はSDA&SCLの二つだけですが、そこにEEPROM、RTC、センサー・・・といろいろなデバイスを複数個繋げられるのです。
ピン数が少ないCPUでは非常に心強い味方です。
(ICごとにアドレスが違うので、CPUがアドレスを指定して通信することで複数個つなげても通信が混信しない)
また、信号速度も最大400kHzと低速です。
・信号線が2本のみ
・速度も遅い
ということで、ハードウェア設計的には非常に簡単です。
よほど酷いパターンをひかない限り普通に動きます。
が、一つだけ注意するべきところが「プルアップ抵抗」です。
I2Cは信号線がプルアップされており、それぞれのデバイスがそれをLに落とすことで通信をしています。
理想状態ではプルアップ抵抗は何Ωでも大丈夫なのですが、実際にはそうはいきません。
I2Cバスに接続される信号線にはGNDとの間に寄生容量が発生します。
さらに、各デバイスのピンにも寄生容量があります。
つまり、I2CのバスをLやHに変化させるときにはその寄生しているコンデンサを充放電する必要があるわけです。
その事自体はどんな信号線も同じです。SPIだろうがMIIだろうが。
でも、他の通信規格はたいていプッシュプルで駆動するので、寄生容量の充放電は速いのです。
ところが、I2Cは・・・
H→Lのときは、問題ありません。
デバイスが信号線とGNDをショートさせるので速やかに電荷が抜けてLになります。
問題は、L→Hのときです。
このとき、デバイスはハイインピーダンスになるだけです。
プッシュプルのように電源と信号線をショートさせたりしません。
ただ単純にプルアップ抵抗から流れてくる電流で寄生容量に充電していくのです。
ということは、「物凄く遅い」のです。
対策としてはプルアップ抵抗を小さくすることですが、あまりに小さくするとデバイスのドライブ能力を超えてしまいますし、消費電流も大きくなります。
なので波形的に問題ない範囲でプルアップ抵抗は大きくしたいのです。
というところで、現実的には1~10kΩという範囲内で大体うまく行きます。
I2Cを使う際には波形をきちんと見てプルアップ抵抗を調整しましょう!
以上、小田切でした。
最近のコメント