SPI通信流程

本文详细比较了SPI和IIC通信协议,阐述了SPI的快速传输、简单设计和较大硬件成本,以及IIC的半双工特性和多主机同步。还介绍了SPI的移位示意图和时序配置,以及IIC的典型应用模式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SPI通信

  • SPI (串行外设接口,Serial Peripheral Interface)是由Motorola公司开发的一种通用数据总线
  • 四根通信线:
    • SCK (Serial Clock) 串行时钟线 或者称为SCLK、CLK、CK
    • MOSI (Master Output Slave Input) 主机输出从机输入 或者称为 DO(Data Output)
    • MISO (Master Input Slave Output) 主机输入从机输出 或者称为 DI(Data Input)
    • SS (Slave Select) 从机选择 或者称为 NSS(Not Slave Select)、CS(Chip Select)
  • 同步,全双工
  • 支持总线挂载多设备(一主多从) 仅支持一主多从,不支持多主机

SPI相较IIC的优缺点

  • 1.SPI传输更快,SPI协议并没有严格规定最大传输速度,这个最大传输速度取决于芯片厂商的设计需求
  • 2.SPI的设计比较简单粗暴,实现的功能没有IIC那么多
  • 3.SPI的硬件卡开销比较大,通信线的个数比较多,并且通信过程中,经常会有资源浪费的现象

硬件电路

  • 所有SPI设备的SCK、MOSI、MISO分别连在一起
  • 主机另外引出多条SS控制线,分别接到各从机的SS引脚
  • 输出引脚配置为推挽输出,输入引脚配置为浮空或上拉输入
    在这里插入图片描述

SS线是低电平有效,主机想和谁通信,就把对应的SS输出线置低电平就行了,所以刚开始初始化的时候把所有的SS线置高电平,即1,这样就谁都不指定,通信结束之后,再置为高电平

当然同一时间,主机只能置一个SS为低电平,只能选中一个从机,否则,如果主机同时选中多个从机,就会导致数据冲突

这里为什么IIC不使用推挽输出获得更快的传输速度呢?

推挽输出,高低电平都有很强的驱动能力,这将使得SPI引脚信号的下降沿,非常迅速,上升沿,也非常迅速,SPI信号变化的快,那自然它就能达到更高的传输速度,一般SPI信号都能轻松达到MHZ的速度级别

然而这里IIC并不是不想使用更快的推挽输出,而是I2C要实现半双工,经常要切换输入输出,另外I2C又要实现多主机的时钟同步和总线仲裁,这些功能,都不允许I2C使用推挽输出

在这里还有一个问题,就是如果三个从机都始终是推挽输出,势必会导致冲突,所以在SPI协议里,有一条规定,当从机的SS引脚为高电平,也就是从机未被选中时,它的MISO引脚,必须切换为高阻态,这样就可以防止,一条线有多个输出,而导致的电平冲突的问题了,在SS为低电平时,MISO才被允许变为推挽输出,当然这个切换过程都是在从机里,我们都是一般写主机程序,并不需要关注这个问题

移位示意图

在这里插入图片描述

SPI一般都是高位先行的,所以波特率发生器也就是时钟源SCK,每来一个时钟,移位寄存器都会向左进行移位,从机中的移位寄存器也是同理

在时钟波形图中,当处于上升沿时,主机将高位数据输出到MOSI通信线上,从机也把最高位输出到MISO通信线上,然后下降沿进行数据采样输入,MOSI线上的数据就输出到从机的移位寄存器中,同样,MISO线上的数据输入到主机的移位寄存器中,这样就完成了一次一位数据的交换,这样的步骤重复8次也就是8个时钟后,那么就可以交换一个字节数据了

在这里插入图片描述

  • 如果只想发送数据,不接受数据,那么主机只管发送数据即可,不去读取从机发送过来的数据即可
  • 如果只想接收数据,那么主机只管随便发送一个字节数据,把从机的数据交换过来就可以了,通常都是发送0x000xFF

SPI时序基本单元

起始和终止条件
  • 起始条件:SS从高电平切换到低电平
  • 终止条件:SS从低电平切换到高电平

在这里插入图片描述

传输单元

什么时候开始移位?是上升沿移位还是下降沿移位?SPI并没有限定死,给了我们可以配置的选择,这样的话,SPI就可以兼容更多的芯片。
SPI有两个可以配置的位CPOL(时钟极性,Clock Polarity)和CPHA(时钟相位,Clock Phase),每一位可以配置为0和1,这样就可以有四种模式,但功能都是一样的

  • 交换一个字节 (模式0)
  • GPOL=0:空闲状态时,SCK为低电平
  • CPHA=0: SCK第一个边沿移入数据,第二个边沿移出数据

在这里插入图片描述

  • 交换一个字节(模式1)
  • CPOL=0:空闲状态时,SCK为低电平
  • CPHA=1: SCK第一个边沿移出数据,第二个边沿移入数据

