2015年11月7日土曜日

ArduinoでSPIの双方向通信をしてみた

SPI(Serial Peripheral Interface)で通信したいよ~♪
って言われたので作ってみた。

はじめは何故Slaveから送信できないのか分からなかったけど、
CSがアサート状態だと送信レジスタに書けないのね。

だからMasterがちゃんとSlaveを気遣ってやらないとダメなんだ。
つまり、奴隷に働いてもらいたかったら、いいご主人様にならないといけない
ってことね♪

/* * SPI Master * UARTから1Byte受け取ってSPIで送信する * SPIから1Byte受け取ってUARTにHEXを送る * (注)Master側がCSをDisableにしてあげないとSlaveは送信レジスタにデータを書けないよ * * CS - to digital pin 10 (SS pin) * SDI - to digital pin 11 (MOSI pin) * CLK - to digital pin 13 (SCK pin) */ #include <SPI.h> #define ouSpiSS 10 //SPI Select void setup() { //UARTを設定するよ Serial.begin (115200); Serial.println("SPI Master"); //SPIをMasterに設定するよ pinMode (ouSpiSS, OUTPUT); //SPI Select SPI.setBitOrder(MSBFIRST); //LSBFIRST / MSBFIRST SPI.setClockDivider(SPI_CLOCK_DIV128); //取り敢えずは最遅で設定するよ SPI.setDataMode(SPI_MODE0 ); //アイドル時SCKはLow 立ち上がりでラッチ SPI.begin(); //SPIをEnableにするよ } void loop(){ char cc; char re; cc = Serial.read(); //UARTから1byte受信 if(cc != -1){//受信データあり? //SPIに1Byte送信するよ digitalWrite(ouSpiSS, LOW); //SPI Select SPI.transfer(cc); //SPIに1Byte送信 digitalWrite(ouSpiSS, HIGH); //Slaveが返せるようにしてあげる delayMicroseconds(100); //Slaveが返す準備ができるまでちょっと待つ //SPIから1Byte受信するよ digitalWrite(ouSpiSS, LOW); //SPI Select re = SPI.transfer(0); //ダミー送信しながら受信するよ digitalWrite(ouSpiSS, HIGH); //SPI Select解除 Serial.println(re,HEX); //受信データをUARTにHEXで送信 } } /* * SPI Slave * Masterからの小文字を大文字に大文字を小文字に変換して返す * (注)Master側がCSをDisableにしてくれないとSlaveが送信レジスタにデータを書けないよ * * CS - to digital pin 10 (SS pin) * SDI - to digital pin 11 (MOSI pin) * CLK - to digital pin 13 (SCK pin) */ #include <SPI.h> void setup (void) { //SPIをSlaveに設定するよ pinMode(MISO, OUTPUT); //送信ポートを出力にする SPI.setBitOrder(MSBFIRST); //LSBFIRST / MSBFIRST SPI.setDataMode(SPI_MODE0 ); //立ち上がりでラッチ SPCR |= _BV(SPE); //SPI Enable SPI.attachInterrupt(); //SPI割り込み開始 } // SPI割り込み処理 ISR (SPI_STC_vect) { byte cc = SPDR; //SPIの受信バッファから取得 if(isupper(cc)){//大文字? SPDR = tolower(cc); //小文字に変換して送信バッファに書き込むよ } else{//大文字以外? SPDR = toupper(cc); //大文字に変換して送信バッファに書き込むよ } } //メインループは何もしてないよ void loop (void) { }

0 件のコメント: