HOME > ソフテックだより > 第79号(2008年12月3日発行) 技術レポート「I/Oポートを使用したIICバス通信の実現方法について」

「ソフテックだより」では、ソフトウェア開発に関する情報や開発現場における社員の取り組みなどを定期的にお知らせしています。
さまざまなテーマを取り上げていますので、他のソフテックだよりも、ぜひご覧下さい。

ソフテックだより(発行日順)のページへ
ソフテックだより 技術レポート(技術分野別)のページへ
ソフテックだより 現場の声(シーン別)のページへ


ソフテックだより 第79号(2008年12月3日発行)
技術レポート

「I/Oポートを使用したIICバス通信の実現方法について」

1. はじめに

先日IIC(Inter-Integrated Circuit)バス通信に触れる機会がありましたので、今回の技術レポートではIICバス通信の基礎知識と、I/Oポートを使用したIICバス通信の実現方法をご紹介いたします。

2. IICバスとは?

IICバスとはフィリップス(PHILIPS)社で開発されたシリアルバスで、LCDドライバやEEPROM等の速度よりもコストを重視するようなデバイスでの通信に広く使用されています。ちなみに「IIC」の読み方は、「アイ・ツー・シー」、または「アイ・スクウェアド・シー」です。また、I2Cと書くこともあります。
IICバスは、以下の特徴があります。

  • 2本の信号線を用いた双方向のシリアル通信が可能。
  • 接続するデバイスは電気的制約の範囲内であればいくつでも接続することができる。
  • デバイスはそれぞれマスタとスレーブに分類し、スレーブは個別のアドレスを割り振り区別する。通信はマスタが指定したスレーブとのみ行う。

IICバスシステム構成例
図1. IICバス通信システム構成例

3. 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ファースト(上位ビットからの送信)となります。

IICバス通信例
図2. IICバス通信例

(1):
スタート条件(SCL=Hi、SDA=Hi→Lo)がマスタより出力されます。これによりマスタがバス権を取得します。
(2):
スレーブアドレス(7ビット)+送受信指定ビット(1ビット)をマスタよりSCLに同期して送信します。マスタから送信されたスレーブアドレスを実際に指定しているスレーブがマスタとの通信相手となります。また、送受信指定ビットによりマスタが以後に送信/受信のどちらを行うのかを指定します。(送信の場合は”0”、受信の場合は”1”を指定する)
(3):
マスタの通信相手のスレーブよりアクノリッジ”0”がSCLに同期して出力されます。
(4):
送信デバイス(送受信指定ビットが”0”の時はマスタ、”1”の時はスレーブ)からデータ(8ビット)がSCLに同期して出力されます。
(5):
受信デバイスよりアクノリッジ”0”がSCLに同期して出力されます。
(6):
(4)と(5)を繰り返します。
(7):
データの送信の後、受信デバイスよりアクノリッジが出力されない場合は通信を続けることができません。
(8):
(7)が発生した場合はストップ条件(SCL=Hi、SDA=Lo→Hi)をマスタより出力し、マスタからバス権を開放して通信を終了します。(ストップ条件はアクノリッジが出力された場合でも使用することはできます。また、ストップ条件を発行せず(1)からやり直すことも可能です)
また、マスタを複数にして(マルチマスタ)IICバス通信を行うこともできます。その場合も手順は同じです。マルチマスタの場合は最初にバス権を取得したマスタ以外のマスタはバス権が開放されるまで通信に参加することはできません。

4. I/Oポートを使用した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端子と呼びます。

マイコンのI/OポートをSCL、SDAとして使用してIICバス通信を行う
図3. I/Oポートを使用したIICバス通信システム構成例

SCL端子、SDA端子はI/Oポートの端子のため、タイミングよくHi/Lo出力および入力/出力切り替えを行いEEPROMと通信するプログラムを作成する必要があります。対して、EEPROMはIICバスインタフェースを搭載しているため、マスタであるマイコンからの入力に対応した動作を自動で行ってくれます。
今回は、マイコンからEEPROMにIICバス通信を使用して8ビットのデータを送信し、その後EEPROMからマイコンが8ビットのデータを受信します。
今回例に挙げるEEPROM(AT24C08A)では、以下のような動作を行います。

マイコン送信時:
スレーブアドレスと送信指定ビットの受信→操作対象(書き込み)メモリアドレスの受信→対象のメモリへのデータの書き込み
EEPROM送信時:
スレーブアドレスと送信指定ビットの受信→操作対象(読み出し)メモリアドレスの受信→スレーブアドレスと受信指定ビットの受信→対象のメモリへのデータの読み込み対象のメモリへのデータの書き込み

なお、受信後には必ずアクノリッジ(0)を送信します。

図4に、マイコンからEEPROMへのデータの送信方法を示します。

IICバスを内蔵しないマイコン→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)

EEPROM→IICバスを内蔵しないマイコンへのデータ送信
図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の説明

5. 終わり

いかがでしたでしょうか?
IICバス通信は2本の通信線で行う通信であるため、このように工夫次第でIICバスインタフェースを使用しなくても通信を行うことが可能です。但し、今回の例ではI/Oポートを使用するため「転送速度が遅い」、「ノイズが入った場合に対応できない(IICバスインタフェースではノイズキャンセラが採用されている)」等の難点がありますので、あくまでひとつの例としてご参考にしていただければ幸いです。

(Y.D.)

[参考文献]
NXPセミコンダクターズ社
I2Cバス仕様書 バージョン2.1
NXPセミコンダクターズ社
I2C-bus specification and user manual Rev. 03

関連ページへのリンク

関連するソフテックだより

ページTOPへ