確実にデータを届ける!定番シリアル通信I²Cの設計テクニック3選

前回のメルマガでは,I2CバスとSPIバスの基本を説明しました.今回は,I2Cをどのように使いこなすのかを説明します.
I2Cは2線式のシリアル・バスで,シンプルな回路で構成できることが特徴です.I2Cバスの信号はオープン・ドレイン出力で,プルアップ抵抗を使って信号を双方向でやりとりします.この「オープン・ドレイン出力を用いた双方向通信」という特徴のため,それを考慮した扱い,特に,チップの信号電圧が異なる場合や,長い配線を引き回す場合は,ちょっとしたテクニックが必要になります.今回は,I2Cの中でも特によく使われる,次のテクニック3つを紹介します.
・テクニック1:配線延長/多接続の対応
・テクニック2:プルアップ抵抗選定法
・テクニック3:電圧の異なるチップ間の通信
信号線を長く延長したり,たくさんのチップを接続すると,信号線の静電容量が増加します.これは信号線自体が持つ静電容量が大きくなり,また各チップの入力容量が並列に接続されることになるためです.静電容量の増加は信号をなまらせる原因となります.プッシュ・プルのデジタル信号であれば,信号線を延長したり,たくさんのチップを接続するときにはバッファによる信号の増強で対応できます.バッファはアンプなので入力側と出力側の容量を分離することができます.
I2Cではこの信号のなまりに特に敏感です.プルアップ抵抗を用いるオープン・ドレイン出力では信号線の容量をプルアップ抵抗を介して充電します.このためLレベルからHレベルへの信号の変化時間は,同じ信号線の容量でもプッシュ・プル出力に比べ格段に遅くなってしまいます.
I2Cは,バスに許容される静電容量の上限値が決められています.クロック周波数が400kHzまでのファースト・モードで400pF.1MHzのファースト・モード・プラスで550pFです.より速いクロックで動作可能なファースト・モード・プラスで上限値が上がっているのは,チップがLレベルを出す際の電流引き込み能力が強化され,より小さい値のプルアップ抵抗が使えるようにしてあるためです.
I2Cで信号線を延長したり,たくさんのチップを接続するときは,I2C対応のバッファを使います.双方向にバッファを接続するだけでは動作しません(後に図3にて説明).このため,両側からの信号レベルを正しく反対側へ反映させる仕組みを持ったものが必要になります.I2Cバッファとしてよく使われる定番品としてPCA9517(NXPセミコンダクターズ),PCA9617(NXPセミコンダクターズ)があります.PCA9517はファースト・モード用.PCA9617はファースト・モード・プラスに対応した製品です.どちらの製品も2電源式になっていて,電圧変換もこのチップで行えます.
図1にバッファをスター型やカスケード型に接続した例を示します.


テクニック1ではI2Cバスの電圧の変換や静電容量(の分離)についての説明をしてきました.しかしこの信号電圧を決めたり,静電容量との組み合わせで信号の立ち上がり時間を決めてしまうプルアップ抵抗の値はどうやって決めるのでしょうか.
一般には2.2kΩや4.7kΩといった値がよく使われます.あまり気にせずにこれらの値を使う場合も多いのではないかと思います.一方,上の図1では1.4kΩを使っています.いったいどのような値を使うのがいいのでしょうか.また,もっと小さい値やもっと大きい値を使うとどうなるのでしょうか.
小さい抵抗値のプルアップでは「信号をLレベルに引ききれない」問題が起こります.デバイスがLレベルを出力すると,プルアップ抵抗には電流が流れます.抵抗値が小さいと,ここに流れる電流が大きくなり,その電流がLレベルを出力しているデバイスに流れ込みます.デバイス内部の信号をLレベルに引き込むトランジスタは抵抗を持っているため,この抵抗分と電流で電圧が発生します.このため電流が大きくなると想定以上の電圧が発生し,充分低いLレベル電圧が得られないことになります.
逆に大きい抵抗値のプルアップでは,充分な通信速度が得られない問題が発生し得ます.信号がLレベルからHレベルへの遷移する時には,信号線が持っている静電容量に対して,プルアップ抵抗を介して充電が行われることにより電圧が上昇します.プルアップに大きい抵抗値を用いると,この時の電流が小さくなり信号の立ち上がり(電圧の上昇)に時間がかかります.
プルアップ抵抗の値には計算の方法があります.これはI2C仕様書英語版(rev7), 日本語版(rev5)の第7節に詳細が掲載されています.一般に,たとえばI2Cのファースト・モード(400kHz)でプルアップ電圧を3.3Vで使用する際には1kΩから8kΩ程度のプルアップならば問題なく使うことができます(図2).


