1. SPI介绍

SPI(Serial Peripheral Interface)总线是主要应用于嵌入式系统内部通信的串行同步传输总线协议。通常为四线制的SPI总线支持全双工通信。SPI最初由Motorola在2000年提出,Motorola所定义的SPI标准为业界广泛引用,但不同半导体公司的实施细节可能有所不同,这些区别体现在寄存器设置、信号定义、数据格式等。业界没有统一的SPI标准,具体应用需要参考特定器件手册。

SPI协议特点包括主从模式、全双工通信、片选功能、模式错误标识及CPU中断、缓冲数据寄存器和可配置时钟相位极性等。SPI允许数据一位一位的传送,甚至允许暂停,因为SCK时钟线由主控设备控制,当没有时钟跳变时,从设备不采集或传送数据。也就是说,主设备通过对SCK时钟线的控制可以完成对通讯的控制。

2. SPI的应用

SPI以其简单高效应用于绝大多数SoC系统上,这些SoC通常同时支持作为主模式或从模式(二选一)。

FPGAs和其它专用芯片也广泛使用SPI传输数据。比如:

  • 传感器:温度、压力传感器等
  • 控制设备:音频编解码器等
  • 通信设备:USB、以太网设备等
  • 存储器:Flash、EEPROM等
  • RTC时钟
  • LCD设备
  • MMC和SD卡

在高性能系统中,FPGAs通常使用SPI连接主从设备,比如连接外部传感器,和应用SPI加载配置。相比于JTAG,SPI定位用于高速配置(初始化)板上设备;而JTAG的初衷是为控制设备以相对低的准确度扫描和检测板上IO,在严格要求的场合,JTAG协议支持改变时钟占空比以满足建立和保持时间的要求。因此,JTAG并不定位于高速数据传输的场合。

3. SPI的优点与缺点

优点:

  • 支持全双工通信
  • Push-Pull驱动性能相比Open Drain信号完整性更好,支持高速应用(100MHz以上)
  • 协议支持字长不限于8bits,可根据应用特点灵活选择消息字长
  • 硬件连接简单
    • 只需要四根信号线(部分应用可以缩减到三根)
    • 相比I2C和SMbus节省上拉电阻
    • 相比I2C和SMbus不需要仲裁机制
    • 从设备使用主设备时钟,节约时钟要求
    • 从设备无需地址寻址
    • 无需收发器

缺点:

  • 相比I2C两根线,SPI四根线更多
  • 没有寻址机制,只能靠设备片选(chip select)选择不同从设备
  • 没有数据流控制(但主设备可以通过延缓时钟边缘降低传输速度)
  • 没有从设备接收数据ACK,主设备对于发送成功与否不得而知
  • 典型应用只支持单主控
  • 没有定义数据校验机制
  • 没有统一的国际组织维护,变种多不利于不同厂商设备的互操作性(interoperability)
  • 相比于RS232、RS422、RS485和CAN,SPI传输距离短
  • 不支持热插拔
  • 中断操作只能通过额外的信号线,或类似USB 1.1 and 2.0的Periodic Polling实现

4. SPI的硬件连接

SPI总线定义两个及以上设备间的数据传输,提供时钟的设备为主设备(Master),接收时钟的设备为从设备(Slave)。下图为单个Master与单个Slave的SPI连接:

4.1 SPI引脚定义

SPI协议定义四根信号线,分别为:

  1. SCK : Serial Clock 串行时钟
  2. MOSI : Master Output, Slave Input 主发从收信号
  3. MISO : Master Input, Slave Output 主收从发信号
  4. SS : Slave Select 片选信号

其中MISO方向为从设备到主设备,其余三个信号均为主设备到从设备。

注意:

  • 对于主设备,如果设置SS作为从设备的片选信号(最常用的场合),则它就不能用于多设备应用的模式错误检测
  • SPI单个数据管脚支持双向模式。在双向模式下,主设备的MOSI,从设备的MISO作为双向IO。

4.2 单个Master对多个Slave

通过多个片选信号(SS)或菊花链方式(Daisy Chain Configuration),单个主设备可以同时控制多个不同从设备。

4.2.1 片选方式

每个从设备都需要单独的片选信号,主设备每次只能选择其中一个从设备进行通信。因为所有从设备的SCK、MOSI、MISO都是连在一起的,未被选中从设备的MISO要表现为高阻状态(Hi-Z)以避免数据传输错误。由于每个设备都需要单独的片选信号,如果需要的片选信号过多,可以使用译码器产生所有的片选信号。

4.2.2 菊花链方式

数据信号经过主从设备所有的移位寄存器构成闭环。数据通过主设备发送(绿色线)经过从设备返回(蓝色线)到主设备。在这种方式下,片选和时钟同时接到所有从设备,通常用于移位寄存器和LED驱动器。注意,菊花链方式的主设备需要发送足够长的数据以确保数据送达到所有从设备。切记主设备所发送的第一个数据需(移位)到达菊花链中最后一个从设备。

菊花链式连接常用于仅需主设备发送数据而不需要接收返回数据的场合,如LED驱动器。在这种应用下,主设备MISO可以不连。如果需要接收从设备的返回数据,则需要连接主设备的MISO形成闭环。同样地,切记要发送足够多的接收指令以确保数据(移位)送达主设备。

5. SPI的数据收发及工作模式

5.1 同步解决方案

SPI的工作方式略有不同。它是一个“同步”数据总线,这意味着它使用单独的数据线和“时钟”,使双方保持完美同步。时钟是一个振荡信号,告诉接收器确切地何时采样数据线上的位。这可能是时钟信号的上升沿(低到高)或下降沿(从高到低); 数据表将指定使用哪一个。当接收器检测到该边沿时,它将立即查看数据线以读取下一位(参见下图中的箭头)。由于时钟与数据一起发送,因此指定速度并不重要,尽管设备将具有可以运行的最高速度(我们将讨论选择合适的时钟边沿和速度)。

5.2 数据接收

你可能会觉得,这对于单向通信来说很简单,但是如何以相反的方向发送数据呢?事情变得稍微复杂一些。

在SPI中,只有一侧产生时钟信号(通常称为串行ClocK的CLK或SCK)。生成时钟的一侧称为“Master”,另一侧称为“Slave。总是只有一个主设备(基本上都是微控制器),但是可以有多个从设备。

当数据从Master发送到Slave时,它将在MOSI线上发送,用于“Master输出/Slave输入”。如果Slave需要将响应发送回Master,则Master将继续生成预先安排好了的时钟周期,Slave将数据放入MISO线进行传输,用于“Master输入/Slave输出”。

注意:

我们在上面的描述中说“预先安排好了”。由于Master始终生成时钟信号,因此必须事先知道Slave何时需要返回数据以及将返回多少数据。这与异步串行不同,异步串行是随时可以向任一方向发送随机数据量。在实际应用中,这不是问题,因为SPI通常用于与具有非常特定命令结构的传感器通信。例如,如果我们将“读取数据”命令从Master发送到Slave,那么我们肯定知道Slave会回应我们(根据芯片文档寄存器的操作可知)。

SPI是“全双工”(具有单独的发送和接收线),因此,在某些情况下,可以发送和接收数据在同一时间(例如,请求一个新的传感器读数的同时接收来自上一个传感器的数据)。

5.3 工作模式

SPI通信有4种不同的模式,不同的从设备可能在出厂是就是配置为某种模式,这是不能改变的;但我们的通信双方必须是工作在同一模式下,所以我们可以对我们的Master的SPI模式进行配置,通过CPOL(时钟极性)和CPHA(时钟相位)来控制我们主设备的通信模式,具体如下:

Mode0:CPOL=0,CPHA=0
Mode1:CPOL=0,CPHA=1
Mode2:CPOL=1,CPHA=0
Mode3:CPOL=1,CPHA=1

