歩き遍路 平成19年春(J1) 記録の準備
SPIでUSB( 1)
 SPIでPIC18F4520と拡張I/O MCP23S08を接続

 LSIの高速化と少Pin化でシリアル転送方式のデバイスが多くなってきました。私もシリアル転送方式のLSIを使う機会が増えてきましたのでシリアル転送方式の一種である「SPI」の勉強をしました。
 SPIマスタはPIC18F4520のMSSPを「Workshop Nak」から購入した基板に実装しました。SPIスレーブはマクシム社の拡張I/O MCP23S08を汎用基板に実装しました。SPIマスタのプログラムは「C18」を使いました。

●実験のハード構成



ハードの構成を示します。

・上:デバッガ










・中:SPIマスタでPIC18F4520を
「Workshop Nak」から購入した基板に実装。
 「C18」でプログラム。









・下:SPIスレーブでマクシム社の
拡張I/O MCP23S08を汎用基板に実装。













●拡張I/O MCP23S08はどんな石、どんな使い方をしているの

 MCP23S08は、8ビット双方向のポートでSPIでSPIマスタに接続します。8ビット双方向のポートは、ビット単位に入力か出力かを設定、プルアップ、極性設定、割込み設定ができます。

 ここでは、上4ビットは入力に設定してスイッチの状態を読込みます。下4ビットは出力でLEDを駆動します。

●SPIマスタのハードウエア

 




SPIマスタのハードウエアと回路です。

両面基なのでコンパクトできました。

基板の添付説明書の回路図に未実装部をXしています。

























●SPIスレーブのハードウエア



SPIスレーブのハードウエアと回路です。

MCP23S08の8つの入出力PinにLED,押しボタンスイッチ、オルタネートスイッチを実装しました。

LED駆動時はスイッチはオープンにします。



























●SPIマスタのプログラム

 SPIマスタのプログラムを次に示します。
 プログラムの動きは、 PIC18F4520に接続してある4個のスイッチを読み取りSPIでMCP23S08に送りLEDを制御します。
 次に、MCP23S08に接続してある4個のスイッチをSPIで読み取り、PIC18F4520に接続してある4個のLEDを制御します。
 
 PIC18F4520のMSSP初期設定は、OpenSPI(SPI_FOSC_16, MODE_00, SMPMID); の一行で出来ました。楽ですね。
 初期設定の内容は、Spiマスター、モード00 クロック:1.25Mbps データサンプルは中央 としました。


/**************************************************************
*
* PIC18FのMSSPを使ってMCP23S08とSPI接続
*
* PIC18F接続のSWでMCP23S08接続のLEDを制御
* MCP23S08接続のSWでPIC18F接続のLEDを制御
*
***************************************************************

/** I N C L U D E S *******************************************/
#include <p18cxxx.h>
#include <spi.h>
#include "delays.h"

/*** コンフィギュレーションの設定 *******/
#pragma config OSC=HS, /*FSCM=OFF, */ IESO=OFF, PWRT=ON
#pragma config BOREN=ON, /*BORV=45,*/ WDT=ON, WDTPS=1024
#pragma config MCLRE=ON, PBADEN=OFF //, CCP2MX=RC1
#pragma config STVREN=ON, LVP=ON, DEBUG=ON
#pragma config CP0=OFF, CP1=OFF, CP2=OFF, CP3=OFF, CPB=OFF
#pragma config CPD=OFF, WRT0=OFF, WRT1=OFF, WRT2=OFF, WRT3=OFF
#pragma config WRTB=OFF, WRTC=OFF, WRTD=OFF, EBTR0=OFF
#pragma config EBTR1=OFF, EBTR2=OFF, EBTR3=OFF, EBTRB=OFF


