2022年8月23日 星期二

NodeMCU SPI 與 Arduino IDE

 

介紹

串行外設接口 (SPI) 是一種總線接口連接協議,最初由摩托羅拉公司發起。

  • SPI 接口使用四根線進行通信。因此它也被稱為四線串行通信協議。
  • SPI是一種全雙工主從通信協議。這意味著只有一個主設備和一個從設備可以同時在接口總線上進行通信。
  • SPI 使設備能夠在兩種基本的 SPI 操作模式下工作,即 SPI 主模式和 SPI 從模式。
  • 主設備負責啟動通信。主設備生成用於同步數據傳輸的串行時鐘。Master Device 可以通過一一選擇來處理總線上的多個從設備。

基於 NodeMCU 的 ESP8266 具有硬件 SPI,帶有四個可用於 SPI 通信的引腳。通過這個 SPI 接口,我們可以將任何支持 SPI 的設備與 NodeMCU 連接,並使其通信成為可能。

ESP8266 的 SPI 引腳(SD1、CMD、SD0、CLK)專門用於與 ESP-12E 上的閃存進行 Quad-SPI 通信,因此它們不能用於 SPI 應用。我們可以將硬件 SPI 接口用於用戶端應用程序。

下圖顯示了內部用於閃存的 Quad SPI 接口引腳。它由四路 i/o(4 位數據總線)組成,即四個 (SDIO_DATA0 – SDIO_DATA3) 雙向(i/p 和 o/p)數據信號,具有同步時鐘 (SDIO_CLK) 和芯片選擇引腳 (SDIO_CMD)。它主要用於獲得比雙 i/o(2 位數據總線)接口更多的帶寬/吞吐量。

NodeMCU SPI 引腳

NodeMCU SPI 引腳

NodeMCU SPI 引腳

 

MISO(主進從出)

                    主機通過該引腳接收數據,從機發送數據。

MOSI(主出從入)

                    主機通過該引腳發送數據,從機接收數據。

SCLK(串行時鐘)

                    主站為通信生成這個時鐘,供從站使用。

                    只有主機可以啟動串行時鐘。

CS(片選)

                    Master 可以通過該引腳選擇從設備開始與其通信。

 

例子

讓我們為 NodeMCU 編寫一個 SPI 通信的 Arduino 草圖。這裡 NodeMCU 充當主設備,我們使用 Arduino UNO 作為從設備。

在此示例中,我們從 NodeMCU 主設備發送帶有“\n”作為字符串結尾的“Hello Slave”字符串。從設備接收此字符串並將其打印在串行監視器上。

NodeMCU 與 Arduino 的通信

NodeMCU Arduino SPI接口圖

 

NodeMCU Master 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 Sketch

#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 Slave Arduino 輸出窗口


資料來源:https://www.electronicwings.com/nodemcu/nodemcu-spi-with-arduino-ide

沒有留言: