「ソフテックだより」では、ソフトウェア開発に関する情報や開発現場における社員の取り組みなどを定期的にお知らせしています。
さまざまなテーマを取り上げていますので、他のソフテックだよりも、ぜひご覧下さい。
ソフテックだより(発行日順)のページへ
ソフテックだより 技術レポート(技術分野別)のページへ
ソフテックだより 現場の声(シーン別)のページへ
先日IIC(Inter-Integrated Circuit)バス通信に触れる機会がありましたので、今回の技術レポートではIICバス通信の基礎知識と、I/Oポートを使用したIICバス通信の実現方法をご紹介いたします。
IICバスとはフィリップス(PHILIPS)社で開発されたシリアルバスで、LCDドライバやEEPROM等の速度よりもコストを重視するようなデバイスでの通信に広く使用されています。ちなみに「IIC」の読み方は、「アイ・ツー・シー」、または「アイ・スクウェアド・シー」です。また、I2Cと書くこともあります。
IICバスは、以下の特徴があります。
図1. IICバス通信システム構成例
IICバス通信の基本的な通信方法について説明します。
まず、IICバス通信で使用する用語等について説明します。
IICバス通信の信号線として表1を使用します。
信号線名 | 説明 |
---|---|
SDA (Serial Data Line) |
データ信号 |
SCL (Serial Clock Line) |
クロック信号 |
表1. ICバス通信の信号線
IICバスの用語として表2を使用します。
用語 | 説明 |
---|---|
スタート条件 (START condition) |
マスタによりSCLがHi状態の時にSDAをHi→Loにすること この状態にすることにより、マスタがバス権を取得し、通信を開始することができる |
ストップ条件 (STOP condition) |
マスタによりSCLがHi状態の時にSDAをLo→Hiにすること この状態にすることにより、マスタがバス権を開放し、通信を終了することができる |
スレーブアドレス (slave address) |
スレーブごとに割り振られた番号のこと 接続した全てのデバイスで異なっていなければならない |
アクノリッジ (acknowledge) |
受信デバイス(マスタ・スレーブ両方の場合有り)がデータを正常に受信した場合に返す1ビットの”0”のデータのこと |
表2. IICバス通信の用語
マスタとスレーブの働きは主に表3のとおりです。
用語 | 働き |
---|---|
マスタ(master) | マスタに指定されたデバイスはデータ転送を開始・終了することができ、転送に使用するクロック(SCL)を出力する |
スレーブ(slave) | スレーブに指定されたデバイスはそれぞれ個別のアドレスを持つマスタが指定したアドレスを持つスレーブがマスタの通信相手となり、マスタが出力するクロック(SCL)に同期して送信・受信を行う |
表3. IICバス通信の用語
図2に示すIICバス通信の具体例をもとにIICバス通信の基本的な通信方法を説明します。
R/W:送受信指定ビット
ACK:アクノリッジ
* SCLは常にマスタから出力されます。
* スレーブアドレス、データの送信はMSBファースト(上位ビットからの送信)となります。
図2. IICバス通信例
上記のようなIICバス通信を簡単に実現する方法は、IICバスインタフェース内蔵デバイスを使用することですが、IICバスインタフェースを内蔵しないデバイスでも実現することができます。
IICバスインタフェース内蔵デバイスを使用した場合、IICバスに必要な一部の動作(スタート/ストップ条件発行やアクノリッジ出力等)を自動で、あるいは簡単な操作で行うことができますが、IICバスインタフェースを内蔵していない場合でもI/Oポートを使用することにより同様の動作を行うことができます。
この方法のメリットとしては、「IICバス通信を使用するシステムにおいてIICバスインタフェースが搭載されているマイコン以外も使用できること」、「I/Oポートを使用するため端子配置を決める際に融通が利く」等があります。これによって、システムのマイコン選定の幅が広がります。
この方法は当社でも活用しております。
以下にIICバスインタフェース非搭載マイコンであるH8/38347(ルネサステクノロジ製)と、IICバス搭載EEPROMであるAT24C08A(Atemel社製)を例にしてその方法をご紹介します。
H8/38347(以下マイコン)とAT24C08A(以下EEPROM)の通信を行います。マイコンがマスタで、EEPORMがスレーブとなります。マイコンではI/Oポートから任意の2本の入出力端子をSCL、SDA端子として使用します。以降ではSCL、SDAとして使用する端子をSCL端子、SDA端子と呼びます。
図3. I/Oポートを使用したIICバス通信システム構成例
SCL端子、SDA端子はI/Oポートの端子のため、タイミングよくHi/Lo出力および入力/出力切り替えを行いEEPROMと通信するプログラムを作成する必要があります。対して、EEPROMはIICバスインタフェースを搭載しているため、マスタであるマイコンからの入力に対応した動作を自動で行ってくれます。
今回は、マイコンからEEPROMにIICバス通信を使用して8ビットのデータを送信し、その後EEPROMからマイコンが8ビットのデータを受信します。
今回例に挙げるEEPROM(AT24C08A)では、以下のような動作を行います。
なお、受信後には必ずアクノリッジ(0)を送信します。
図4に、マイコンからEEPROMへのデータの送信方法を示します。
図4. I/Oポートを使用したIICバス通信例(マイコンからEEPROMへのデータ送信)
しかし、システムCではドライバの内容が少し違っていることがあります。
No | マイコン(マスタ) | EEPROM(スレーブ) | ||||
---|---|---|---|---|---|---|
動作 (全ての動作をプログラミングする) |
ポート状態 (入出力) |
動作 (EEPROMが全て行ってくれる) |
ポート状態 (入出力) |
|||
SCL | SDA | SCL | SDA | |||
(1) | SCL端子、SDA端子を出力状態にする SCL=Hi、SDA=Hi→Loにする(スタート条件を発行する) |
出力 | 出力 | 自分のスレーブアドレスを受信するまで待機 | 入力 | 入力 |
(2) | SCL=Hiの時にSDAの値が有効なデータになるようなタイミングで、SCLをトグル出力しながらSDAからスレーブアドレス+送受信指定ビット(送信指定=0)を出力する | |||||
(3) | SDA端子を入力状態にし、SCL=Lo→Hiにして、SDA=Loになるまで待つ(アクノリッジを待つ) | 入力 | ||||
(4) | (2)で受信した値が自分のスレーブアドレスと一致した場合SDA=Loにする(アクノリッジを出力する) | 出力 | ||||
(5) | SDA=LoになったらSCL=Hi→Loにする | 入力 | ||||
(6) | SDA端子を出力状態にする SCL=Hiの時にSDAの値が有効なデータになるようなタイミングで、SCLをトグル出力しながらSDAからEEPROMの操作対象(書き込み)メモリアドレス(8ビット)を出力する |
出力 | ||||
(7) | SDA端子を入力状態にし、SCLをLo→HiにしてSDA=Lo(アクノリッジ)を待つ | 入力 | ||||
(8) | 8ビットデータを受信したらSDA=Loにする(アクノリッジを出力する) | 出力 | ||||
(9) | SDA=Loになったら(アクノリッジが入力されたら)SCL=Hi→Loにする | 入力 | ||||
(10) | SCL=Hiの時にSDAの値が有効なデータになるようなタイミングで、SCLをトグル出力しながらSDAから8ビットデータを出力する | 出力 | ||||
(11) | SDA端子を入力状態にし、SCL=Lo→HiにしてSDA=Lo(アクノリッジ)を待つ | 入力 | ||||
(12) | 8ビットデータを受信したらSDA=Loにする(アクノリッジを出力する)(6)で指定されたメモリアドレスに受信したデータを書き込む | 出力 | ||||
(13) | SDA=Loになったら(アクノリッジが入力されたら)SCL=Hi→Loにする | 入力 | ||||
(14) | SDA端子を出力状態にする SCL=Hi、SDA=Lo→Hiにする(ストップ条件を出力する) |
出力 |
表4. 図4の説明
次に、図5にEEPROMからマイコンへのデータの送信方法を示します。
R:送受信指定ビットは受信指定(1)
W:送受信指定ビットは送信指定(0)
図5. I/Oポートを使用したIICバス通信例(EEPROMからマイコンへのデータ送信)
No | マイコン(マスタ) | EEPROM(スレーブ) | ||||
---|---|---|---|---|---|---|
動作 (全ての動作をプログラミングする) |
ポート状態 (入出力) |
動作 (EEPROMが全て行ってくれる) |
ポート状態 (入出力) |
|||
SCL | SDA | SCL | SDA | |||
(15) | SSCL端子、SDA端子を出力状態にする SCL=Hi、SDA=Hi→Loにする(スタート条件を発行する) |
出力 | 出力 | 自分のスレーブアドレスを受信するまで待機 | 入力 | 入力 |
(16) | SCL=Hiの時にSDAの値が有効なデータになるようなタイミングで、SCLをトグル出力しながらSDAからスレーブアドレス+送受信指定ビット(送信指定=0)を出力する | |||||
(17) | SDA端子を入力状態にし、SCL=Lo→HiにしてSDA=Loになるまで待つ(アクノリッジを待つ) | 入力 | ||||
(18) | (16)で受信した値が自分のスレーブアドレスと一致した場合SDA=Loにする(アクノリッジを出力する) | 出力 | ||||
(19) | SDA=Loになったら(アクノリッジが入力されたら)SCL=Hi→Loにする | |||||
(20) | 時にSDAの値が有効なデータになるようなタイミングで、SCLをトグル出力しながらSDAからEEPROMの操作対象(読み込み)メモリアドレス(8ビット)を出力する | 出力 | 入力 | |||
(21) | SSDAを入力状態にし、SCL=Lo→HiにしてSDA=Loになるまで待つ(アクノリッジを待つ) | 入力 | ||||
(22) | 8ビットデータを受信したらSDA=Loにする(アクノリッジを出力する) | 出力 | ||||
(23) | SDA=Loになったら(アクノリッジが入力されたら)SCL=Hi→Loにする | |||||
(24) | SCL端子、SDA端子を出力状態にする SCL=Hi、SDA=Hi→Loにする(スタート条件を発行する) |
入力 | ||||
(25) | SCL=Hiの時にSDAの値が有効なデータになるようなタイミングで、SCLをトグル出力しながらSDAからスレーブアドレス+送受信指定ビット(受信指定=1)を出力する | 出力 | ||||
(26) | SDA端子を入力状態にし、SCL=Lo→HiにしてSDA=Loになるまで待つ(アクノリッジを待つ) | 入力 | ||||
(27) | (25)で受信した値が自分のスレーブアドレスと一致した場合SDA=Loにする(アクノリッジを出力する) | 出力 | ||||
(28) | SDA=Loになったら(アクノリッジが入力されたら)SCL=Hi→Loにする | |||||
(29) | SCL=Hiの時のSDAの値を取得しながらSCLをトグル出力させる(8回行い、8ビットデータを得る) | マスタから入力されるSCLに合わせて(22)で指定したメモリアドレスにある8ビットデータをSDAから出力する | ||||
(30) | SDA端子を出力状態にする SCL=Hi、SDA=Lo→Hiにする(アクノリッジを出力せずストップ条件を発行する) |
出力 | 入力 |
表5. 図5の説明
いかがでしたでしょうか?
IICバス通信は2本の通信線で行う通信であるため、このように工夫次第でIICバスインタフェースを使用しなくても通信を行うことが可能です。但し、今回の例ではI/Oポートを使用するため「転送速度が遅い」、「ノイズが入った場合に対応できない(IICバスインタフェースではノイズキャンセラが採用されている)」等の難点がありますので、あくまでひとつの例としてご参考にしていただければ幸いです。
(Y.D.)
関連ページへのリンク
関連するソフテックだより