Arduino - 外围接口

首页 / Arduino / Serial Peripheral Interface

串行外围设备接口(SPI)总线是用于串行通信的系统,它最多使用四根导线,通常为三根,一根导线用于数据接收,一根导线用于数据发送,一根导线用于同步,另一根导线用于选择要与之通信的设备,这是全双工连接,这意味着将同时发送和接收数据,最大波特率高于I2C通信系统中的波特率。

Board SPI Pins

SPI使用以下四线-

  • 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时钟设置为系统时钟频率的四分之一(对于5Mhz,板以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传输基于同时发送和接收:接收到的数据在receiveVal中返回。

  • SPI.beginTransaction(SPISettings(speedMaximum,dataOrder,dataMode))    -  speedMaximum是时钟,dataOrder(MSBFIRST或LSBFIRST),dataMode(SPI_MODE0,SPI_MODE1,SPI_MODE2或SPI_MODE3)

我们在SPI中有以下四种操作模式-

  • Mode 0(默认)    -  时钟通常为低电平(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)    -   从设备从主机接收数据时调用的函数。

现在,我们将两个Arduino UNO板连接在一起,一个作为主设备,另一个作为从设备。

  • (SS)       : pin 10
  • (MOSI) : pin 11
  • (MISO) : pin 12
  • (SCK)   : pin 13

以下是两块板之间连接的示意图-

Connection of Boards

让我们看一下SPI作为主设备和SPI作为从设备的示例。

SPI as MASTER

#include <SPI.h>

void setup (void) {
   Serial.begin(115200); //将 usart 的波特率设置为 115200
   digitalWrite(SS, HIGH); //禁用从选择
   SPI.begin ();
   SPI.setClockDivider(SPI_CLOCK_DIV8);//将时钟除以 8
}

void loop (void) {
   char c;
   digitalWrite(SS, LOW); //启用从机选择
   //发送测试字符串
   for (const char * p="Hello, Learnfk!\r" ; c=*p; p++) {
      SPI.transfer (c);
      Serial.print(c);
   }
   digitalWrite(SS, HIGH); //禁用从选择
   delay(2000);
}

SPI as SLAVE

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

void setup (void) {
   Serial.begin (115200);
   pinMode(MISO, OUTPUT); //必须发送到主控,所以它设置为输出
   SPCR |= _BV(SPE); //在从模式下打开 SPI
   indx=0; //缓冲区空
   process=false;
   SPI.attachInterrupt(); //开启中断
}
ISR (SPI_STC_vect) //SPI中断程序
   byte c=SPDR; //从 SPI 数据寄存器读取字节
   if (indx < sizeof buff) {
      buff [indx++]=c; //将数据保存在数组缓冲区的下一个索引中
      if (c == '\r') //检查单词的结尾
      process=true;
   }
}

void loop (void) {
   if (process) {
      process=false; //重置进程
      Serial.println (buff); //在串行监视器上打印阵列
      indx= 0; //将按钮重置为零
   }
}

这一章《Arduino - 外围接口》你学到了什么?在下面做个笔记吧!做站不易,你的分享是对我们最大的支持,感谢!😊

相关文章

Service Mesh实践指南 -〔周晶 - 6讲〕

SRE实战手册 -〔赵成 - 13讲〕

用户体验设计实战课 -〔相辉 - 34讲〕

大厂晋升指南 -〔李运华 - 44讲〕

numpy ndarray 是同质的和矩形的(子数组必须是相同的长度),因为...

当值相同时如何组合字典的键?

如何将绘图复制到剪贴板进行粘贴?

在专注于输入时按 Enter 会导致同级按钮触发

如何根据 PHP 变量中的值显示 div

Java 流的总和为

视频推荐〔Arduino - 1-21 mc猜数字 - 3 while〕

更多视频 »
好记忆不如烂笔头。留下你的足迹吧 :)