- 什么是SPI?
- SPI的工作
- Arduino UNO中的SPI引脚
- 在Arduino中使用SPI
- Arduino SPI通信所需的组件
- Arduino SPI通信电路图
- 如何对Arduino进行SPI通信编程:
- Arduino SPI Master编程说明
- Arduino SPI从站编程说明
- SPI如何在Arduino上工作?-测试一下!
单片机使用许多不同的协议与各种传感器和模块进行通信。无线和有线通信有许多不同类型的通信协议,最常用的通信技术是串行通信。串行通信是通过通信通道或总线顺序一次发送一位数据的过程。串行通信有很多类型,例如UART,CAN,USB,I2C和SPI通信。
在本教程中,我们将了解 SPI协议以及如何在Arduino中使用它。我们将使用SPI协议在两个Arduino之间进行通信。在这里,一个Arduino将充当Master,另一个将充当Slave,两个LED和按钮将连接到两个Arduino。为了演示SPI通信,我们将使用SPI串行通信协议通过从设备侧的按钮控制主设备LED,反之亦然。
什么是SPI?
SPI(串行外围接口)是一种串行通信协议。SPI接口是由Motorola在1970年发现的。SPI具有全双工连接,这意味着可以同时发送和接收数据。即主机可以将数据发送到从机,而从机可以同时将数据发送到主机。SPI是同步串行通信,意味着通信需要时钟。
以前在其他微控制器中介绍了SPI通信:
- 与PIC单片机PIC16F877A的SPI通信
- 将3.5英寸触摸屏TFT LCD与Raspberry Pi连接
- 使用SPI引脚对AVR微控制器进行编程
- 将诺基亚5110图形LCD与Arduino接口
SPI的工作
SPI使用四条线进行主/从通信。一个SPI只能有一个主机,也可以有多个从机。主机通常是微控制器,而从机可以是微控制器,传感器,ADC,DAC,LCD等。
下面是具有单从机的SPI主站的框图表示。
SPI具有以下四行MISO,MOSI,SS和CLK
- MISO(主机输入从机输出) -从机线路,用于将数据发送到主机。
- MOSI(主输出从站输入) -用于将数据发送到外围设备的主线。
- SCK(串行时钟) -时钟脉冲,用于同步主机产生的数据传输。
- SS(从选择) –主站可以使用此引脚来启用和禁用特定设备。
具有多个从设备的SPI主设备
要开始主机与从机之间的通信,我们需要将所需设备的从机选择(SS)引脚设置为LOW,以便它可以与主机通信。高时,它将忽略主节点。这使您可以让多个SPI器件共享相同的主MISO,MOSI和CLK线。如上图所示,有四个从机,其中SCLK,MISO,MOSI共同连接到主机,每个从机的SS分别连接到主机的各个SS引脚(SS1,SS2,SS3)。通过将所需的SS引脚设置为低电平,主机可以与该从机通信。
Arduino UNO中的SPI引脚
下图显示了Arduino UNO上的SPI引脚(在红色框中)。
SPI线 |
固定在Arduino中 |
摩西 |
11或ICSP-4 |
味噌 |
12或ICSP-1 |
SCK |
13或ICSP-3 |
SS |
10 |
在Arduino中使用SPI
在开始为两个Arduino之间的SPI通信进行编程之前。我们需要了解Arduino IDE中使用的Arduino SPI库。
图书馆
1. SPI.begin()
使用:通过将SCK,MOSI和SS设置为输出,将SCK和MOSI拉低,将SS拉高来初始化SPI总线。
2. SPI.setClockDivider(除法器)
使用:相对于系统时钟设置SPI时钟分频器。可用的分频器为2、4、8、16、32、64或128。
分频器:
- SPI_CLOCK_DIV2
- SPI_CLOCK_DIV4
- SPI_CLOCK_DIV8
- SPI_CLOCK_DIV16
- SPI_CLOCK_DIV32
- SPI_CLOCK_DIV64
- SPI_CLOCK_DIV128
3. SPI.attachInterrupt(处理程序)
使用:当从属设备从主设备接收数据时,将调用此函数。
4. SPI.transfer(val )
使用:此功能用于同时在主机和从机之间发送和接收数据。
因此,现在让我们开始在Arduino中进行SPI协议的实际演示。在本教程中,我们将使用两个arduino,一个作为主节点,另一个作为从属节点。两个Arduino都分别附有LED和按钮。主LED可以通过使用从Arduino的按钮来控制,而从Arduino的LED可以通过主Arduino的按钮使用arduino中提供的SPI通信协议来控制。
Arduino SPI通信所需的组件
- Arduino UNO(2)
- LED灯(2)
- 按钮(2)
- 电阻10k(2)
- 电阻2.2k(2)
- 面包板
- 连接线
Arduino SPI通信电路图
下面的电路图显示了如何在Arduino UNO上使用SPI,但是您可以按照相同的步骤进行Arduino Mega SPI通信或Arduino nano SPI通信。除了引脚号,几乎所有内容都将保持不变。您必须检查Arduino nano或mega的引脚排列,才能找到Arduino nano SPI引脚和Arduino Mega引脚,完成后,其他所有操作都将相同。
我已经在面包板上构建了上面显示的电路,您可以在下面看到我用于测试的电路设置。
如何对Arduino进行SPI通信编程:
本教程有两个程序,一个用于主Arduino,另一个用于从Arduino。双方的完整计划都在项目结束时给出。
Arduino SPI Master编程说明
1.首先,我们需要包括用于使用SPI通信功能的SPI库。
#包括
2.在无效的setup()中
- 我们以波特率115200开始进行串行通信。
Serial.begin(115200);
- 将LED连接到引脚7,将按钮连接到引脚2,然后分别将这些引脚设置为OUTPUT和INPUT。
pinMode(ipbutton,INPUT); pinMode(LED,输出);
- 接下来我们开始SPI通信
SPI.begin();
- 接下来,我们将Clockdivider设置为SPI通信。在这里,我们设置了分频器8。
SPI.setClockDivider(SPI_CLOCK_DIV8);
- 然后将SS引脚设置为高电平,因为我们没有开始向从属arduino进行任何传输。
digitalWrite(SS,HIGH);
3.在void loop()中:
- 我们读取连接到pin2(主Arduino)的按钮引脚的状态,以将这些值发送到从Arduino。
buttonvalue = digitalRead(ipbutton);
- 设置逻辑以设置x值(发送至从机)取决于引脚2的输入
if(buttonvalue == HIGH) { x = 1; } else { x = 0; }
- 在发送该值之前,我们需要将从机选择值设为LOW,以开始从主机到从机的传输。
digitalWrite(SS,LOW);
- 重要的步骤到了,在下面的语句中,我们将存储在 Mastersend 变量中的按钮值发送到从属端arduino,并从从属端接收将存储在 Mastereceive 变量中的值。
Mastereceive = SPI.transfer(Mastersend);
- 之后,根据 Mastereceive 值,我们将打开或关闭Master Arduino LED。
if(Mastereceive == 1) { digitalWrite(LED,HIGH); //将引脚7设置为HIGH Serial.println(“ Master LED ON”); } else { digitalWrite(LED,LOW); //将引脚7设置为LOW Serial.println(“ Master LED OFF”); }
注意:我们使用 serial.println() 在Arduino IDE的Serial Motor中查看结果。最后检查视频。
Arduino SPI从站编程说明
1.首先,我们需要包括用于使用SPI通信功能的SPI库。
#包括
2.在无效的setup()中
- 我们以波特率115200开始进行串行通信。
Serial.begin(115200);
- 将LED连接到引脚7,将按钮连接到引脚2,然后分别将这些引脚设置为OUTPUT和INPUT。
pinMode(ipbutton,INPUT); pinMode(LED,输出);
- 重要的步骤如下
pinMode(MISO,OUTPUT);
上面的语句将MISO设置为OUTPUT(必须将数据发送到Master IN)。因此数据是通过Slave Arduino的MISO发送的。
- 现在通过使用SPI控制寄存器以从机模式打开SPI
SPCR-= _BV(SPE);
- 然后打开中断以进行SPI通信。如果从主机接收到数据,则调用中断例程,并从SPDR(SPI数据寄存器)获取接收到的值
SPI.attachInterrupt();
- 来自master的值取自SPDR,并存储在 Slavereceived 变量中。这发生在以下中断例程功能中。
ISR(SPI_STC_vect) {从机 接收= SPDR; 收到=真; }
3.接下来在空循环()中,根据从设备接收到的值将从设备Arduino LED设置为打开或关闭。
如果(Slavereceived == 1) { digitalWrite(LEDpin,HIGH); //将引脚7设置为HIGH LED ON Serial.println(“ Slave LED ON”); } else { digitalWrite(LEDpin,LOW); //将引脚7设置为LOW LED OFF Serial.println(“ Slave LED OFF”); }
- 接下来,我们读取Slave Arduino Push按钮的状态,并将值存储在 Slavesend中, 通过将值 赋给 SPDR寄存器将其发送给Arduino Master。
buttonvalue = digitalRead(buttonpin); 如果(buttonvalue == HIGH){x = 1; } else {x = 0; } Slavesend = x; SPDR =从机发送;
注意:我们使用 serial.println() 在Arduino IDE的Serial Motor中查看结果。最后检查视频。
SPI如何在Arduino上工作?-测试一下!
下面是两个Arduino板之间SPI通信的最终设置图。
按下主机侧的按钮时,从机侧的白色LED点亮。
按下从站侧的按钮后,主站侧的红色LED点亮。
您可以查看下面的视频,以查看Arduino SPI通信的演示。如果您有任何疑问,请在我们使用我们的论坛的评论部分中保留。