マイコン(Master)とZynq(Slave)をI2C通信する方法 (1)デバイス間の接続構成

Vitis
スポンサーリンク

本記事の概要

概要

I2C(Inter-Integrated Circuit)規格でマイコンとZynqをデータを通信する方法を解説。実験に用いるマイコンには、Wio TerminalのATSAMD51P19を選ぶ。まず、マイコンの方をマスター(Manager, Master)として、スレーブ(Subordinary, Slave)であるZynqからデータを要求する。
本記事では、I2C通信方式について解説した後、マイコンとZynqの接続の構成について解説する。

ZynqやWio Terminalで遊んでいると、世の中に流通している加速度センサやイメージセンサを接続し、IoTデバイスを作ってみたいという欲にかられます。
I2C(Inter-Integrated Circuit)規格 は、タッチセンサや加速度センサなどのセンシングデバイスとの接続によく用いられる通信規格です。


イメージセンサでも、例えば安価で手軽に用いられるOV7670のようなセンサでは、設定レジスタの書き換えに、I2Cと類似したSCCB通信が用いられています。

センシングデバイスをI2C通信で制御する知見を得るため、I2C通信規格について学ぶとともに、ZynqやマイコンでI2C通信を行う方法について調べ、実際に試してみました。
いきなり、センシングデバイスを接続するとデバッグや動作検証がしにくかったので、今回はWio TerminalのマイコンATSAMD51P19とZynqとの通信に挑戦しました。Wio TerminalをM側(マスター)、ZyboをS側(スレーブ)とした通信をまず行っています。

Wio Terminalは加速度センサや光センサを備えるほかに、無線通信機能も備えており、これひとつでIoTデバイスとしてやりたいことが大体できてしまいます。
価格も比較的安価なので、一台持っておいても良いと思います。

本記事では、I2C通信方式について解説しつつ、デバイス間の接続構成までを解説したいと思います。

本記事の対象読者:以下の状況に直面している方
  • I2C通信の動作原理、構成について知りたい場合
  • ZynqのプロセッサからI2C通信を行うAPIドライバの使用方法を知りたい場合
  • Wio Terminalを使った、外部機器とのI2C通信の方法を知りたい場合

今後の記事では、以下の順に解説をしていきます。

  1. I2C通信の概略とデバイス間の接続方法(←本記事)
  2. Zynqにおけるブロックデザイン
  3. サンプルプログラムxiicps_intr_slave_example.cにおけるドライバAPIの動作原理
  4. Wio Terminalの制御コード(Arduino)

I2C通信とは

I2C通信規格は、フィリップス社で開発された規格で、SCL(シリアル・クロック)とSDA(シリアル・データ)の2本の信号線を使って通信する同期式シリアル通信の1種です。

ひがし
ひがし

I2CやUARTなどの汎用的に使われる通信規格は、以下の書籍を参考にしています。組み込みマイコン周りのメモリやペリフェラルについて広く浅く記載されているので、網羅的に組み込みシステムを理解する初学者向けの書籍です。
細かいところまでは記載されていないので、より通信規格について学ぶにはWebや別の本が必要にはなりますが、まず持っておいても損はないかと思います。

シリアル・クロックのクロック周波数は、一般的に4種類あります。

I2C通信のビットレート
  • 高速モード(High Speed mode):3.4 Mbit/s
  • ファーストモード(Fast mode):400 kbit/s
  • 標準モード(Standard mode):100 kbit/s
  • 低速モード(low-speed mode):10 kbit/s

I2C通信の接続方法

I2C通信でデバイス間を接続する配線は、デバイス間でSCL信号とSDA信号とをやり取りするための2本の伝送線に加えて、GNDをデバイス間で共通に揃える配線の、合計3本の配線で構成されます。また、一方の機器に電源を供給したい場合は、さらに電源Vddの配線を加えた、合計4本の配線で構成されます。

ここで、I2C通信での注意点が、2本の信号線(SDA, SCL)はVddにプルアップしておくという点です。

プルアップする理由

各信号線はオープンコレクタと呼ばれる出力方式でデバイスと接続されています。

オープンコレクタ、オープンドレイン出力とは

NPNトランジスタをスイッチとして動作させている出力方式で、トランジスタがOFF状態のときはプルアップしているHigh状態(電圧Vdd)、ON状態のときは短絡されたLow状態(電圧GND)が出力される。

バイポーラ・トランジスタではオープンコレクタ、MOS型トランジスタではオープンドレインと呼ばれるが、機能は同じ。

このオープンコレクタ方式であれば、一方をHigh、もう一方をLowに設定したとしても、大電流が流れるのを防ぐことができるようになります。

Low状態とするデバイスがあっても、プルアップ抵抗に電流が流れるだけで済みますので、機器の破壊を避けることが可能です。

ただし、 Vddにプルアップしておかないと、両方の信号源がOFF状態のとき、信号の電圧が不定になってしまいます。そのため、必ずプルアップする必要があります。

I2C通信のプロトコル

I2C通信では、1台のマスターデバイスに、複数のスレーブデバイスを接続することができます。例えば、マイコンがマスターデバイスとなって、複数のセンサから情報を取得するような用途で用いられます。また、一本のSDA線を介して双方向に信号がやり取りされます。
そのため、 I2C通信でのデバイス間でのプロトコル(通信手順) は若干複雑になるので、簡単にまとめました。

I2C通信のプロトコル

