1. 程式人生 > >WiFi-ESP8266入門開發(十三)-使用SPI

WiFi-ESP8266入門開發(十三)-使用SPI

注:對於ESP8266開源技術感興趣的可以加群,我們一起探索交流學習,群號:579932824。群名:ESP8266開源技術交流群。

介紹

序列外設介面(SPI)是摩托羅拉公司最初啟動的匯流排介面連線協議。

  • SPI介面使用四根線進行通訊。因此也被稱為四線序列通訊協議。
  • SPI是全雙工主從通訊協議。這意味著只有一個主站和一個從站可以同時在介面總線上進行通訊。
  • SPI使能的器件工作在SPI操作的兩種基本模式下,即SPI主模式和SPI從模式。
  • 主裝置負責啟動通訊。主器件為同步資料傳輸生成序列時鐘。主裝置可以通過逐個選擇匯流排來處理總線上的多個從裝置。

基於NodeMCU的ESP8266具有硬體SPI,具有4個可用於SPI通訊的引腳。通過這個SPI介面,我們可以將任何支援SPI的器件與NodeMCU連線起來,並與其進行通訊。

ESP8266的SPI接腳(SD1,CMD,SD0,CLK)專門用於與ESP-12E的flash進行Quad-SPI通訊,因此不能用於SPI應用。我們可以將硬體SPI介面用於使用者端應用程式。

下圖顯示了內部用於flash的四路SPI介面引腳。它包括具有同步時鐘(SDIO_CLK)和片選引腳(SDIO_CMD)的四路I / O(4位資料匯流排),即四路(SDIO_DATA0- SDIO_DATA3)雙向(I / P和O / P)資料訊號。它主要用於獲得比雙I / O(2位資料匯流排)介面更多的頻寬/吞吐量。

NodeMCU SPI引腳

NodeMCU SPI引腳

NodeMCU SPI引腳

MISO(Master In Slave Out

                    主機接收資料,從機通過該引腳傳輸資料。

MOSI(Master Out Slave In

                    主機發送資料,從機通過該引腳接收資料。

SCLK(序列時鐘)

                    主機為從機使用的通訊生成此時鐘。

                    只有主人可以啟動序列時鐘。

CS(片選)

                    主機可以通過該引腳選擇從機,開始與其通訊。

我們來為NodeMCU編寫SPI通訊的Arduino草圖。這裡NodeMCU是主裝置,我們使用Arduino作為從裝置。

在這個例子中,我們傳送“Hello Slave”字串作為從NodeMCU主裝置的字串結尾“\ n”。從屬裝置接收到該字串並將其列印在序列監視器上。

NodeMCU Arduino SPI介面圖

NodeMCU Arduino SPI介面圖

NodeMCU主SPI的Arduino程式

#include<SPI.h>

char buff[]="Hello Slave\n";

void setup() {
 Serial.begin(9600); /* begin serial with 9600 baud */
 SPI.begin();  /* begin SPI */
}

void loop() {
 for(inti=0; i<sizeof buff; i++)  /* transfer buff data per second */
  SPI.transfer(buff[i]);
 delay(1000);  
}

Arduino Uno 從機 SPI的Arduino程式

#include <SPI.h>

char buff [100];
volatile byte index;
volatile bool receivedone;  /* use reception complete flag */

void setup (void)
{
  Serial.begin (9600);
  SPCR |= bit(SPE);         /* Enable SPI */
  pinMode(MISO, OUTPUT);    /* Make MISO pin as OUTPUT */
  index = 0;
  receivedone = false;
  SPI.attachInterrupt();    /* Attach SPI interrupt */
}

void loop (void)
{
  if (receivedone)          /* Check and print received buffer if any */
  {
    buff[index] = 0;
    Serial.println(buff);
    index = 0;
    receivedone = false;
  }
}

// SPI interrupt routine
ISR (SPI_STC_vect)
{
  uint8_t oldsrg = SREG;
  cli();
  char c = SPDR;
  if (index <sizeof buff)
  {
    buff [index++] = c;
    if (c == '\n'){     /* Check for newline character as end of msg */
     receivedone = true;
    }
  }
  SREG = oldsrg;
}

從站輸出視窗

該輸出在從主裝置傳送的從裝置上接收。

SPI從器件Arduino輸出視窗