基本的なI2C通信手順を説明します。
説明内容
I2Cデータ通信はI2Cモジュール(I2Cスレーブ)ごとに異なりますので、この記事では基本的な通信手順を説明します。
基本的な通信手順として、マスターがスレーブを選択した後、マスターからスレーブに2バイトのデータを送信する例で説明します。
この実践編で使用する液晶モジュールは、I2C通信で2バイトのデータをマスターからスレーブに送信して制御します。この記事で説明するI2Cの通信手順は、液晶モジュールのデータ通信例になります。
一方で、温度センサはマスターからスレーブにデータを送信した後、スレーブからマスターにデータ(温度データ)を返信します。この温度センサのI2C通信手順は、液晶モジュールのそれに比べると複雑になりますので、まずは簡単な2バイトデータをマスターからスレーブに送信する手順を基本形として説明します。温度センサの通信手順は温度取得プログラム作成時に説明します。
I2C通信手順の概略
何度も説明してしまいますが、I2C通信ではクロック信号線とデータ信号線の2本の信号線のみをうまく制御しながらデータ通信を行います。
マスターからスレーブに2バイトのデータを送信するには、前回の記事で説明しました「I2C通信手順のイメージ」のように、クロック信号とデータ信号をうまく操作して以下のように制御します。
これから、上のそれぞれの番号ごとに信号の制御方法を説明していきます。なお、(1)の通信開始と(8)の通信終了は対になっていますので、一緒に説明します。また、(4)(5)の1バイト送信と(6)(7)の1バイト送信は全く同じ内容になりますので、(6)(7)の手順の説明は省略します。
(1)通信開始・(8)通信終了
SPI通信ではチップセレクト信号線(スレーブセレクト信号線)が別にありましたので、その信号線を制御すればスレーブを選択すると同時に、通信開始、通信終了を容易に伝えることができました。
I2C通信では、クロック信号線とデータ信号線の2本の信号線でデータ(0か1か)の送受信を行いますが、これら以外に信号線はありません。
この通信の仕組みを使って「通信開始」と「通信終了」という特殊な合図を送るにはどうしたらよいでしょうか。
この課題はチャレンジ課題(1)に似ています。このチャレンジ課題では、0〜9の数字を送信するためのスイッチと電球を使って、0〜9以外の情報(例えば通信終了やハイフンなど)を送信する方法を検討していただきました。
I2C通信では、0か1かのデータを送受信する信号線を使用して、0か1かのデータではない「通信開始」と「通信終了」という特別な情報を伝える必要があります。例えば0000を通信開始、1111を通信終了などと決めてしまうと、0000や1111のデータは送受信できなくなってしまいます。
I2C通信では、この課題を以下のように解決しています。
まず、クロック信号とデータ信号を使ってデータを送受信する方法をもう一度よく見てみましょう(SPI通信と同じです)。
このように、クロックの立ち上がりでデータを読み取り、クロックの立ち下がりで次のデータをセットします。
このタイミングをもう少し詳しく検討してみます。「クロックの立ち上がりでデータを読み取る」と言っても、データを読み取る側は実際にはクロックが立ち上がったことを確認してからデータ信号線を読み取りますので「クロックが立ち上がった瞬間にデータを読み取る」ということは難しいです。
そのため、以下のようにクロックが立ち上がった後、クロックの立ち下がりまでの期間、データ信号は変更しないようにしています。
つまり「クロックが1の間はデータ信号は変更しない」というルールがあるわけです。
「通信開始」と「通信終了」を伝えるには、このルールを逆手に取ります。このルールを破ることにより、特殊な状況を作るわけです。どういうことかというと、クロックが1の間にデータ信号を変化させて特殊な状況を作ってしまおう、というわけです。
データを送るときは「クロックが1の間はデータ信号は変更しない」わけですから、上の図のような状況は0か1かのデータ通信ではないわけです。
また、クロックが1の間にデータ変化させる、というのは2通りのパターンがあります。一つは「クロックが1の間にデータを1から0に変化させる」というパターンと、もう一つは「クロックが1の間にデータを0から1に変化させる」というパターンです。
通信開始と通信終了の2つの合図を送りたいので、この2つのパターンをそれぞれ「通信開始」「通信終了」に割り当てます。
具体的には、「クロックが1の間にデータを1から0に変化させる」という特殊な信号パターンを「通信開始」の合図にします。
この通信開始のパターンを「スタートコンディション」と呼んでいます。通信開始の条件、という意味です。
また、「クロックが1の間にデータを0から1に変化させる」という特殊な信号パターンを「通信終了」の合図にします。
先ほどと同じように、この通信終了のパターンを「ストップコンディション」と呼んでいます。
I2C通信の(1)通信開始の信号パターンはここで説明しましたスタートコンディション、(8)通信終了の信号パターンはストップコンディションになります。
(2) スレーブアドレスの送信
マスターがスタートコンディションを生成した後、すぐにスレーブを選択するためにマスターはスレーブアドレスを送信します。
第37回のスレーブアドレスのところで説明しましたが、実際にはスレーブアドレスの7ビットと読み取りか書き込みかの1ビットの合計8ビットのデータを送信します。
この8ビットはデータ送信と同じ要領で以下のタイミングチャートになります。スタートコンディションを生成したらすぐにスレーブアドレスを送信する点に注意してください。
(3) 選択されたスレーブの「了解」返信
I2C通信の場合、スレーブアドレス送信やデータ送信のあと、そのデータを受信した側は「了解」という信号を返信します。
具体的には、データ受信側はクロック信号に合わせて「了解」の時はデータとして0を、何か問題があって受信できていない場合はデータとして1を返信します。
この「了解」のことを「ACK」(アック)と呼んでいます。Acknowlegement(受領通知)の略です。また、何か問題があった場合にデータとして1を返信しますが、「了解しない」「問題があった」ことを「NACK」(ナック)と呼んでいます。Negative Acknowlegement(未受領通知)の略です。
このACK/NACK(アック/ナック)はI2C通信に限らず、何かのデータをやりとりするシステムではよく出てきますので、ここで慣れておきましょう。
タイミングチャートとしては以下のようになります。
(4) 1バイト送信と(5) 「了解」の返信
1バイト送信と「了解」の返信は、上のスレーブアドレスの送信と「了解」の返信と同じパターンになります。タイミングチャートは以下のようになります。
マスターが生成するクロックに合わせて、送信側が8ビットのデータを送信、受信側はACKを返信します。
以上を組み合わせるとI2C通信の通信手順になります。
PICマイコンI2C通信
SPI通信に比べると、I2C通信は信号制御が複雑ですよね。
SPI通信のプログラムを作る時は、SPIの通信手順に合わせてピンをデジタル制御していました。
これからI2C通信のプログラムを作っていくわけですが、ピンのデジタル制御をするプログラムを作るのは大変そうですよね。というのは、データ信号線(SDA)は送信だけではなく受信も行います。PICマイコンはピンの入出力設定はTRISレジスタでいつでも変更できますが、データを送るたびに入力と出力の切り替えを行うのも大変そうです。
PICマイコンにはI2C通信のモジュールが搭載されていますので、これから作成するI2C通信のプログラムではそのモジュールを使用します。
実は、PICマイコンにはSPI通信のモジュールも搭載されているのですが、実践編では使用しませんでした。理由は、モジュールを使うには設定などいろいろ大変なのと、SPI通信は通信手順はわかりやすいため、ピンのデジタル制御でプログラムを作成した方がより理解が深まるためです。
次回から、PICマイコンのI2C通信モジュールを使用したI2C通信プログラムを作成していきます。
更新履歴
日付 | 内容 |
---|---|
2018.6.11 | 新規投稿 |