最近のプロセッサやマイコンは低電圧化が進み,入出力信号電圧が低いものが増えています.もし互いに通信するチップの信号電圧が異なる場合にはこの電圧を合わせてやるための電圧レベル・トランスレータ(Voltage Level Translator.略してVLT.レベルシフタともいう)が必要になります.このVLTには標準ロジック・チップ(各社で販売されている74シリーズなど)を使うことができます.
SPIのような単純な片方向のデジタル信号の場合,一方から他方への電圧変換は簡単です.電圧変換方法にはいろんな方法がありますが,例えば,74HCT245(Nexperia)などのバッファ・チップを使えば,3.3Vから5Vへの信号変換を簡単に実現できます.
しかし,I2Cではそうはいきません.I2Cはオープン・ドレイン出力の双方向の信号です.ここに標準ロジックのオープン・ドレイン・バッファを使うとどうなるでしょうか.2個のバッファの入力と出力を互いに接続し,それぞれにプルアップ抵抗を付けて動かしてみましょう.図3ではそれぞれのプルアップに接続されている電源は3.3Vと5Vの電源に接続されていて,この電圧での信号変換をしようとしていますが,これではうまく動作しません.


初期状態として3.3V側,5V側がともにHレベル状態であったとします.この状態から一方がLレベルになると,Lレベル入力を受けたバッファは出力にLレベルを出します.さて,先ほどLレベルを出した側のチップが信号をHレベルに戻そうとオープン・ドレイン状態になっても.. 信号はこちら向きに接続されたバッファのLレベル出力によってHレベルになることができず,デッドロック状態になります.このような現象を回避するために,回路に工夫が必要になります.
最も簡単な例はMOSFETで変換を行う例です.図4は2000年当時のI2C仕様書に紹介されていた回路例です.このように単純な回路で電圧変換が可能ではあるのですが,MOSFETのスレッショルド電圧やそのバラツキなどの考慮が必要で,低電圧への対応は難しくなります.

I2Cには,MOSFETの代わりに専用のVLTを用いるのが便利です.I2Cに対応したVLTとしてはPCA9306(NXPセミコンダクターズ),NVT2002(NXPセミコンダクターズ),さらにNTS0302(NXPセミコンダクターズ)などがポピュラーです.PCA9306,NVT2002は図4のようなMOSFETを信号線数だけ内蔵し,さらに変換する信号電圧に充分な差がある時には,低電圧側のプルアップ抵抗を省略できる仕組みが用意されています.NTS0302は最新のVLTで,オープン・ドレイン信号制御をベースとしながら汎用的に高速信号にも対応できるよう信号の立ち上がり時間を改善するための回路が内蔵されている製品です.図5はNTS030x(末尾の数字は変換を行う信号の本数)の接続例です.

* * *
このようにI2Cバスは速度がそれほど速くないデジタル通信の仕様ながら,その扱いはアナログ的な振る舞いを充分に考慮しておかなければなりません.簡単で便利に使えるバス仕様ですが,上記のような原理を把握しておかないと思わぬハマりどころとなってしまいます.
NXP Tech Blog:「I2C ハードウェア・デバッグ (日本語ブログ)」
-- https://community.nxp.com/t5/NXP-Tech-Blog/I-C-ハードウェア-デバッグ-日本語ブログ/ba-p/2037021
・組み込みマイコン入門講座
-- https://interface.cqpub.co.jp/mcu-hands-on/
・登録内容の変更,メール・マガジン配信中止はこちらからお願いします.
-- https://cc.cqpub.co.jp/system/auth/
I2CとSPIの良いとこ取り!次世代2線式シリアル通信「I3C」
・開催日 :2025年7月25日 10:00-17:00
・受講料 :5,000円(ボード・お弁当付き,税込み)
・使用ボード:FRDM-MCXA153(NXPセミコンダクターズ)
・講師 :岡野 彰文氏(NXPジャパン株式会社 プリンシパル・フィールド・アプリケーション・エンジニア)
※セミナ受講時に使用したFRDM-MCXA153はそのままお持ち帰り頂けます.
申し込みページはこちら