在这里插入图片描述

  • 交换一个字节 (模式2)
  • CPOL=1:空闲状态时,SCK为高电平
  • CPHA=0: SCK第一个边沿移入数据,第二个边沿移出数据

  • 交换一个字节(模式3)
  • CPOL=1:空闲状态时,SCK为高电平
  • CPHA=1: SCK第一个边沿移出数据,第二个边沿移入数据

IIC规定一般是有效数据流第一个字节是寄存器地址,之后依次是读写的数据,使用的是读写寄存器的模型
而SPI使用的是指令码加读写数据模型,第一个发送交换的数据,一般叫作指令码,在从机中,对应的会定义一个指令集,当我们需要发送什么指令时,就可以在起始后第一个字节发送指令集里面的数据,这样就能指导完成相应的功能了,不同的指令,可以有不同的数据个数,有的指定,只需要一个字节的指令码就可以完成,比如W25Q64(存储器模块)的写使能,写失能等指令,而有的指令,后面就需要再跟要读写的数据,比如W25Q54的写数据、读数据等,写数据,指令后面就得跟上,我要在哪里写,写什么

<think>好的,用户想了解嵌入式系统中的SPI通信过程。首先,我需要回忆SPI的基本原理和组成部分。SPI是串行外设接口,常用于嵌入式系统中连接微控制器和外围设备,如传感器、存储器等。 首先,SPI通常采用主从模式,一个主设备控制多个从设备。通信需要四根线:SCK(时钟)、MOSI(主出从入)、MISO(主入从出)、SS(片选)。用户可能需要知道每个信号线的作用,比如SCK由主设备生成,同步数据传输;SS用于选择特定从设备。 接下来是通信的具体步骤。主设备通过拉低对应从设备的SS线来启动通信。然后主设备生成时钟信号,数据在时钟的上升沿或下降沿传输。数据通常以字节为单位,通过MOSI和MISO线同时进行全双工通信。传输结束后,SS线被拉高,结束本次通信。 可能还需要提到SPI的模式,即时钟极性和相位的不同组合(模式0-3),这决定了数据何时被采样。例如,模式0是时钟空闲低电平,在上升沿采样数据。 另外,用户可能关心SPI的优势,比如高速、全双工、简单实现,但也要提到缺点,比如没有错误检测机制,需要更多引脚连接多个从设备。 根据提供的引用,特别是引用[1]提到嵌入式系统的输入输出和处理器,SPI作为通信方式属于输入输出部分。引用[3]中提到的RFID与物联网的数据传输可能与SPI有关联,比如传感器数据的传输过程。 需要确保回答符合用户的要求,使用中文,行内公式用$...$,独立公式用$$...$$。同时生成相关问题,如SPI与其他协议的区别、配置步骤、常见问题等。 最后检查LaTeX语法是否正确,引用标识自然添加在相关段落末尾。例如,提到主从结构时引用[^1],提到硬件连接时引用[^2]。</think>### SPI通信过程详解 SPI(Serial Peripheral Interface)是一种**全双工同步串行通信协议**,广泛应用于嵌入式系统中连接处理器与传感器、存储器等外设[^1]。其核心特征包含以下步骤: #### 1. 硬件连接结构(主从模式) SPI采用主从架构,需四根信号线: - **SCK (Serial Clock)**:主设备生成的时钟信号,同步数据传输 - **MOSI (Master Out Slave In)**:主设备发送数据通道 - **MISO (Master In Slave Out)**:从设备响应数据通道 - **SS/CS (Slave Select/Chip Select)**:从设备使能信号(每个从设备独立一根) 主设备通过拉低SS线选择特定从设备进行通信,例如选择温度传感器时拉低对应SS引脚。 #### 2. 数据传输时序 $$数据有效性 = \text{时钟边沿} \times \text{极性控制}$$ 通信流程分为五个阶段: 1. **SS激活**:主设备拉低目标从设备的SS线 2. **时钟配置**:设置CPOL(时钟极性)和CPHA(时钟相位)确定数据采样时刻 3. **数据交换**: - 主设备通过MOSI发送数据字节(MSB/LSB优先) - 从设备通过MISO同步返回数据 4. **时钟控制**:每个时钟周期传输1bit数据(上升沿发送/下降沿接收等模式) 5. **通信终止**:SS线恢复高电平 #### 3. 典型应用场景 - 高速ADC/DAC数据传输(如音频编码) - 存储器访问(Flash/EEPROM) - 显示器驱动(OLED/LCD屏配置) - 多传感器系统(温湿度+气压组合模块)[^3] ```c // 示例:STM32 SPI初始化代码片段 void SPI_Config(void) { SPI_HandleTypeDef hspi; hspi.Instance = SPI1; hspi.Init.Mode = SPI_MODE_MASTER; hspi.Init.Direction = SPI_DIRECTION_2LINES; hspi.Init.DataSize = SPI_DATASIZE_8BIT; hspi.Init.CLKPolarity = SPI_POLARITY_LOW; // CPOL=0 hspi.Init.CLKPhase = SPI_PHASE_1EDGE; // CPHA=0 HAL_SPI_Init(&hspi); } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值