Circuit)は、フィリップス社が提唱した周辺デバイスとのシリアル通信の方式で、主にEEPROMメモリICなどとの高速通信を実現する方式です。《参照》フィリップス社のI2Cの英文の仕様書は下記からダウンロードできます★フィリップス社I2Cホームページこの当初の目的から推定されるように、I2Cは同じ基板内などのように近距離で直結したデバイスと、100kbpsまたは400kbpsの速度でシリアル通信を行うように使われるのが主で、離れた装置間の通信には向いていません。I2Cは、マスタ側とスレーブ側を明確に分け、マスタ側が全ての制御の主導権を持っています。I2Cはパーティーライン構成が可能となっており、1つのマスタで複数のスレーブデバイスと通信することが可能です。I2C通信のしくみは下図の構成を基本としています。図のように1台のマスタと1台または複数のスレーブとの間を、SCLとSDAという2本の線でパーティーライン状に接続します。マスタが常に権限を持っており、マスタが送信するクロック信号SCLを基準にして、データ信号がSDAライン上で転送されます。通信方式で類似のSPIと大きく異なるのは、個々のスレーブがアドレスを持っていて、データの中にアドレスが含まれていることと、1バイト転送毎に受信側からACK信号の返送をして、互いに確認を取りながらデータ転送を行っていることです。SSPをI2Cモードで使う時の通信手順の基本は、SCLとSDAの2本の信号線ですべてのデータの送受信を行います。SCLピン、SDAピンともに複数のスレーブを接続しますので、I2Cモードを選択すると両ピンともオープンドレイン構成となります。スレーブ側は両ピンとも常時は入力モードにしてハイインピーダンス状態にし、アドレスで指定された出力するデバイスだけ出力モードにする必要があります。Conditionを出力し続いてアドレスとRead/Write要求を出力します。全スレーブがこの時のSCLのクロックを元にSDAのデータを受信し、SSPADDレジスタにセットされたアドレスと一致したデバイスだけが、その後の送受信を継続します。受信した側がデータを受信完了すると自動的にACKビットを返送し、同時にSSP割込みを発生します。Conditionを出力するまで続けます。このようにI2C通信もブロック転送ができますので、大量のデータを一気に転送する時に便利に使うことが出来ます【I2C通信のタイミング】I2C通信の基本的な転送タイミングは下図のようになっています。マスタ側がSCLがHighの時にSDAをLowにしたときをスタートコンディションとする。その後続けてマスタがクロックの供給を続けながらアドレスとRead/Write要求のデータを送信します。この後は、アドレスで指定された1台のスレーブが、マスタと1対1で、指定された方向で通信を行います。続いて受信側からアクノリッジ(ACK)信号が返送されます。送信側は次のデータを出力するのを待つことになります。最後のデータを送り終わり、ACKを確認したあと、スレーブはSDAを解放するので、マスタがSDAをLowにしてクロックを停止してHighにしてから、SDAをHighにすることでストップシーケンスとなり通信は完了します。【I2Cの通信データフォーマット】I2C通信の基本的な通信のデータフォーマットは、アドレスフォーマットとデータフォーマットがあります。アドレスフォーマットは下図のようになります。アドレスには7ビットモードと10ビットモードがあり、図中の(a)(b)がそれぞれに対応します。図中のACKビットは受信側から自動返信されるビットです。通信データ全体のフォーマットは下図のようになり、マスタ側が送信側になるか受信側になるかによって図の(a)(b)のように2種類のフォーマットとなります。ここで、マスタが受信側になる場合には、まず最初にアドレスフォーマットの部分で、受信側になることを特定スレーブに向けて送信し、それに続いて指定されたスレーブがデータの送信を始めます。マスタはデータを受信したらACKを返信します。Cコンパイラには、I2C通信をサポートする組込み関数が用意されています。この関数を使うためには、プリプロセッサ関数でI2C通信を使うことを宣言して、関数ライブラリを組み込む必要があります。プリプロセッサ関数I2C用に用意されたプリプロセッサは、下表のようになっています。I2Cライブラリをリンクし、I2Cとして使用する入出力ピンを特定します。スレーブモードは内蔵のSSPモジュールがあるときのみ可能となりますが、マスターモードはどのPICでも有効となります。NOFORCE_SW指定が無いときは、プログラムで機能するよう自動的に必要なプログラムモジュールを生成します。これで、I2C通信をC言語で扱うことが可能となります。Conditionを出力する。このあとSCLはI2C_READかI2C_WRITEの実行までLowレベルに保たれます。Conditionを出力します。出力するためには条件が整っていることが必要です。1バイトのデータをI2Cに出力します。マスタのときはこれでクロックを出力し,スレーブのときはクロックを待ちます。内蔵SSPモジュールを使わないときはタイムアウトは無いので送信完了まで永久待ちとなります。I2Cインターフェースからデータを読込みます。マスタモードの時はこの命令でクロックが出力されますが、スレーブモードの時はクロック出力を待ちます。この命令は永久にデータを待ちます。従ってWDTを使用しているときはUSE関数でRESTART_WDTをパラメータ指定しておく必要があります。'0'を指定すると受信データに対しACKを返信しません。この命令は内蔵SSPモジュールを使っているときだけ有効です。受信バッファにデータが入っている時TRUEを返します。TRUEがかえされたらできるだけ早くI2C_READ命令を実行する必要があります。condition【プログラムの作り方】I2C通信は、外付けのEEPROMやA/D変換などとの通信になるので、PICがマスタになることが大部分ですので、マスタモードでのプログラミング方法について説明します。初期化で、I2C通信のモード設定でマスタモードを設定しておきます。あとは、通信を始めるのはすべてマスタ側からとなります。マスタ側がデータを送るか受けるかによって下図のようにプログラムの流れが変わります。Cコンパイラを使って簡単な例題を説明します。この例題は、2つのPICの間でI2C通信を使ってデータ転送を行うものです。回路を、下図に示しますが、PIC16F84がI2Cのマスタとなりデータを送信すると同時に液晶表示器に送信データを表示します。これに対し、I2Cで接続されたPIC16C73がスレーブとなってマスタからのデータを受信すると同時に、液晶表示器に受信データを表示します。送信データは0x30から0xFDまでを順次8個づつまとめてブロック転送します。従って、I2C通信では、アドレスに続いて8個のデータが送信されることになります。★I2Cテスト回路図(クリックして直接見られます)(2)マスタ側プログラムマスタとなるのはPIC16F84となります。SSPモジュールは内蔵していませんから、プログラムでI2Cのマスタ機能を実現することになります。液晶表示器も接続して表示制御をしていますが、これにはライブラリを利用しています。このプログラムは下記リストとなります。scl=PIN_A3)ここでI2CをマスタモードでSSPモジュール無しで使うことを宣言している。使う入出力ピンも指定している。i2c_start();スタートコンディションのシーケンスi2c_write(0xa0);アドレス送信のシーケンスi2c_write(asci);データ送信のシーケンスi2c_stop();ストップコンディションのシーケンス(3)スレーブ側のプログラム例スレーブ側は、PIC16C73で作成していますので、こちらはSSPモジュールを使用します。Cコンパイラではスレーブ側にはSSPモジュールがあることを前提にしているようです。SSPモジュールを使うといっても関数上は区別が無く、同じ形のプログラムとなります。ここでのスレーブは受信専用の使い方になっています。液晶表示器に受信データを表示しますのが、この制御にも液晶表示器用のライブラリを使っていますが、マスタ側とはピン接続が異なるので別のライブラリとなっています。下記リストがスレーブ側のプログラム例となっています。NOFORCE_SW)これでI2C通信をSSPモジュールで使用することを宣言している。同時にスレーブアドレスと使用する入出力ピンも指定しています。i2c_read();ここで、受信が完了したかをチェックし、完了していればデータを読込みます。