Arduino 入門 番外編 07 SPI通信 とは

arduino-extra-edition-07-00 学習
スポンサーリンク

「Arduino 入門 番外編 07 SPI通信 とは」

こんにちはomoroyaです。

今回は、Arduino 入門 番外編 07 SPI通信 とはです。

arduino 入門 番外編はarduinoの基本的なことを書いていく方向性にしたいと考えています。

本日は、arduinoのSPI通信についてです。
※Serial Peripheral Interfaceの略

 

その前に、arduinoの外観とピン配置を確認することをおすすめします。

 

arduino自身のことを少しづつ理解して行きましょう。

 

いやいや、arduinoを早速始めたいんだ!というかたは下記の入門編からお読みください。

 

Lessonの入門編で使用しているArduinoは互換品です。

互換品とは言え、Arduinoはオープンソースであり複製して販売するのもライセンス的に問題なし。

そのため互換品の品質も悪くなく、それでいて値段は安いです。

正規品本体の値段で豊富な部品が多数ついています。

 

スポンサーリンク

SPI通信について

SPI通信とは、番外編06で説明したI2C通信と同様に、ICなどの電子部品との通信のために開発された通信方式です。

ICとデバイス間で通信することを目的に、旧モトローラ社が提唱した通信規格です。

SPIとは?

wikipedia シリアル・ペリフェラル・インタフェース(Serial Peripheral Interface, SPI)

シリアル・ペリフェラル・インタフェース(Serial Peripheral Interface, SPI)は、コンピュータ内部で使われるデバイス同士を接続するバスである。パラレルバスに比べて接続端子数が少なくて済むシリアルバスの一種で、比較的低速なデータ転送を行うデバイスに利用される。

 

SPI通信の特徴は、I2Cと同様に少ない信号線で通信のやり取りができる通信方式です。

また、I2Cに比べて高速通信にも対応しいます。

番外編06で説明した、I2Cは標準モードで100kbpsと低速で、高速に対応したデバイスでも3.4Mbpsでしか通信できません。

そのため、ストレージなど大量のデータ転送が必要なデバイスには向きません。

SPIは、デバイスにもよりますが最大数十Mbpsの通信が可能です。

 

また、SPI通信はI2C通信と同様に電子部品を制御する「マスター」と、「マスター」からの命令によって制御される「スレーブ」に分かれます。

Arduinoを使用する場合は
マスター:Arduino
スレーブ:制御する電子部品※I2C通信方式同様にSPI通信に対応した電子部品を複数接続することが可能です。

 

SPI通信の信号線

SPIは4本の信号線で制御します。
※ちなみにI2Cは2本。

 

信号名用途
SCLK
Serial Clock
データ転送を同期させるためマスタにより生成されるクロック信号
※機器によってはSCLと記載されている場合もあります。
MISO
Master In Slave Out
スレーブからマスタへのデータ送信ライン
MOSI
Master Out Slave In
マスタからスレーブへのデータ送信ライン
SS
Slave Select
制御対象のデバイスの選択をするための信号ライン
CS(Chip Select)、CE(Chip Enable)と記載されている場合もあります。

※マスタ:Arduino、スレーブ:周辺デバイス

 

上記に加えて、電源ラインのVDDとGNDの2本必要となります。

 

Arduino SPI端子

番外編02のおさらいです。

Arduino UNO R3の外観図を下記に示します。

SPIに使用する端子はデジタル入出力と同じ端子を利用します。

外観図右上にあるデジタル10,11,12,13の端子です。

デジタル13が「SCLK」。

デジタル12が「MISO」、デジタル11が「MOSI」。

デジタル10が「SS]。

arduino_uno_R3-appearance

 

通信速度について

Arduino UNO R3はマイコン(ATmega328p)のハードウェアSPIを利用しています。

SPIクロック信号はシステムクロックを分周した周波数です。
※分周とは周波数を1/Nにすることです。
動作を遅くできると考えて問題ありません。

 

選択できる分周比は1/2、1/4、1/8/、1/16、1/32、1/64、1/128の7つです。

データシートには以下のように記載されています。

SPR10011
SPR00101
SPI2X10101010
SCK周波数fOSC/2fOSC/4fOSC/8fOSC/16fOSC/32fOSC/64fOSC/128

fOSC:システムのクロック周波数
上記のように最小の分周比が1/2となっています。

 

Arduino UNO R3のシステムクロックは16MHzです。

