ホームに戻る
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