【江协STM32】11-1 SPI通信协议

  • SPI(Serial Peripheral Interface)是由Motorola公司开发的一种通用数据总线
  • 四根通信线:SCK(Serial Clock)、MOSI(Master Output Slave Input)、MISO(Master Input Slave Output)、SS(Slave Select)
  • 同步,全双工
  • 支持总线挂载多设备(一主多从)

1. 硬件电路

  • 所有SPI设备的SCK、MOSI、MISO分别连在一起
  • 主机另外引出多条SS控制线,分别接到各从机的SS引脚(低电平有效,主机想指定哪个从机,就把对应的SS输出线置低电平)
    同一时间,主机只能置一个SS为低电平,选中一个从机
  • 输出 引脚配置为推挽输出输入 引脚配置为浮空上拉输入
    SPI协议在从机中的规定:当从机的SS引脚为高电平(从机未被选中),它的MISO引脚必须切换为高阻态(相当于引脚断开,不输出任何电平),在SS为低电平时,MISO才允许变为推挽输出,避免了MISO引脚数据冲突

2. 移位示意图

SPI一般为高位先行,每来一个时钟,移位寄存器都会向左进行移位。移位寄存器的时钟源(波特率发生器)由主机提供。主机移位寄存器向左移出去的数据,通过MOSI引脚,输入到从机移位寄存器的右边。从机移位寄存器向左移出去的数据,通过MISO引脚,输入到主机移位寄存器的右边。

规定波特率发生器时钟的上升沿,所有移位寄存器向左移动1位,移出去的位放在引脚上。波特率发生器的下降沿,引脚上的位采样输入到移位寄存器的最低位。

3. SPI时序基本单元

  • 起始条件:SS从高电平切换到低电平
  • 终止条件:SS从低电平切换到高电平
  • 交换一个字节(模式0)该模式使用较多
  • CPOL=0 (Clock Polarity, 时钟极性):空闲状态时,SCK为低电平
  • CPHA=0 (Clock Phase, 时钟相位):SCK第一个边沿移入数据,第二个边沿移出数据
  • 交换一个字节(模式1)
  • CPOL=0:空闲状态时,SCK为低电平
  • CPHA=1:SCK第一个边沿移出数据,第二个边沿移入数据(数据采样)

SS高电平时,MISO用一条中间的线表示高阻态

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

4. SPI时序

每个芯片对SPI时序字节流功能的定义不同,这里以W25Q64的时序为例。

SPI对字节流功能的规定与I2C不同。I2C的规定一般是,有效数据流第一个字节是寄存器地址,之后依次是读写的数据,使用的是读写寄存器的模型。而在SPI中,通常采用的是指令码加读写数据的模型。SPI起始后,第一个交换发送给从机的数据,一般叫做指令码。在从机中,对应的会定义一个指令集,这样就可以指导从机完成相应的功能。

4.1 发送指令

  • 向SS指定的设备,发送指令(0x06)

SS产生下降沿,时序开始。MOSI,由于指令码最高位仍然是0,所以保持低电平不变。MISO,从机现在没有数据发送给主机,引脚电平没有变换,实际上W25Q64不需要回传数据时,MISO仍然为高阻态,从机没有开启输出,这里因为STM32的MISO为上拉输入,所以MISO呈现高电平。之后,SCK第一个上升沿,进行数据采样,从机采样输入得到0,主机采样输入得到1。

再往后,主机要发送数据1,SCK下降沿,主机将1移出到MOSI,MOSI变为高电平,这里因为是软件模拟的时序,所以MOSI的数据变化有延迟,没有紧贴SCK的下降沿,只要在下一个SCK上升沿之前完成变化即可。然后SCK上升沿,数据采样输入。在最后一位,下降沿,数据变化,MOSI变为0。上升沿,数据采样,从机接收数据0。SCK低电平是变化的时期,高电平是读取的时期。

4.2 指定地址写

  • 向SS指定的设备,发送写指令(0x02),随后在指定地址(Address[23:0])下,写入指定数据(Data)

SS下降沿,开始时序。这里MOSI空闲时是高电平,所以在下降沿之后,SCK第一个时钟之前,MOSI变换数据,由高电平变为低电平。随后SCK上升沿,数据采样输入。下降沿变换数据,上升沿采样数据。8个时钟后,一个字节交换完成,用0x02换来了0xFF,接收的0xFF不需要使用。第二个字节,用0x12(发送地址的23~16位)换来了0xFF。第三个字节,用0x34(发送地址的15~8位)换来了0xFF。第四个字节,用0x56(发送地址的7~0位)换来了0xFF。通过3个字节的交换,24位地址发送完毕。从机收到的24位地址是0x123456。3位地址结束后,发送写入指定地址的内容。第五个字节,发送数据,这里的波形是0x55。如果只想写入一个数据,就可以SS置高电平,结束通信。

这里也可以继续发送数据,SPI也有和I2C一样的地址指针,每读写一个字节,地址指针自动加1,如果发送一个字节之后不终止,继续发送的字节就会依次写入到后续的存储空间内。由于SPI没有应答机制,所以交换一个字节后,立刻交换下一个字节即可。

4.3 指定地址读

  • 向SS指定的设备,发送读指令(0x03),随后在指定地址(Address[23:0])下,读取从机数据(Data)
相关推荐
国科安芯3 小时前
ASP4644芯片低功耗设计思路解析
网络·单片机·嵌入式硬件·安全
充哥单片机设计3 小时前
【STM32项目开源】基于STM32的智能厨房火灾燃气监控
stm32·单片机·嵌入式硬件
CiLerLinux10 小时前
第四十九章 ESP32S3 WiFi 路由实验
网络·人工智能·单片机·嵌入式硬件
时光の尘10 小时前
【PCB电路设计】常见元器件简介(电阻、电容、电感、二极管、三极管以及场效应管)
单片机·嵌入式硬件·pcb·二极管·电感·三极管·场效应管
Lu Zelin10 小时前
单片机为什么不能跑Linux
linux·单片机·嵌入式硬件
宁静致远202111 小时前
stm32 freertos下基于hal库的模拟I2C驱动实现
stm32·嵌入式硬件·freertos
Wave84515 小时前
STM32--智能小车
stm32·单片机·嵌入式硬件
wdfk_prog18 小时前
[Linux]学习笔记系列 -- lib/timerqueue.c Timer Queue Management 高精度定时器的有序数据结构
linux·c语言·数据结构·笔记·单片机·学习·安全
helesheng20 小时前
用低成本FPGA实现FSMC接口的多串口(UART)控制器
stm32·fsmc·fpga·uart控制器
充哥单片机设计21 小时前
【STM32项目开源】基于STM32的智能家居环境(空气质量)检测系统
stm32·单片机·嵌入式硬件