そのため、設定できる最大動作スピードは、16MHz×1/2=8MHzとなります。

 

実際に使用する場合は、周波数を制御するデバイスの仕様に合わせる必要があります。

制御するデバイスの周波数を超えないように設定してください。

 

興味のあるかたはATmega328-328PのDatasheetをご確認ください。

詳しい仕組みはわからなくても、SPI通信を使えてしまうのがArduinoの良いところです。

まずは、こんなもんか程度で遊んでみて必要になったら詳しく勉強するでかまいません。

 

SPI通信方法

SPI通信で使用する4本の信号線の接続方法は以下となります。

arduino-extra-edition-07-01

 

電源はArudinoのからの供給能力で足りる場合は図の通りとなります。
※必要に応じて別の外部電源につなげます。

SS(Slave Select)は制御する電子部品の数で決まります。

図では、2つの電子部品を制御することをイメージしているので2本となります。

SS = Lowとすることで、制御する電子部品を選択たします。

 

次に通信方法の概略図を示します。

arduino-extra-edition-07-02

 

SPI通信のやりとりは図に示すように、MOSIとMISOで行います。

MOSIはArduinoからのデータ送信。

MISOは電子部品からのデータ受信。

それぞれの電子部品には送信するためのデータを格納するシフトレジスタがあります。

シフトレジスタに格納されたデータは、1ビットごとに送信、受信を繰り返して同時に送受信します。

データ送信時は、命令を送信後、送信内容を送ります。

データ受信時は、マスターから受信命令を送り、スレーブ側ではシフトレジスタ内にデータをセットしてマスターに送り返します。

 

上記は概略を説明したものです。

実際には、使用する電子部品によって異なるため、各種データシートを確認する必要があります。

 

wikipedia シフトレジスタ

シフトレジスタ(英: Shift register)とは、複数のフリップフロップをカスケード接続し、データがその回路内を移動(シフト)していくよう構成したデジタル回路のこと。

 

SPI通信について詳しく知りたい方は、下記のサイトが参考になるかなと思います。

 

SPIを使うための「SPIライブラリ」

ArduinoでSPI対応の電子部品を使うための方法はライブラリを使用するのが簡単です。

ライブラリ名:「SPI」ライブラリ
※標準でIDE環境に実装されています。

このライブラリを使うことで、SPI制御用の各関数が使えるようになります。

#include <SPI.h>

ArduinoのIDE環境を立ち上げたら
「スケッチ」⇒「ライブラリをインクルード」⇒「SPI」
を選択すれば使えるようになります。

 

以下、SPIライブラリの関数について列挙します。

コマンド内容
SPI.begin()SPIライブラリの初期化処理。および有効化。
SCLK,MOSI,SSの各ピンは出力に設定される。
初期値は下記に設定される。
SCLK、MOSI:Low
SS:High
戻り値:なし
SPI.end()SPI通信を無効にする。
各ピンの設定は変更されない。
戻り値:なし
SPI.setBitOrder(order)データを送信するビットの順序を設定する。

パラメータ
order:LSBFIRSTまたはMSBFIRST
下位ビット、上位ビットのどちらから送信するかを指定できる。

戻り値:なし

SPI.setClockDivider(divider)SPIクロック分周器を設定する。
分周値:2,4,8,16,32,64,128
デフォルト:4パラーメータ
divider:
SPI_CLOCK_DIV2
SPI_CLOCK_DIV4
SPI_CLOCK_DIV8
SPI_CLOCK_DIV16
SPI_CLOCK_DIV32
SPI_CLOCK_DIV64
SPI_CLOCK_DIV128
戻り値:なし
SPI.setDataMode(mode)SPIの転送モードの設定。
データを取得するタイミングを指定する。クロック極性:
アイドル状態時のクロックがHighかLowか。
位相極性:
データ取得タイミングがクロックの立上がりか、立下りか。

パラメータ
mode:
SPI_MODE0:アイドル時Low、立上がりエッジ
SPI_MODE1:アイドル時Low、立下がりエッジ
SPI_MODE2:アイドル時High、立上がりエッジ
SPI_MODE3:アイドル時High、立下がりエッジ
戻り値:なし

SPI.transfer(value)データの送受信をする。
SPIパスでの1バイト転送。
送信、受信の両方で使用。パラメータ
value:転送するバイト
戻り値:受信したバイト

 

SPIライブラリ関数 使用例

