PIC解説

【PIC】SPI通信のやり方

投稿日:2020-08-15 更新日:

多くの PIC に搭載されている MSSPモジュールを使うと I2C と SPI の2つのシリアル通信を行うことができます。

今回は SPI通信のやり方(マスター)を紹介します。

I2C についてはこちらを参照してください。

【PIC】I2C通信のやり方

SPI通信とは

まず初めに SPI通信について軽く紹介します。

SPI通信ではマスターとスレーブがそれぞれシフトレジスタを持っていて、クロックに合わせてその値を交換します。

通信に必要な線は、INPUT、OUTPUT、クロックの3本と、スレーブ1つにつき1本のスレーブ選択用の線となります。

スレーブが複数あっても2本で通信できる I2C に比べて、多くの線が必要となるのはデメリットと言えます。

では、SPI のメリットは何かというと、通信速度の速さが挙げられます。I2C のクロック周波数は主に 100kHz や 400kHz ですが、SPI では 1MHz 以上(PIC のクロックに依存しますがもっと)出すことができます。

センサーなどのほかに通信量の多い液晶や SDカードとの通信などに使われます。

 

SPI通信の種類

SPI通信を行うときに注意しなくてはいけないのは、SPI通信には次のようにいくつもの種類があるということです。

  1. クロックのアイドル状態:Low / High
  2. 送信タイミング:Idle to Active / Active to Idle
  3. 受信タイミング:中央 / 後縁

Timing chart

統一されていれば楽なのですが、デバイスに合わせて設定しなければいけません。いきなりこれを見てもよく分からないと思うので、具体的な事例で確認してみましょう。

 

今回はこちらの温湿度・気圧センサーBME280を使用します。データシートを確認してみると、SPI通信のタイミングチャートが載っていました。

BME280 SPI timing chart

この図から次のことがわかります。

  1. クロックのアイドル状態:High
  2. 送信タイミング:Active to Idle
  3. 受信タイミング:中央

このようにデータシートを確認して通信の種類を決定しましょう。

 

SPI制御レジスタ

続いて、SPI通信を制御するためのレジスタについて説明します。MSSPモジュールは I2C と SPI の両方をサポートしていますが、今回は SPI のマスターに関わる部分だけ説明します。

以下、レジスタ名に “x” が登場しますが、これは MSSPモジュールを複数搭載している場合にその総称として用いています。

実際に使用するときには、1または2、MSSPモジュールが一つだけの場合は何も無いものとして解釈してください。

SSPxSTAT

SSPxSTAT

SMP (SPI Data Input Sample bit)
受信サンプル位置
1:後縁  0:中央
 
CKE (SPI Clock Edge Select bit)
送信エッジ
1:Active to Idle 0:Idle to Active
 
BF (Buffer Full Status bit)
1:SSPxBUF にデータあり  0:データなし

SSPxSTATレジスタでは、クロックの設定とバッファフル状態の確認ができます。他のビットは I2C のときのみ使用するビットです。

 

SSPxCON1

SSPxCON1

WCOL (Write Collision Detect bit)
1:Write衝突発生  0:正常SSPOV (Receive Overflow Indicator bit)
1:受信オーバーフロー発生  0:正常
 
SSPEN (Synchronous Serial Port Enable bit)
1:SSP有効化  0:無効化
 
CKP (Clock Polarity Select bit)
クロックのアイドル状態
1:High  0:Low
 
SSPM (Synchronous Serial Port Mode Select bits)
1010:SPIマスター Clock = FOSC/(4 * (SSPxADD+1))
0011:SPIマスター Clock = TMR2/2
0010:SPIマスター Clock = FOSC/64
0001:SPIマスター Clock = FOSC/16
0000:SPIマスター Clock = FOSC/4

SSPxCON1レジスタでは SPIのモードなどを設定します。最初の二つのビットは使わないで大丈夫です。クロックの周波数は迷ったら一番速い 0000 にしておけば大丈夫だと思います。

SSPxBUF

SSPxBUFレジスタは送受信に使うバッファです。

このレジスタに値を書き込むことでその値が送信され、同時に受信した値はこのレジスタを読むことで取得できます。

 

サンプルプログラム

続いて、先程のレジスタを使用するサンプルプログラムを紹介します。

まずは、初期化と1バイトを交換する関数です。

SPI の設定は今回使用する BME280 に合わせています。

交換の関数ですが、引数を送信し、受信した値を戻り値として返します。送信のみの場合は戻り値を無視し、受信のみの場合はダミーのデータを送信します。

 

次に、BME280 の通信プロトコルを確認してみましょう。

書き込みBME_write

読み出し

BME_read

これを参考にして作ったコマンド書き込みとデータ読み出しの関数がこちらです。

CSはチップセレクタピンで、#define で指定しておきます。

I2C と異なり、SPI ではスレーブアドレスを送信する必要がない代わりに、Read/Write をレジスタアドレスの先頭ビットに指定する必要があるようです。

 

動作確認

それではこのプログラムを使用して、温度を読み取って LCD に表示させてみたいと思います。今回使用するものは以下の通りです。

  • PIC16F18857
  • 温湿度・気圧センサーBME280
  • I2C接続LCD

LCD に I2C を使うので、センサーも I2C を使えばいいのですが、今回は SPI の動作確認なので目を瞑りましょう。

プログラムは以下の通りです。I2CLCDセンサーの使い方はそれぞれリンク先のページで説明しているため、ここでは省略します。必要に応じて参照ください。

I2Cライブラリ

LCDライブラリ

PIC16F18857 では SDO と SCK のピンがデフォルトで割当て先が決まっていないので PPS の設定をしておきます。

また、I2C では SCL や SDA のピンは入力にしますが、SPIでは普通の感覚で SCK と SDO は出力、SDI は入力にします。

回路図はこんな感じです。

Schematic

無事に動作確認できました。暑いですね…

Operation_check

この記事は以上となります。ご覧いただきありがとうございました。

-PIC解説

執筆者:


comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

関連記事

PIC超入門!ゼロからLチカまでの道【その2:プロジェクト作成~プロパティ設定】

前回 MPLAB X IDE を導入したので、今回はプロジェクトの作成から説明していきます。 前回の記事はこちら PIC超入門!ゼロからLチカまでの道【その1:部品購入~IDE導入】 目次1 プロジェ …

PIC超入門!ゼロからLチカまでの道【その3:コンフィギュレーション~プログラミング】

前回プロジェクトを作成して設定まで終わったのでいよいよプログラミングに入ります。PIC の第一の関門であるコンフィギュレーションも順を追ってやっていけば簡単にできます。 前回の記事はこちら PIC超入 …

【PIC】LCD 1602の使い方

今回はパラレル接続のキャラクタLCD の使い方を紹介します。 タイトルに 1602 とついていますが、キャラクタLCD の制御IC は大抵同じものなので、文字数の違うものだったり、メーカーの違うもので …

【PIC】ぷちFatFsでmicroSDカードと通信する

今回は PIC で microSDカードを使用する方法を紹介します。なお、microSDじゃなくて普通のSDカードでも同様にできるはずです。 以下 microSDカードも含めて SDカードと呼ぶことに …

PIC超入門!ゼロからLチカまでの道【その4:プログラム書き込み~Lチカ】

前回プログラムが完成したので、あとはプログラムを書き込んで、回路を組み立ててついにLチカです! あともう少しでゴールなので頑張りましょう。 前回の記事はこちら PIC超入門!ゼロからLチカまでの道【そ …