ホームに戻る
 PIC16F88 でSPI通信

0、はじめに

PICはSPI通信によってデータの送受信を行うことができます。
(ただし、SPI通信機能の無いPICもあるので注意)
SPI通信は主に基盤上などの短い距離の通信を想定しており長距離通信には向かないようです。
PIC16F88 にはSPI通信の機能があります。
PIC16F88 を2つ使って通信してみます。

1、PIC16F88 について

1個200円くらいで売っています。
PIC16F88 はSPI通信に対応しています。
SPI通信に設定すると以下のピンがSPI通信用に設定されます。

RB1:受信ピン
RB2:送信ピン
RB4:クロック用ピン
RB5:スレーブセレクトピン(スレーブの場合のみ使用)

2、SPI通信について

SPI通信はマスターとスレーブ間で通信します。
PIC16F88 はマスターとしてもスレーブとしても動作します。
初期設定でマスターにするかスレーブにするか設定する必要があります。
複数のPICで通信する場合マスターは必ず1つです。
マスター1つで複数のスレーブと通信が可能です。
スレーブにはスレーブのアクティブと非アクティブを選択できるピンがあります。
マスターの汎用ピンでスレーブのアクティブ、非アクティブを操作することで、
データの通信をしたいスレーブをマスターが選択できるのです。
実際にはスレーブのスレーブセレクトピンをLowにすると通信可能になります。
操作できるスレーブの最大数はマスターが自由に使える汎用ピンの数と言えます。

送受信は8ビット単位の双方向通信です。
バッファとして SSPBUF レジスタを利用します。
受信単独や送信単独はできません。
受信だけしたい場合でもダミーを送信する必要があります。

まず送信したいスレーブのスレーブセレクトをLowにします。
送信の仕方はWレジスタから SSPBUF のデータをセットするだけ。
次に、SSPSTAT の BF が1になるのを待ちます。
(BF は SSPSTAT の bit0 です)
これが1であれば送受信が完了したことになります。
SSPBUF のデータをWレジスタに入れれば受信完了となります。
受信とともに SSPSTAT の BF も0にクリアされます。

コードにすると以下のようです。

; 00000001 をSPI通信で送信
 MOVLW B'00000001'
 CALL SPI
 ; Wレジスタに受信データあり

; SPI通信本体
SPI
 MOVWF SSPBUF
 BSF STATUS,RP0
SPI_LOOP
 BTFSS SSPSTAT,BF
 GOTO SPI_LOOP
 BCF STATUS,RP0
 MOVF SSPBUF,W  ; 受信したデータをWレジスタに移動
 RETURN

マスターがスレーブセレクトをするのはマスターだけのことだが、
送受信自体にマスターとスレーブで大きな違いは無い。

3、回路設計

PIC16F88 と PIC16F88 を繋ぐ場合。
送信ピンから受信ピンに繋ぐ。
クロックはクロック同士で繋ぐ。
マスターの汎用ピンからスレーブのスレーブセレクトピンに繋ぐ。

4、初期設定

ポートの入出力を設定します。

マスターであれば受信用に RB1 ピンを入力にします。
スレーブであればクロックも受信するので RB1 と RB4 を入力にします。
スレーブであってスレーブセレクトを使用する場合は RB5 も入力にする。

SSPCONレジスタを設定します。

bit0-3:マスター、スレーブの選択とクロック、スレーブセレクトの設定
bit5:1にするとSPI通信有効です。

bit0 から bit3 は以下のようになります。

0000:マスター PICのクロック/4
0001:マスター PICのクロック/16
0010:マスター PICのクロック/64
0011:マスター TMR2の出力/4
0100:スレーブ スレーブセレクト有効
0101:スレーブ スレーブセレクト無効

5、サンプルコード

; PIC16F88 でSPI通信を行うサンプル
;  以下のサンプルはマスター用のコードです。
;  スレーブのコードはコメントアウトしてあるので、
;  スレーブとして使う場合はマスターと入れ替えてください。
;  2箇所あります。

 LIST P=PIC16F88
 INCLUDE P16F88.INC

__CONFIG _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_OFF & _PWRTE_ON & _WDT_OFF & _HS_OSC 
__CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF

 T0 EQU 20H
 T1 EQU 21H
 T2 EQU 22H
 T3 EQU 23H
 RXDATA EQU 24H

; スタート地点

 ORG 0

; 初期設定

 BSF STATUS, RP0
 CLRF TRISA
 MOVLW B'00000010' ; RB1 を入力に マスター
 ;MOVLW B'00010010' ; RB1 RB4 を入力に スレーブ
 MOVWF TRISB
 MOVLW B'00000000'
 MOVWF SSPSTAT
 BCF STATUS, RP0
 MOVLW B'00100010' ; SPIモード マスター クロック/64
 ;MOVLW B'00100101'  ; SPIモード スレーブ SSピン無効
 MOVWF SSPCON

 MOVLW B'00000011'
 MOVWF PORTA

 CALL TIME1000

LOOP

 MOVLW B'00000001'
 CALL SPI

 MOVF RXDATA,W
 MOVWF PORTA

 CALL TIME1000

 MOVLW B'00000010'
 CALL SPI

 MOVF RXDATA,W
 MOVWF PORTA

 CALL TIME1000

 GOTO LOOP

SPI
 MOVWF SSPBUF
 BSF STATUS,RP0
SPI_LOOP
 BTFSS SSPSTAT,BF
 GOTO SPI_LOOP
 BCF STATUS,RP0
 MOVF SSPBUF,W
 MOVWF RXDATA
 RETURN

; 以降、遅延タイマー

; 0.4ms
TIME04
 MOVLW D'250'
 MOVWF T1
TIMELOOP1
 NOP
 DECFSZ T1,F
 GOTO  TIMELOOP1
 RETURN

; 20ms
TIME20
 MOVLW D'50'
 MOVWF T2
TIMELOOP2
 CALL TIME04
 DECFSZ T2,F
 GOTO  TIMELOOP2
 RETURN

; 1m
TIME1000
 MOVLW D'50'
 MOVWF T3
TIMELOOP3
 CALL TIME20
 DECFSZ T3,F
 GOTO  TIMELOOP3
 RETURN

 END

inserted by FC2 system