Arduino - 外围串口

Arduino - 外围串口 首页 / Arduino入门教程 / Arduino - 外围串口

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

Board SPI Pins

SPI使用以下四线-

链接:https://www.learnfk.comhttps://www.learnfk.com/arduino/arduino-serial-peripheral-interface.html

来源:LearnFk无涯教程网

  • 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; //将按钮重置为零
   }
}

祝学习愉快!(内容编辑有误?请选中要编辑内容 -> 右键 -> 修改 -> 提交!)

技术教程推荐

白话法律42讲 -〔周甲徳〕

Nginx核心知识150讲 -〔陶辉〕

分布式协议与算法实战 -〔韩健〕

跟月影学可视化 -〔月影〕

技术管理案例课 -〔许健〕

代码之丑 -〔郑晔〕

深入剖析Java新特性 -〔范学雷〕

李智慧 · 高并发架构实战课 -〔李智慧〕

结构会议力 -〔李忠秋〕

好记忆不如烂笔头。留下您的足迹吧 :)