## SPI - 同步、全双工的串行外设接口 SPI(Serial Peripheral Interface - 同步外设接口)总线是一种用于短距离通信(主要是嵌入式系统中)的同步串行通信接口规范,虽然没有正式的国际标准,但这种接口协议由Motorola发明迄今经过很多厂商的支持,已经成了一种事实标准,被广泛用于各种[[MCU]]处理器中,同传感器,串行[[ADC]]、[[DAC]]、存储器、SD卡以及LCD等进行数据连接。由于没有统一的国际标准,SPI出现了很多不同的协议选项,例如不同的Word大小;每个设备都有自己的协议定义,包括是否支持命令;有些设备只发送,其它的则只是接收;有的片选是高有效,有的则是低有效;有的协议先发送最低位。 {{ :spi_lpc.jpg |}} **当前的处理器中几乎都有[[SPI]]和[[I2C]]和[[UART]]接口** {{ :spi_sensor.jpg |}} 数字接口的传感器也采用[[SPI]]和[[I2C]] {{ :spi_fpga.jpg |}} [[FPGA]]也将[[SPI]]、[[I2C]]硬化在器件内部方便各种外设的连接 {{ :spi_msconnection.jpg |}} 主、从器件之间的连接及数据传输方式 多个SPI设备可以通过全双工的模式同单一的Master以主、从结构进行通信。主、设备发起读、写,多个从设备通过独立的片选信号(SS - Slave Select)被寻址。 {{ :300px-spi_three_slaves.svg.png |SPI总线:单主多从连接}} **SPI总线:单主多从连接** 有时SPI也被称为四线串行总线,主要是与3线、2线、1线串行总线进行区分,虽然SPI可以准确地描述为一个同步串行接口,但它与同步串行接口(SSI)协议还是不同的,SSI同样也是一种4线同步串行通信协议,但SSI采用的是差分信号,且只提供了一个简单的通信信道。 {{ :spi_640.gif |}} 动画1显示数据从器件A移出到器件B,从器件B移出到器件A. ### 1. SPI的技术实现 #### 1.1 接口信号 SPI总线定义了4个逻辑信号: * SCLK: 串行时钟(由主设备输出). * MOSI: 主输出、从输入(由主设备输出). * MISO: 主输入、从输出(由从设备输出). * SS: 从设备选中(低有效, 由主设备输出). SPI端口管脚的名字也有其它的叫法,不同的芯片公司叫法不同,比如: * 串行输出: SCLK : SCK, CLK. * 主输出 --> 从输入: MOSI : SIMO, SDI(对于“从”设备), DI, DIN, SI, MTST. * 主输入 <-- 从输出: --> MISO : SOMI, SDO (对于“从”设备), DO, DOUT, SO, MRSR. * 从选择: SS : nCS, CS, CSB, CSN, EN, nSS, STE, SYNC. {{ :spi_6402.gif |}} 动画2显示了通过一个虚拟的4通道示波器捕捉的两个器件之间SPI的转换 #### 1.2 工作模式 SPI总线可以工作在一个主设备/一个或多个从设备的模式。 如果只有一个从设备,SS管脚可以直接接地(从设备允许的话),有些从设备需要片选信号的下降沿来启动传输,一个例子就是[[http://www.maximintegrated.com|美信]]公司的串行ADC [[https://www.maximintegrated.com/en/products/analog/data-converters/analog-to-digital-converters/MAX1242.html|MAX1242]],通过一个高电平到低电平的转换标记传输的起始。如果有多个从设备,每个从设备需要一个独立的SS信号连接到主设备。 多数从设备的输出是三态的,当该从设备没有被选中的时候它们的MISO信号就为高阻(逻辑上断开连接)。不具有三态输出的器件是不能同其它器件共享SPI总线部分的,只能是一个从设备跟主设备相连。 {{ :spi_clocking.jpg |}} SPI的时钟采样 ##### 通过多个从片选信号(SSN)配置 在标准的SPI配置中,主设备可以通过使能相应的从设备,即通过将相应设备的从选择线(SSN或SS)设置为逻辑低电平,通过共享的公共数据线将数据写入各个从设备或由各个从设备中读取数据。 应注意不要同时使能多个从设备,因为返回到主设备的数据将在MISO线路之间的驱动器上产生竞争导致无法进行数据的判读。在某些应用中不需要将数据返回给主设备,在这种情况下,如果主设备想要将相同的数据发送到多个从设备,则可以同时寻址多个从设备。 {{ :spi_mms.jpg |}} 在多从设备选择配置中,每个从设备都需要来自主设备的唯一从设备选择线(SS、SSN或CSn)。如果主设备没有足够的I/O引脚用于所需数量的从设备,则使用解码/解复用器(例如74HC(T)238(3到8线)来实现I/O扩展)。 ##### 菊花链配置 在这种配置中,数据从一个设备移动到下一个设备, 最终的从设备可以将数据返回给主设备(给FPGA编程的JTAG在给多个器件编程的时候也常用这种方式)。 {{ :spi_daisy.jpg |}} 在菊花链配置中,所有从设备共享一条公共的从选择线(SS)。 数据从主设备传输到第一个从设备,然后从第一个从设备传输到第二个从设备,依此下去,数据沿着线路级联,直到系列中的最后一个从设备,最后的一个从设备使用其MISO线路将数据传送到主设备。 这种配置非常适合于主设备的信号引脚有限的场景。 #### 1.3 4种传输模式 每次数据传输都是先将SSN(有的器件命名为SS,从选择线)被驱动为逻辑低电平时开始。由时钟的极性(CPOL)和相位(CPHA)构成了4种不同的数据传输模式(0,1,2,3),分别对应四种可能的时钟配置。 * CPOL: 时钟的极性,它控制着时钟信号的初始逻辑状态。 * CPHA: 时钟相位,它控制了数据转换和时钟转换之间的关系。 {{ :400px-spi_timing_diagram2.svg.png|}} 具有非反相时钟极性(即,当从器件选择转换为逻辑低时,时钟处于逻辑低电平): * **模式0**:配置时钟相位使得数据在时钟脉冲的上升沿采样,并在时钟脉冲的下降沿移出。 这对应于上图中的第一个蓝色时钟轨迹。 请注意,数据必须在时钟的第一个上升沿之前可用。 * **模式1**:配置时钟相位使得数据在时钟脉冲的下降沿采样,并在时钟脉冲的上升沿移出。 这对应于上图中的第二个蓝色时钟轨迹。 使用反相时钟极性(即,当从器件选择转换为逻辑低时,时钟处于逻辑高电平): * **模式2**:配置时钟相位,使得数据在时钟脉冲的下降沿采样,并在时钟脉冲的上升沿移出。 这对应于上图中的第一个橙色时钟轨迹。 请注意,数据必须在时钟的第一个下降沿之前可用。 * **模式3**:配置时钟相位,使得数据在时钟脉冲的上升沿采样,并在时钟脉冲的下降沿移出。 这对应于上图中的第二个橙色时钟轨迹。 由于主设备一般为可以编程各种模式的控制器/处理器或者可以灵活编程的FPGA,因此在使用SPI连接的时候要认真阅读自己选用的从设备的工作模式,以便在时序上满足传输的要求。 #### 1.4 SPI数据传输的主设备端代码示例 以下是一段主设备工作于CPOL=0、CPHA=0模式时的数据传输的代码,每次传输为8位,此示例采用C语言。由于工作于CPOL=0, 在片选被选中之前要把时钟拉低,片选信号必须使能,也就是说在数据传输之前要将外设的片选信号电平变低,并在传输结束以后不再“使能”。 多数的外设允许或需要在片选信号选中以后进行多次传输,次子程序也许需要被多次调用。 /* * Simultaneously transmit and receive a byte on the SPI. * * Polarity and phase are assumed to be both 0, i.e.: * - input data is captured on rising edge of SCLK. * - output data is propagated on falling edge of SCLK. * * Returns the received byte. */ 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; } ### 2. SPI的优点和缺点 #### 2.1 优点 * 支持全双工通信 * 推挽驱动(跟漏极开路正相反)提供了比较好的信号完整性和较高的速度 * 比I²C或SMBus吞吐率更高 * 协议非常灵活支持“位”传输 * 不仅限于8-bit一个字节的传输 * 可任意选择的信息大小、内容、以及用途 * 异常简单的硬件接口: * 一般来讲比I²C或SMBus需要的功耗更低,因为需要更少的电路(包括上拉电阻) * 没有仲裁机制或相关的失效模式 * “从设备”采用的是“主设备”的时钟,不需要精确的晶振 * “从设备”不需要一个单独的地址 — 这点不像I²C或GPIB或SCSI * 不需要收/发器 * 在一个IC上只用了4个管脚, 板上走线和布局连接都比并行接口简单很多 * 每个设备最多只有一个单独的总线信号(片选);其它的都是共享的 * 信号都是单方向的,非常容易进行电流隔离 * 对于时钟的速度没有上限,有进一步提高速度的潜力 #### 2.2 缺点 * 相比于I²C总线需要更多的管脚, 即便是只用到3根线的情况下 * 没有寻址机制,在共享的总线连接时需要通过片选信号支持多个设备的访问 * 在**从设备**侧没有硬件流控机制(**主设备**一侧可以通过延迟到下一个时钟沿以降低传输的速率) * **从设备**无法进行硬件“应答”(主设备传送的信息无法确定传递到哪里,是否传递成功) * 一般只支持一个主设备(取决于设备的硬件构成) * 没有查错机制 * 没有一个正式的标准规范,无法验证一致性 * 相对于RS-232, RS-485, 或CAN-总线,只能近距离传输 * 存在很多的变种,很难能够找到开发工具(例如主适配卡)支持这所有的变种 * SPI不支持热交换(动态地增加一个节点). * 如果想使用“中断”,只有通过SPI信号以外的其它信号线,或者采用类似USB1.1或2.0中的周期性查询的欺骗方式 * 有一些变种比如多路I/O SPI和下面定义的三线串行总线都是半双工的 ### 3. SPI的主要应用 与并行I/O总线相比,SPI能够大大节省电路板的空间,因此在嵌入式系统中发挥了重要作用,对于大多数片上系统处理器而言都是如此,这些处理器都具有较高端的32位处理器,例如使用ARM、MIPS或PowerPC的处理器以及其它微控制器,如AVR、PIC和MSP430等。 这些芯片通常包括能够以主模式或从模式运行的SPI控制器,也可以使用SPI接口对系统内可编程AVR控制器(包括空白控制器)进行编程。 基于芯片或FPGA的设计有时使用SPI在内部的组件之间进行通信,即便是片内,其面积的节省也像电路板上一样非常重要。 全双工功能使SPI非常简单、高效、适用于单主/单从机应用。 一些设备使用全双工模式为数字音频、数字信号处理或电信信道等应用实现高效、快速的数据流,但大多数现成的芯片都采用半双工请求/响应协议。 SPI被用来同各种外设通信,例如: * 传感器:温度、压力、ADC、触摸屏、视频游戏控制器 * 控制设备:音频编解码器、数字电位器、DAC * 相机镜头:佳能EF镜头卡口 * 通信:以太网、USB、USART、CAN、IEEE802.15.4、IEEE 802.11、手持视频游戏 * 内存:闪存和EEPROM * 实时时钟 * LCD,有时甚至用于管理图像数据 * 任何MMC或SD卡(包括SDIO变种) 对于高性能系统,FPGA有时使用SPI作为主机的从机接口、作为传感器的主机、或者如果它们是基于SRAM的,则用于引导的闪存。 虽然SPI总线和JTAG(IEEE 1149.1-2013)协议之间存在一些相似之处,但它们不可互换。 SPI总线用于器件外设的高速、板载初始化,而JTAG协议旨在通过板外控制器(有着比较低精度的信号延迟和偏斜参数)提供对I/O引脚的可靠测试访问。 JTAG协议不是严格意义上的电平敏感接口,它通过降低时钟速率或改变时钟的占空比来支持JTAG器件在建立和保持违规的情况下能够恢复。 因此,JTAG接口不是用来支持极高的数据速率的。 ### 4. 协议分析及调试设备 #### 4.1 主适配卡 有许多使用USB的硬件解决方案可以利用运行Linux、Mac或Windows的计算机支持SPI主控和/或从属功能。其中许多还提供脚本和/或编程功能(Visual Basic,C / C ++,VHDL等)。 SPI主机适配器允许用户直接从PC在SPI总线上扮演主站的角色。它们用于嵌入式系统、芯片(FPGA/ASIC/SoC)和外设测试、编程和调试。 SPI适配器的关键参数包括:串行接口支持的最大频率、命令到命令延迟以及SPI命令的最大长度。目前市场上可以找到支持高达100MHz串行接口的SPI适配器,几乎无限制的访问长度。 SPI协议是事实上的标准,一些SPI主机适配器还能够支持超越传统4线SPI的其他协议(例如,支持四SPI协议或其他源自SPI的定制串行协议)。 SPI适配器的示例(制造商按字母顺序): ^生产商 |SPI Host适配卡 |Host总线 |支持的总线协议 |最高频率| ^Byte Paradigm |SPI Storm |USB |SPI, dual/quad, custom |100 MHz | ^Corelis |BusPro-S |USB |SPI, dual/quad |60 MHz | ^HydraBus |HydraBus-HydraFW |USB |SPI |42 MHz | ^Microchip |MCP2210 Kit |USB |SPI |12 MHz | ^National Instruments |USB-8452 |USB |I²C, SPI |50 MHz | ^Total Phase |Cheetah SPI Host Adapter |USB |SPI |40 MHz | ^Total Phase |Promira Serial Platform |USB, Ethernet |I²C, SPI, single/dual/quad, and eSPI |80 MHz | ^Dangerous Prototypes |Bus Pirate |USB |1-Wire, I2C, SPI, JTAG*, Asynchronous serial, Scriptable binary bitbang, UART |varies | #### 4.2 协议分析仪 SPI协议分析仪可以对SPI总线进行采样并对电信号进行解码分析,以提供在特定总线上传输的数据的更高级别视图。SPI协议分析仪示例(制造商按字母顺序排列): ^厂商 |分析仪的型号|上位机的总线 |支持的总线协议 |最高采样率 |其它| ^Saleae Logic Pro 16 |USB |SPI, I2C, serial, custom |500 Mega-samples/second |Analog (50Msps)| ^TechTools |DigiView Logic Analyzers |USB |SPI, I2C, CAN, Async, Sync, I2S, State, Custom |500Msps|Extendable with custom plugins| ^Total Phase |Beagle I2C/SPI Protocol Analyzer |USB |SPI, I2C, MDIO |50Msps| ^Total Phase |Promira Serial Platform |USB, Ethernet |eSPI | #### 4.3 示波器 每个主要的示波器供应商都为SPI提供了基于示波器的触发和协议解码,大多数支持2线、3线和4线SPI。 触发和解码功能通常作为可选附件提供。SPI信号可通过模拟示波器通道或数字MSO通道进行访问。 #### 4.4 逻辑分析仪 在开发和/或排除SPI总线故障时,检查硬件信号非常重要。 逻辑分析仪是收集、分析、解码和存储信号的工具,因此人们可以用它来查看高速波形。 逻辑分析仪显示每个信号电平变化的时间戳,这有助于发现协议问题。大多数逻辑分析仪都能够将总线信号解码为高级协议数据并显示ASCII数据。 ### 5. 相关设计资源参考 * 苏老师公众号文章 - [几种最常用的串行数据传输总线(1)- SPI](https://mp.weixin.qq.com/s/jWbvn-DGR9xrrMHKBqXleQ) * FPGA4FUN上关于如何使用SPI的文章及相应的参考代码 - [[https://www.fpga4fun.com/SPI.html|SPI接口]] * [[简易电压表设计|使用SPI总线的简易电压表设计]] * Lattice Semi官网提供的[SPI控制器模块](http://www.latticesemi.com/en/Products/DesignSoftwareAndIP/IntellectualProperty/ReferenceDesigns/ReferenceDesign03/SPIMasterController)使用说明,及参考IP下载 * Lattice Semi官网提供的[SPI从设备控制器]( http://www.latticesemi.com/en/Products/DesignSoftwareAndIP/IntellectualProperty/ReferenceDesigns/ReferenceDesign03/SPISlaveController)使用说明,及参考IP下载 * Lattice Semi官网的[用于嵌入式功能块中的SPI从外设](http://www.latticesemi.com/en/Products/DesignSoftwareAndIP/IntellectualProperty/ReferenceDesigns/ReferenceDesign03/SPISlavePeripheralusingEmbeddedFunctionBlock)使用说明,及参考IP下载 * Lattice Semi官网的[SPI从设备到PWM的发生器](http://www.latticesemi.com/en/Products/DesignSoftwareAndIP/IntellectualProperty/ReferenceDesigns/ReferenceDesign03/SPISlavetoPWMGeneration)使用说明,及参考IP下载