2018年02月03日 20:21:46 Afantor 阅读数:4705 标签: ESP8266 NodeMCU 更多
所属专栏: ESP8266入门到实战开发
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.youkuaiyun.com/solar_Lan/article/details/79249153
注:对于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引脚
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主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;
}
从站输出窗口
该输出在从主设备发送的从设备上接收。