水瓶座列車

どこまで行けるか、とりあえず発車します。

I2Cの通信フォーマットや波形の読み方の解説

f:id:aquarius999:20211230062342j:plain

 

組み込み開発では、制御したいハードウェアの仕様を理解し、そのハードウェアを制御するために、

知っておかなければならない基本知識がたくさんあります。その中の1つとしてI2Cがあります。

I2Cは、必ずと言ってよいほど組み込み開発では使用されますので、知っておくと良いです。

ここでは、I2Cの通信フォーマット、波形の取得方法から読み方など解説していきたいと思います。

 

 

 

 

 

1.I2Cについて

 

I2Cは、「アイツーシー」や「アイスクエアドシー」という言い方があり、

フィリップス・セミコンダクターズ(現在は、NXP セミコンダクターズ)が、開発したシリアル通信方式です。

実際の開発現場では、I2Cの言い方は、特に統一されていませんが、

その開発現場で呼ばれている方に合わせると良いと思います。

I2Cは、SCL(クロック線)とSDA(データ線)の2線を使用して、接続されているデバイスと通信を行います。

I2Cの接続イメージは、このような感じです。

f:id:aquarius999:20211228024058p:plain

 

そして、1つのバス(SCLとSDA)には、スレーブアドレスが7bitの場合、最大112個まで接続できますが、

複数のデバイスが1つのバスを共有して使用しているため、1つのバスに接続するデバイスは、

多くても3つか4つぐらいにする場合が多いです。

スレーブアドレスとは、接続されているデバイスのIDのようなもので、同じバス上では、唯一の値になります。

同じバス上に同一のスレーブアドレスのデバイスが接続されていると、通信エラーになります。

スレーブアドレスの値は、7bitもしくは10bitの値になっており、デバイス毎に設定されています。

また、通信元はマスターデバイスと呼び、スレーブアドレスを指定して通信を行います。

通信速度は、100kbps、400kbps、3.4Mbps、5Mbpsがありますが、

接続しているスレーブデバイスが対応している速度に合わせて設定します。

 

 

2.I2Cの7bit通信について

 

I2Cの7bit通信とは、スレーブアドレスが7bitになっているデバイスと通信を行うことで、I2Cの基本の通信です。

例えば、このブログでラズパイに接続したLCD1602の動作について書いているのですが、

LCD1602のスレーブアドレスの値は、0x26で、2進数にすると「0010 1010」となり、

7bit通信では、「010 1010」の7bitを使用します。

I2C通信を行うためには、I2Cの通信フォーマットに基づいて、データの送受信を行います。

マスターデバイスからスレーブデバイスにデータを送信する際の通信フォーマットは、以下です。

f:id:aquarius999:20211228024557p:plain

 

マスターデバイスがスレーブデバイスからのデータを受信する際の通信フォーマットは、以下です。

f:id:aquarius999:20211228024616p:plain

 

I2C通信をする際には、スレーブアドレスの後に送信か受信かを示すために1bitの値を付加する必要があります。

プログラム上でI2Cデータを作成する時には、

送信(Write)の場合は、スレーブアドレスを左に1bitシフトして最下位bitを0にして、

受信(Read)の場合は、スレーブアドレスを左に1bitシフトして最下位bitを1にします。

I2C通信フォーマットは、8bit単位で扱うことと送信/受信の操作を示す1bitを付加することが要点です。

送信時のデータの内容は、スレーブデバイスの仕様に従って、自分でデータを作成します。

スレーブデバイスからデータを受け取りたい場合には、

マスターデバイスからデータ受信したい旨をスレーブデバイスにデータで送信して、その後に、

マスターデバイスから受信フォーマットに従ったデータを送ると、

それに対する受信データがスレーブデバイスから受け取ることができます。

このように、受信の場合は、まず送信してから受信するという流れで行い、

この操作をシングルリード(Single Read)という呼び方をしています。

 

