PSoCでSPI通信してみた

ども、Ramencozoです(´ω`)
ひさびさのひさびさです。

こないだまでPSoC2個使ってI2C(クロック線1本、双方向データ線1本、GND線1本の低速なデバイス間通信方式)でどうにかデータやりとりできないかなーとヤッてたんですが、どうにもよくわかんなくてぐぬぬ(´ω`)

でもってデバイス間通信に他の手法ないかなと探ったところ、SPIなる通信方式があるらしいので使ってみることに。

PSoCにモジュールがあったので、今度こそラクにイケてくれと思いつつ。

PSoC Designerの各種情報を下図に示します。まずはマスタから。
グローバルリソース

ChipEditor

ポート設定

各種ユーザーモジュールの設定

次にスレーブ側です。グローバルリソースとUART・PWM8は一緒なので上記にて御覧ください。
ChipEditor

Pinout

SPIスレーブの設定

ボード外観。某卒研で使ってるボードまんまです。

2011/10/27 追記:
ソースコード載せ忘れてたので記しますね


SPI Master / main.c

//----------------------------------------------------------------------------
// C main line
//----------------------------------------------------------------------------

#include // part specific constants and macros
#include "PSoCAPI.h" // PSoC API definitions for all User Modules

#define BUF_SIZE 8

void init(void);

BYTE buf_tx[BUF_SIZE];
BYTE buf_rx[BUF_SIZE];

void main(void)
{
unsigned char *str;
unsigned char j = 0;

init();

UART_1_CPutString("SPI Master Started...");
UART_1_PutCRLF();

while(1){
if(UART_1_bCmdCheck()){
UART_1_CPutString("Send:");
while(str = UART_1_szGetParam()){
UART_1_PutString(str);
UART_1_CPutString(",");
buf_tx[j] = *str;
if(j < BUF_SIZE - 1){
j++;
}
}
UART_1_PutCRLF();
j = 0;

while(!(SPIM_1_bReadStatus() & SPIM_1_SPIM_TX_BUFFER_EMPTY));
SPIM_1_SendTxData(buf_tx[0]);

while (!(SPIM_1_bReadStatus() & SPIM_1_SPIM_RX_BUFFER_FULL));
UART_1_CPutString("Received:");
UART_1_PutSHexByte(SPIM_1_bReadRxData());
UART_1_PutCRLF();

UART_1_CmdReset();
}
}
}

void init(void){
PWM8_1_DisableInt();
PWM8_1_Start();

UART_1_CmdReset();
UART_1_IntCntl(UART_1_ENABLE_RX_INT);
UART_1_Start(UART_1_PARITY_NONE);

SPIM_1_Start(SPIM_1_SPIM_MODE_0 | SPIM_1_SPIM_MSB_FIRST);
SPIM_1_EnableInt();

M8C_EnableGInt;
}

SPI Slave / main.c

//----------------------------------------------------------------------------
// C main line
//----------------------------------------------------------------------------

#include // part specific constants and macros
#include "PSoCAPI.h" // PSoC API definitions for all User Modules

#define BUF_SIZE 8

void init(void);

BYTE buf_tx[BUF_SIZE];
BYTE buf_rx[BUF_SIZE];

BYTE count = 0;

BOOL intFlag = FALSE;
BOOL initFlag = FALSE;

#pragma interrupt_handler SPIS_1_INT
void SPIS_1_INT(void){
unsigned char i;

UART_1_CPutString("Receive Interrupt happenned.");
UART_1_PutCRLF();

if(intFlag){
buf_rx[count] = SPIS_1_bReadRxData();
if(count < BUF_SIZE - 1){
count++;
}else{
count = 0;
}
UART_1_CPutString("Received:");
for(i=0; i

でもって実際に動作させてみました。双方電源ON→スレーブから一回送信(なんか起動後一回だけ割込みが効かなくて…)→マスタから文字いくつか送信、といった感じに。TeraTermでこんな感じのログが得られました。(図中の色付けは後からやりました)
[f:id:ramencozo:20111024174740p:image]

一応データのやりとりはイケてるみたいです。起動後の1回目の通信だけはなぜかスレーブからデータ送らないとマスタのデータ受け付けませんが…
(この記事書いてる間にボード上でプルアップされてるのを見つけたのでもしかしたらソレかもしれないです)

ひとまずこんな感じで(´ω`)ノではまたー