时钟极性CPOL是用来配置SCLK的电平出于哪种状态时是空闲态或者有效态,时钟相位CPHA 
是用来配置数据采样是在第几个边沿:
CPOL=0,表示当SCLK=0时处于空闲态,所以有效状态就是SCLK处于高电平时
CPOL=1,表示当SCLK=1时处于空闲态,所以有效状态就是SCLK处于低电平时
CPHA=0,表示数据采样是在第1个边沿,数据发送在第2个边沿
CPHA=1,表示数据采样是在第2个边沿,数据发送在第1个边沿

例如:
CPOL=0,CPHA=0:此时空闲态时,SCLK处于低电平,数据采样是在第1个边沿,也就是 
SCLK由低电平到高电平的跳变,所以数据采样是在上升沿,数据发送是在下降沿。

CPOL=0,CPHA=1:此时空闲态时,SCLK处于低电平,数据发送是在第1个边沿,也就是 
SCLK由低电平到高电平的跳变,所以数据采样是在下降沿,数据发送是在上升沿。

CPOL=1,CPHA=0:此时空闲态时,SCLK处于高电平,数据采集是在第1个边沿,也就是 
SCLK由高电平到低电平的跳变,所以数据采集是在下降沿,数据发送是在上升沿。

CPOL=1,CPHA=1:此时空闲态时,SCLK处于高电平,数据发送是在第1个边沿,也就是 
SCLK由高电平到低电平的跳变,所以数据采集是在上升沿,数据发送是在下降沿。

注意:

我们的主设备能够控制时钟,因为我们的SPI通信并不像UART或者IIC通信 那样有专门的通信周期,有专门的通信起始信号,有专门的通信结束信号;所以我们的 SPI协议能够通过控制时钟信号线,当没有数据交流的时候我们的时钟线要么是保持高电平要么是保持低电平。

下面是将SPI协议作为SPI主控位进行位操作的例子,CPOL = 0,CPHA = 0,每次传输8位。该示例使用C编程语言编写。因为这是CPOL = 0,所以必须在激活芯片选择之前将时钟拉低。必须激活芯片选择线,这通常意味着在传输开始之前为外设切换为低电平,然后在之后停用。选择线为低时,大多数外设允许或需要多次传输; 在取消选择芯片之前,可能会多次调用此例程。

/ *
*同时在SPI上发送和接收一个字节。
*
*假设极性和相位均为0,即:
*  - 在SCLK的上升沿捕获输入数据。
*  - 输出数据在SCLK的下降沿传播。
*
*返回接收的字节。
* /
uint8_t SPI_transfer_byte(uint8_t byte_out)
{uint8_t byte_in = 0;uint8_t bit;for (bit = 0x80; bit; bit >>= 1) {/* Shift-out a bit to the MOSI line */write_MOSI((byte_out & bit) ? HIGH : LOW);/* Delay for at least the peer's setup time */delay(SPI_SCLK_LOW_TIME);/* Pull the clock line high */write_SCLK(HIGH);/* Shift-in a bit from the MISO line */if (read_MISO() == HIGH)byte_in |= bit;/* Delay for at least the peer's hold time */delay(SPI_SCLK_HIGH_TIME);/* Pull the clock line low */write_SCLK(LOW);}return byte_in;
}

读例子:

/*——————————————————————————
* 函 数 名:SPI_Read_Reg
* 输入参数:addr:    寄存器地址
* 输出参数:None
* 返 回 值:寄存器数据
* 功能说明:读计量参数 下降沿发送和读取数据, 先发送8位地址,再读取24位数据
*——————————————————————————*/
uint32_t SPI_Read_Reg(uint8_t addr)
{uint8_t        i;uint32_t  temp = 0;addr &= 0x7F;HIGH_CS();SPI_Delay();LOW_CS();SPI_Delay();SPI_Delay();SPI_Delay();LOW_CLK();//SPI_Delay();//LOW_CS();for (i=0; i<8; i++){SPI_Delay();HIGH_CLK();if (addr&0x80){HIGH_DIN();}else{LOW_DIN();}addr <<= 1;LOW_CLK();}SPI_Delay();SPI_Delay();SPI_Delay();SPI_Delay();SPI_Delay();SPI_Delay();for (i=0; i<24; i++){SPI_Delay();temp <<= 1;HIGH_CLK();SPI_Delay();if (PIN_DOUT){temp |= 0x01;}LOW_CLK();}SPI_Delay();HIGH_CS();SPI_Delay();HIGH_CLK();return (temp);
}

写例子:

/*——————————————————————————
* 函 数 名:SPI_Write_Reg
* 输入参数:addr:     寄存器地址
*           temp:       寄存器数据
* 输出参数:None
* 返 回 值:None
* 功能说明:写寄存器参数 下降沿发送 先发送8位地址数据,再发送24位数据位数据
*——————————————————————————*/
void SPI_Write_Reg(uint8_t addr, uint32_t temp)
{uint8_t    i;addr |= 0x80;HIGH_CS();SPI_Delay();LOW_CS();SPI_Delay();SPI_Delay();SPI_Delay();LOW_CS();for (i=0; i<8; i++){SPI_Delay();HIGH_CLK();if (addr&0x80){HIGH_DIN();}else{LOW_DIN();}addr <<= 1;LOW_CLK();}for (i=0; i<24; i++){SPI_Delay();HIGH_CLK();SPI_Delay();if (temp&0x800000){HIGH_DIN();}else{LOW_DIN();}temp <<= 1;LOW_CLK();}SPI_Delay();HIGH_CS();SPI_Delay();HIGH_CLK();
}

【硬件通信协议】1. IIC通信协议

参考链接:

http://www.wangdali.net/spi/

https://learn.sparkfun.com/tutorials/serial-peripheral-interface-spi

https://en.wikipedia.org/wiki/Serial_Peripheral_Interface

【硬件通信协议】2. 详细解析SPI通信协议(标准4线SPI)相关推荐

  1. 【软件通信协议】2. 详细解析UDP通信协议(附广播 组播)

    1. UDP协议简介 UDP是User Datagram Protocol的简称,全称是用户数据报协议,在网络中它与TCP协议一样用于处理数据包,是一种无连接的协议.在OSI模型中,在第四层--传输层 ...

  2. TLE5012B ESP32驱动程序、硬件电路设计、4线SPI通信,驱动完美兼容4线SPI不用改MOSI开漏推挽输出

    一.TLE5012B 简介 TLE5012B 是一种款高分辨率旋转位置传感器,用于在整个 360 度范围内进行角度测量. 它通过使用单片集成 巨磁阻 (iGMR) 元件,来测量正弦和余弦角分量,这些原 ...

  3. 嵌入式开发基础—SPI通信协议解析

    嵌入式开发基础-SPI通信协议解析 1 通信方式(主从通信) 1.1 什么是主从通信 1.2 主从通信如何实现 1.2.1 相关控制引脚介绍 1.2.2 如何通过控制引脚实现主从通信 2 通信数据交换 ...

  4. STM32 SPI通信协议详细讲解—小白入门

    文章目录 (一)SPI协议简介 (二)SPI物理层 (三)SPI协议层 3.1.SPI基本通信过程 3.2.通信的起始和终止信号 3.3.数据有效性 3.4.CPOL/CPHA及通信模式 (四)STM ...

  5. 【总线】SPI 通信协议

    目录 SPI总线协议概述 串行与并行通信 SPI通信介绍 SPI的工作原理 时钟 从属选择 多个从机 常规方法 菊花链方法 MOSI 和 MISO SPI 数据传输的步骤 SPI 的优缺点 优点 缺点 ...

  6. MPU6050开发 -- 进阶之I2C/SPI通信协议

    如需转载请注明出处:https://blog.csdn.net/qq_29350001/article/details/78611309 上一篇基本概念讲了一通,大体上对MPU6050有了一个了解.对 ...

  7. SPI接口通信协议详解:SPI时序、2线、3线、4线SPI及4种常用工作模式

    简介 SPI通信原理比I2C要简单,它主要是主从方式通信.这种模式通常只有一个主机和一个或者多个从机,标准的SPI是4根线,分别是SSEL(片选,也写作 SCS).SCLK(时钟,也写作SCK).MO ...

  8. 【嵌入式】STM32基于SPI通信协议OLED屏显示

    STM32基于SPI通信协议OLED屏显示 一.SPI协议和OLED介绍 1.SPI协议介绍 物理层 协议层 2.OLED显示屏介绍 二.显示个人学号姓名实验 1.题目要求 2.代码部分 1.完整代码 ...

  9. spi通信协议_arduino的SPI通信

    SPI通信简介 SPI全称Serial Peripheral Interface,即串行外设接口. 由Motorola公司提出的一种同步串行数据传输标准. 所谓同步,即数据收发双方共用一个时钟: 所谓 ...

  10. 基于STM32的0.96OLED基本显示学习,及 上下或左右的滑动显示长字符(使用硬件刷屏模式),OLED显示变量值操作详细解析

    基于STM32的0.96OLED基本显示学习,及 上下或左右的滑动显示长字符(使用硬件刷屏模式),OLED显示变量值操作详细解析 简   介 一.项目说明 二.学习入门 1)开始了解例程 三.实战过程 ...