// ********************
// ***** SPI送受信関数 SSピン制御無し
char SpiTxRx(char data){
char Temp;
//??? LATAbits.LATA5 = 0; //SSピンLow
SSPBUF = data; //送信開始

Temp = SSPSTAT; //ステータスReg読出し
while(!(SSPSTAT & 0x01)){ //送信完了待ち
Temp = SSPSTAT; //ステータスReg読出し
}

data = SSPBUF; //受信データ読み出し
//??? LATAbits.LATA5 = 1; //SSピンHigh
return(data); //受信データ戻り
}
// ********************
// ***** メイン
void main(void)
{
char tempData;
char tempData2;
char tempData3;

//ポートデータ設定
LATA = 0xFF; // データ
LATB = 0xFF; // データ
LATC = 0xFF; // データ
LATD = 0xFF; // データ
LATE = 0xFF; // データ

//ポート方向設定 TRISx 1 = IN,0 = OUT
TRISA = 0xDF; // bit5はSpiのSS
TRISB = 0xFF; // SW入力
TRISC = 0xFC; // bit1,0はLED
TRISD = 0xFE; // bit0はLED
TRISE = 0xFB; // bit2はLED

//*** MSSP初期設定 Spiマスター、モード00 クロック:1.25Mbps データサンプル:中央
OpenSPI(SPI_FOSC_16, MODE_00, SMPMID);

//*** MCP23S08の方向Reg設定 Bit7-4:Input,3-0:Output
LATAbits.LATA5 = 0; //SSピンLow
SpiTxRx(0x40); //SPI送受信 Writeオペコード
SpiTxRx(0x00); //SPI送受信 方向RegAdrs
SpiTxRx(0xF0); //SPI送受信 Bit7-4:Input,3-0:Output
LATAbits.LATA5 = 1; //SSピンHigh
Delay10TCYx(10);

/// メインループ
while(1)
{
/// スイッチを読込みPSI通信でデバイスに送信
tempData= PORTB; // スイッチ状態を読込み
LATAbits.LATA5 = 0; //SSピンLow
SpiTxRx(0x40); //SPI送受信 オペコード
SpiTxRx(0x0A); //SPI送受信 ラッチRegAdrs
SpiTxRx(tempData); //SPI送受信 スイッチData
LATAbits.LATA5 = 1; //SSピンHigh
Delay10TCYx(10);

/// デバイスからPSI通信でスイッチを受信して、LEDに表示
LATAbits.LATA5 = 0; //SSピンLow
SpiTxRx(0x41); //SPI送受信 オペコード
SpiTxRx(0x09); //SPI送受信 GPIORegAdrs
tempData2 = SpiTxRx(tempData); //SPI送受信 スイッチData
LATAbits.LATA5 = 1; //SSピンHigh

tempData = LATE & ~0x04; //LED3のセット準備 PORTE bit2
tempData3 = (tempData2 & 0x80)?0x04:0; //LED3の抽出
PORTE = tempData3 | tempData; //LED3のセット PORTE bit2

tempData = LATD & ~0x01; //LED2のセット準備 PORTD bit0
tempData3 = (tempData2 & 0x40)?0x01:0; //LED2の抽出
PORTD = tempData3 | tempData; //LED2のセット PORTD bit0

tempData = LATC & ~0x03; //LED1,0のセット準備 PORTC bit1,0
tempData3 = (tempData2>>4) & 0x03; //LED1,0の抽出
PORTC = tempData3 | tempData; //LED1のセット PORTC bit0

Delay10TCYx(10);


}//END of while(1)
}//END of main



●プログラムの実行と結果



SPIスレーブ側の波形です。


・上:クロック(SCK)
・下:セレクト(CS)

セレクトのLow期間40uSの間にクロックの3群が入っています。先頭がオペコード,中間がレジスタアドレス、最後がデータを転送しています。








SPIスレーブ側の波形です。


・上:クロック(SCK)
・下:入力データ(SI)

800nS周期のクロックが8個が群になっています。
データはクロックの立ち上がりでサンプルします。








 問題無くスイッチを操作するとLEDは動きました。周期が速いのでLEDの動きは素早いです。


ホームへ戻る