ここからは、SPIライブラリの使用例を示します。

SPIライブラリを使用するためには、プログラムの先頭でSPIライブラリを読み込みます。

#include <SPI.h>

 

SPIライブラリの初期処理

SPIを使えるようにするために、setup()関数内で下記を記述します。

void setup(){
   pinMode( SS, OUTPUT ); //デジタル10番ピンをOUTPUTに設定
   digitalWrite( SS, HIGH ); //デジタルの10番ピンからHighを出力

   SPI.setBitOrder( LSBFIRST ); // 下位ビットから送信
   SPI.setClockDivider( SPI_CLOCK_DIV8 ); //分周器1/8を指定 同期クロック16/8=2MHz
   SPI.setDataMode( SPI_MODE0 ); //アイドル時Low、立上がりエッジでデータ取得

   SPI.begin(); //SPI通信の初期化、有効化
}

 

SPIデバイスへのデータ送信

SPIデバイスにデータを送る手順は以下となります。

 

1.SPIデバイスと通信ができるようにする。
対象の電子部品に接続したSSのデジタル出力を「Low」にする。

2.SPI.transferで送信する値を指定。
続けて送信する場合は、連続で上記を実行。

3.必要に応じて、待機時間を入れる。(電子部品のデータシートを参照)

4.通信が完了したらSSを「High」にする。

 

digitalWrite( SS, LOW ); //対象の電子部品を接続したSS
SPI.transfer( 送信する値 ); //data送信
delay( 10 ); //必要に応じて設定
SPI.transfer( 送信する値 ); //続けて送信する場合
digitalwrite( SS, HIGH ); //通信終了

 

SPIデバイスのからのデータ送受信

SPIは送信と受信を同時にやりとりする仕組みです。

そのため、SPI.transfer()でデータを送信するとSPI対応の電子部品からデータが送られてきます。

送られたデータはSPI.transfer()の戻り値となります。

 

1.SPIデバイスと通信ができるようにする。
対象の電子部品に接続したSSのデジタル出力を「Low」にする。

2.SPI.transfer()の戻り値を変数に格納。

3.通信が完了したらSSを「High」にする。

 

digitalWrite( SS, LOW ); //対象の電子部品を接続したSS
value = SPI.transfer( 送信する値 ); //valueに電子部品から受信したデータを格納
digitalwrite( SS, HIGH ); //通信終了

 

電子部品がArduinoからの命令を受け取ってから次のタイミングで結果を送るような場合は以下のように記述します。

digitalWrite( SS, LOW ); //対象の電子部品を接続したSS
SPI.transfer( 送信する値 ); //data送信
delay( 10 ); //必要に応じて設定
value = SPI.transfer( 送信する値 ); //valueに電子部品から受信したデータを格納
digitalwrite( SS, HIGH ); //通信終了

 

連続してデータを受信したい場合は以下のように記述します。

digitalWrite( SS, LOW ); //対象の電子部品を接続したSS
value1 = SPI.transfer( 送信する値 ); //valueに電子部品から受信したデータを格納
value2 = SPI.transfer( 送信する値 ); //valueに電子部品から受信したデータを格納
digitalwrite( SS, HIGH ); //通信終了

 

いかがですか?

I2Cと違いアドレスの指定ではなく、「SS」で電子部品の選択ができます。

私としては、こちらの方が使いやすいかなと感じています。

実際はどちらがというのは、用途次第というのもあります。

 

まとめ

今回は、SPI通信について概略を説明しました。

演習では実際にSPI通信に対応した電子部品を使って制御してみたいと考えます。

 

Arduino 入門のLesson編にてSPI対応の電子部品を使った実践の解説を記事にする予定です。

Lesson編の記事を更新しだい、ここにもリンクを貼りますのでしばらくお待ちください。

 

次回の番外編 08は「UART通信」の解説を予定しています。

Arduinoのデジタル通信方式の3つとなりますので次回が最後の予定です。

 

Lessonの入門編で使用しているUNOはAmazonにて購入可能です。

Amazon ベストセラーNo.1
ELEGOO UNO キット レベルアップ  チュートリアル付 uno mega2560 r3 nanoと互換 Arduino用

 

上記のものでも十分に多数の部品が入っていますが、最初からもっと多数の部品が入っているこちらもお勧めです。

ELEGOO Arduino用UNO R3 最終版スタータキット UNOチュートリアル付 (63 Items)

コメント

タイトルとURLをコピーしました