最新文章

  1. 【Vegas原创】“無法解析 equal to 動作的定序衝突”错误的处理
  2. 前端学习(3019):vue+element今日头条管理--自定义格式化面板
  3. PaperNotes(17)-图卷积神经网络GCN-笔记
  4. 模块使用:time、datetime、calendar、sys、os、os.path、normcase和normapath、random、json、pickle...
  5. 怎么取消计算机的用户名和密码怎么设置密码,开机密码如何取消 电脑开机密码取消设置方法介绍...
  6. HDU2034 人见人爱A-B【水题】
  7. LSH︱python实现局部敏感哈希——LSHash(二)
  8. 读书笔记--精通CSS高级Web标准解决方案(一)---CSS基础
  9. 冲击波内幕点滴 (转)
  10. oracle查看表索引及索引类型
  11. 聚合物/硅胶色谱填粒径1.7μm到50μm
  12. python操作模拟器多开操作_窗口多开模拟器同步操作器▲按键精灵脚本▲
  13. android 设置默认铃声,我的Android进阶之旅------gt;Android系统设置默认来电铃声、闹钟铃声、通知铃声,android进阶...
  14. html 5与css 3权威指南 第2版 pdf,html5与css3权威指南
  15. mysql 5.6 64 位安装 缺少libai.so_CentOS6.7安装部署LNMP(nginx1.8.0+php5.6.10+mysql5.6.12) 法外狂徒...
  16. python求平均值_如何用python求平均值
  17. 小草酒店客房管理系统 免费
  18. 2022年值得关注的22项新兴技术
  19. linux下添加新用户,并赋予root权限
  20. 私信基本功能数据库设计

热门文章

  1. win7原版镜像_(超详细)WIN7原版系统win镜像安装教程
  2. linux中打zip命令,zip命令 - Linux命令大全 | linux教程
  3. catia 快捷键 激活零件_CATIA常用快捷键
  4. 关于主机的思维导图_【思维导图大咖分享干货】关于思维导图中插图的用法细解!!...
  5. 最新TP开源的淘宝客系统/推券客CMS系统+功能强大
  6. c语言文件读不同格式,c语言文件的读写格式
  7. c语言程序中文复制到word变乱码,怎么复制C程序代码到Word不会有乱码,不会有乱字等情况...
  8. lisp6 暖通cad_AutoCAD超强小工具(ARKtools)说明
  9. 【Axure原型】新闻资讯客户端APP原型 今日头条同类APP实战原型
  10. spring过滤器、拦截器