通信を開始するときには、M側(マスター)となるデバイスが、まずSCL信号がHigh状態のときのSDA信号をLowに落とす、立ち下がりを行います。これを、Start Conditionとし、データの送受信を開始します(①)。

続いて、スレーブアドレスを順にSCLと同期させてシリアル伝送します(②)。
I2C通信では、マスターから複数の S側(スレーブ) のデバイスと通信することが可能で、S側(スレーブ)のデバイスにはそれぞれアドレスが割り当てられています。
これにより、複数のスレーブのうち、マスターが通信したいデバイスを特定し、どのスレーブとデータの送受信を行うかを決定します。

次に、Writeコマンド(0)、あるいはReadコマンド(1)を送信します(③)。
これにより、マスターからデータを送信するか(Write)、スレーブからデータを送信するか(Read)かを決定します。

アドレスとWrite/Readコマンドを受け取ったスレーブ側のデバイスは、無事受け取ったことを示す、ACK信号を返します(④)。


通信するデバイスの特定と送受信の方向について、デバイス間で合意をとることができました。(といっても、マスターがすべて指示していますが…)
次に実際のデータの送受信の手順を説明します。

⑤ ACK信号を送信・受信後、データを送信する方のデバイスが、データを1byte分(8bit)送信します。
このとき、スレーブ側のデバイスがbusy状態のときは、SCLをLowに落とすことによって、スレーブがReadyになるまで待つことが可能です。

データ受信した方のデバイスがACK信号を返します

⑤と⑥の動作を送受信したいバイト数だけ繰り返して行います。
SCLがHighレベルのときのSDAの立ち上がりをStop Conditionとし、マスター側からデータの送受信を終了します(⑦)。

デバイス間の接続

では、I2C通信の概略を理解したうえで、実際にデバイスであるWio TerminalとZynqを接続していきたいと思います。

冒頭でも述べた通り、Wio TerminalとZynqをI2C通信するにあたり、今回はWio TerminalのマイコンをM(マスター)側に、ZynqをS(スレーブ)側としました。

Wio Terminal

Wio TerminalにはもともとI2C通信のためのバスが2種類用意されています。

Wio TerminalのI2Cポート
  • I2C0: Wio Terminal内部の加速度センサ、背面の40ピンコネクタの27端子(SDA)・28端子(SCL)と接続。Arduinoでは[Wire1.h]で制御可能。
  • I2C1: 背面の40ピンコネクタの3端子(SDA)・5端子(SCL)、側面のGroveコネクタ(#1。左側のポート)と接続。Arduinoでは[Wire.h]で制御可能。

ブロック図で示すと、このようになります。
図のATSAMD51P19がWio Terminalで使われているマイコンです。

今回は、I2C1の方のバスを利用し、背面の40ピンコネクタからジャンパ線でZyboと接続します。

Zybo

Zynqでは、Wio Terminalとやり取りするためのコネクタとして、Pmod JBを選択しました。

Zybo Reference Manual - Digilent Reference
Zybo Reference Manual Note The Zybo Zynq-7000 has been retired and replaced by the Zybo Z7. If you need assistance with migration to the Zybo Z7, please follo...

下のZyboの写真におけるU20をSDAT20をSCLとし、Wio Terminalとやり取りすることにしました。
各PmodとZynq I/Oとの接続の関係やZynqの制約ファイル(出力ピンをどう割り付けるか)の設定は次回の記事で解説します。

Digilent HP https://digilent.com/reference/programmable-logic/zybo/reference-manualより抜粋

デバイス間の接続

実際の接続はブロック図のようにして、Wio TerminalとZyboの間にブレッドボードを配置しています。

ブレッドボード上に、10kΩのプルアップ抵抗を接続して、SCLとSDAをHigh状態にプルアップしました。プルアップ抵抗の大きさは立ち上がりの時定数を考慮すると、2.2kΩや5kΩなど、もう少し下げた方がよい気もしましたが、手持ちによい抵抗がなかったため、今回は10kΩとしました。

プルアップのためのVdd信号はWio Terminalの3.3V電源を利用しました。なお、注意点としてWio TerminalとZyboはそれぞれ別電源に接続されているので、PWR電源同士を接続しないように注意が必要です(ともに3.3V同士ではありますが、素子破壊の恐れもあります…)

I2C通信配線名Wio Terminal 40ピンコネクタZybo ピン
SCL#5Pmod JB01 (T20)
SDA#3Pmod JB02 (U20)
Vdd#17【接続しない】
GND#20Pmod JB05
I2C通信におけるデバイス間の接続でのピンの対応表

実際に接続した、Wio TerminalとZyboの写真はこの通りです。

ひがし
ひがし

センサを活用したIoTデバイスづくりをやってみようと思い、手始めにI2C通信の実装が難しそうでしたので、簡単な回路から作成してみました。
次回の記事では、Zynq内部のブロックダイアグラムについて解説しようと思います。

最後までご覧いただきありがとうございました!

スポンサーリンク


次回の記事のリンク

参考:コードの動作を確認したシステムの構成

開発環境

環境
  • 開発用PC: Windows 10, 64bit
    • Vivado Design Suite – HLx Edition – 2020.2
    • Vitis コア開発キット – 2020.2
  • 開発用基板: Zybo Zynq-7010評価ボード(Board Rev.4)
    • Zynq XC7Z010-1CLG400C
  • 開発用マイコン: Wio Terminal
    • ATSAMD51P19

開発ボード Zybo Zynq-7010評価ボード

コメント