Arduino-シリアルペリフェラルインターフェース

シリアルペリフェラルインターフェイス(SPI)バスは、シリアル通信用のシステムであり、最大4本の導体(通常は3本)を使用します。1つの導体はデータ受信、1つはデータ送信、1つは同期、もう1つは通信するデバイスの選択に使用されます。これは全二重接続です。つまり、データは同時に送受信されます。最大ボーレートは、I2C通信システムのボーレートよりも高くなっています。

ボードSPIピン

SPIは次の4本のワイヤーを使用します-

  • SCK −これはマスターによって駆動されるシリアルクロックです。

  • MOSI −これはマスターによって駆動されるマスター出力/スレーブ入力です。

  • MISO −これはマスターによって駆動されるマスター入力/スレーブ出力です。

  • SS −これはスレーブ選択ワイヤです。

以下の機能を使用します。SPI.hを含める必要があります。

  • SPI.begin() − SCK、MOSI、およびSSを出力に設定し、SCKおよびMOSIをローに、SSをハイに設定することにより、SPIバスを初期化します。

  • SPI.setClockDivider(divider)−システムクロックを基準にしてSPIクロック分周器を設定します。AVRベースのボードでは、使用可能な分周器は2、4、8、16、32、64、または128です。デフォルト設定はSPI_CLOCK_DIV4で、SPIクロックをシステムクロックの周波数の4分の1に設定します(5 Mhz 20 MHzのボード)。

  • Divider −(SPI_CLOCK_DIV2、SPI_CLOCK_DIV4、SPI_CLOCK_DIV8、SPI_CLOCK_DIV16、SPI_CLOCK_DIV32、SPI_CLOCK_DIV64、SPI_CLOCK_DIV128)である可能性があります。

  • SPI.transfer(val) − SPI転送は、同時送信と受信に基づいています。受信したデータは、receivedValで返されます。

  • SPI.beginTransaction(SPISettings(speedMaximum, dataOrder, dataMode)) − speedMaximumは、クロック、dataOrder(MSBFIRSTまたはLSBFIRST)、dataMode(SPI_MODE0、SPI_MODE1、SPI_MODE2、またはSPI_MODE3)です。

SPIには次の4つの動作モードがあります-

  • Mode 0 (the default) −クロックは通常ロー(CPOL = 0)であり、データはローからハイ(リーディングエッジ)への遷移時にサンプリングされます(CPHA = 0)。

  • Mode 1 −クロックは通常ロー(CPOL = 0)であり、データはハイからロー(トレーリングエッジ)への遷移時にサンプリングされます(CPHA = 1)。

  • Mode 2 −クロックは通常ハイ(CPOL = 1)であり、データはハイからロー(リーディングエッジ)への遷移時にサンプリングされます(CPHA = 0)。

  • Mode 3 −クロックは通常ハイ(CPOL = 1)であり、データはローからハイ(トレーリングエッジ)への遷移時にサンプリングされます(CPHA = 1)。

  • SPI.attachInterrupt(handler) −スレーブデバイスがマスターからデータを受信したときに呼び出される関数。

次に、2つのArduinoUNOボードを接続します。1つはマスターとして、もう1つはスレーブとして。

  • (SS):ピン10
  • (MOSI):ピン11
  • (味噌):ピン12
  • (SCK):ピン13

地面は一般的です。以下は、両方のボード間の接続の図式表現です。

マスターとしてのSPIとスレーブとしてのSPIの例を見てみましょう。

マスターとしてのSPI

#include <SPI.h>

void setup (void) {
   Serial.begin(115200); //set baud rate to 115200 for usart
   digitalWrite(SS, HIGH); // disable Slave Select
   SPI.begin ();
   SPI.setClockDivider(SPI_CLOCK_DIV8);//divide the clock by 8
}

void loop (void) {
   char c;
   digitalWrite(SS, LOW); // enable Slave Select
   // send test string
   for (const char * p = "Hello, world!\r" ; c = *p; p++) {
      SPI.transfer (c);
      Serial.print(c);
   }
   digitalWrite(SS, HIGH); // disable Slave Select
   delay(2000);
}

スレーブとしてのSPI

#include <SPI.h>
char buff [50];
volatile byte indx;
volatile boolean process;

void setup (void) {
   Serial.begin (115200);
   pinMode(MISO, OUTPUT); // have to send on master in so it set as output
   SPCR |= _BV(SPE); // turn on SPI in slave mode
   indx = 0; // buffer empty
   process = false;
   SPI.attachInterrupt(); // turn on interrupt
}
ISR (SPI_STC_vect) // SPI interrupt routine { 
   byte c = SPDR; // read byte from SPI Data Register
   if (indx < sizeof buff) {
      buff [indx++] = c; // save data in the next index in the array buff
      if (c == '\r') //check for the end of the word
      process = true;
   }
}

void loop (void) {
   if (process) {
      process = false; //reset the process
      Serial.println (buff); //print the array on serial monitor
      indx= 0; //reset button to zero
   }
}