また、シングルリードは、送信/受信と2回通信することになり、処理時間がかかります。

そこで、送信受信を1回の通信できる複合フォーマットがあります。

f:id:aquarius999:20220103223250p:plain

 

このフォーマットでは、送信の後にリピートスタートコンディション(Sr)を行うことで、受信も続けて行うことができます。

複合フォーマットの要点は、リピートスタートコンディション(Sr)を行うことで、通信を繋げることができます。

なので、上記の受信フォーマット部分を送信フォーマットにすることで、2回連続送信も行うことができます。

システムの状況や処理速度を考慮して、使い分けると良いです。

 

 

3.I2Cの10bit通信について

 

I2Cの10bit通信とは、スレーブアドレスが10bitになっているデバイスと通信を行うことを言います。

スレーブアドレスが7bitの場合、最大接続数は、7bitの最大値である112個までなので、

その個数を超える場合を考慮して、スレーブアドレスのbit幅が10bitに拡張されました。

例えば、スレーブアドレスが0x266のようなデバイスで、この値を2進数で表現すると「0010 0110 0110」となり、

10bit通信では、「10 0110 0110」の10bitを使用します。

10bit通信にも7bit通信とは異なりますが、10bit用の通信フォーマットが決まっています。

ただ、10bit通信は、あまり使用しませんので、ここでは省略します。

 

 

4.I2C波形の読み方について

 

ここでは、7bit通信のI2C波形の解析のやり方について解説していきます。

7bit通信の送信時の波形は、以下のような感じです。

f:id:aquarius999:20211228030608p:plain

 

上図は、このブログのRaspberry Pi 3B+ でI2CキャラクタLCD(1602) の動作確認で使用した環境で取得した波形です。

D6がSCL、D7がSDAで、I2Cのタグは、波形取得ソフトで解析した結果になっています。

まず、I2C通信を始めるために、最初に「S」のスタートコンディションを設定します。

スタートコンディションをレジスタに設定すると、まずD7のSDAの電圧がHighからLowに変わります。

そして、I2Cのデータレジスタに送信データをセットしていくことで、

D6のクロックが出力されて、スレーブデバイスにデータが送信されます。

1バイト送信する毎にスレーブデバイスから「A」のACKが返され、順番にデータが送信されます。

波形の読み方は、SCLがHighの時に、SDAがHighになっていれば1,Lowになっていれば0になり、

8クロック毎にbit列にして、2進数から16進数に変換すると送信データを読むことができます。

ただ、先頭データのスレーブアドレス部分については、1bit左シフトしていることを考慮して読みます。

波形を読んで解析するケースは、

・組み込み開発では、新規I2Cデバイスのソフト(デバイスドライバ)を開発する際に通信確認をする。

・I2Cデバイスの通信エラーが出た場合に、原因を見つけるために通信を確認する。

などがあります。

 

また、波形のなまりを見たい時には、ロジックアナライザではなく、オシロスコープで見る必要があります。

波形のなまりとは、電圧の不安定などによって、LowからHighに電圧が上がる際に、緩やかに上がったり、

HighからLowに電圧が下がる際に、緩やかに下がったりと、通常時の波形と比べて曲線が目立つ波形のことです。

例えば、LowからHighになる場合に波形がなまると、Highと認識できないことがあったりして、

意図した動きにならずにバグの要因になることもあります。

 

 

5.独学でI2Cを勉強する方法について

 

I2Cの勉強や波形を実際に取得してみたいならば、

・ラズパイのような組み込みボード

・組み込みボードに接続するI2Cデバイス

・I2C通信波形を取得するためのロジックアナライザもしくはオシロスコープ

のような機材が必要になります。

 

ラズパイのような組み込みボード

 

組み込みボードは、世の中にいろいろありますが、ラズパイが一番おすすめです。

下記のように、Amazon楽天で、簡単に購入することができます。

 

ラズパイは、I2C以外にも、SPI、UART、カメラI/F、ディスプレイI/Fなどありますので、

組み込みについて、全般的に勉強することに役立ちます。

 

 

組み込みボードに接続するI2Cデバイス

 

I2C通信を行うためには、組み込みボードにI2C接続できるデバイスが必要になります。

例えば、このブログでも書いているLCD1602キャラクタデバイスのI2C版のようなデバイスで、

この他にもいろいろなデバイスがあります。

このようなデバイスは、Amazonで組み込みボードで使用できるセンサーキットが多数ありますので、

自分が触ってみたいI2Cデバイスがあるものを選ぶと良いと思います。

私の場合は、組み込みボードはラズパイを使用しているので、下記のようなセンサーセットを購入しました。

 

このセンサーセットの他にも、Amazon楽天で様々なセンサーセットの種類がありますので、

自分がやってみたいセンサーがあるセットを探してみるのも楽しいと思います。

 

I2C通信波形を取得するためのロジックアナライザもしくはオシロスコープ

 

I2C通信波形を見るためには、ロジックアナライザオシロスコープの機材が必要になります。

実際の開発現場で使用するような機材は、個人で購入するとなるとかなり高額になりますが、

安価な値段で波形を見ることができる機材があります。

私の場合は、下記の機材を購入して波形確認してみました。

 

この機材と無料でダウンロードできるPulseViewというソフトを使用することで、通信波形を取得することができます。

もちろん、I2Cだけでなく、SPIやUART、GPIOなど全ての波形を見ることができます。

この機材とPulseViewについては、

RaspberryPi 3B+でロジックアナライザを使ってI2Cの波形を取得する方法 - 水瓶座列車

で、手順を書いていますので、参考にしてみてください。

 

 

6.I2Cの用語まとめ 

 

これまでに解説していきた中で、理解しておきたいI2Cの用語について簡単にまとめてみました。

 

用語 説明
マスターデバイス I2Cの通信元の機器
スレーブデバイス I2Cの通信先の機器
スレーブアドレス 通信先を指定するために接続デバイスが持っているIDのような値
7bit 通信 スレーブアドレスが7bitのデバイスと通信を行うこと
10bit 通信 スレーブアドレスが10bitのデバイスと通信を行うこと
スタートコンディション I2C通信を始めるために最初に行うコマンド
ストップコンディション I2C通信を終了する時に行うコマンド
リピートスタートコンディション 複合通信フォーマット時に使用されるコマンド
NACK 指定したスレーブアドレスがバス上に存在しない場合のエラー
アービトレーションロスト 指定したスレーブアドレスがバス上に複数存在するなど、通信が競合した場合のエラー

 

I2Cを使用する組み込み開発では、必ずI2C通信の波形をみて、正確にデータを送信できているか、

受信できているかを確認しながら開発を行いますので、これらの用語を理解しておくと良いです。

 

 

7.最後に

 

I2Cの知識について、これだけ知っておくと、実際の組み込み開発でも十分通用する内容を書きました。

後は、実際にI2Cのソースコードや、I2Cを使用するソースコードを見たり書いたりするとより理解が深まります。

もし興味があれば、5項の独学でI2Cを勉強する方法で説明した機材を使用して、実際にI2Cを深く触ってみてください。

 

 

<関連・おすすめ記事>

RaspberryPi (ラズパイ)の購入時に最低限必要なものとおすすめセット - 水瓶座列車

Raspberry Pi (ラズパイ)の購入後すぐにやっておきたい設定を解説 - 水瓶座列車

プログラミングを独学で勉強するためのLinuxパソコン準備手順 - 水瓶座列車

RaspberryPi 4Bと3B+のスペック比較解説 - 水瓶座列車

Raspberry Pi 3B+ でI2CキャラクタLCD(1602) の動作確認 - 水瓶座列車

RaspberryPi 3B+でロジックアナライザを使ってI2Cの波形を取得する方法 - 水瓶座列車