SPI通信
•SPI(Serial Peripheral Interface)是由Motorola公司开发的一种通用数据总线
•四根通信线:SCK(Serial Clock串行时钟线)、MOSI(Master Output Slave Input主机输出从机输入)、MISO(Master Input Slave Output主机输入从机输出)、SS(Slave Select从机选择)
•同步,全双工(数据发送和接收各占一条线,互不影响)
支持总线挂载多设备(一主多从)
硬件电路
•所有SPI设备的SCK、MOSI、MISO分别连在一起
•主机另外引出多条SS控制线,分别接到各从机的SS引脚(SS线低电平有效)
•输出引脚配置为推挽输出,输入引脚配置为浮空或上拉输入
左侧的SPI主机,主导整个SPI总线,一般是控制器来做,比如STM32。
由于有3个从机,因此需要3根SS(从机选择)线。
上图中没画出GND线,但是需要所有设备共地。
时钟线SCK完全由主机掌控,因此对于主机来说SCK为输出,对于所有从机来说,SCK为输入,由此把主机的同步时钟送到各个从机。
MOSI,主机输出从机输入,主机通过MOSI输出,所有从机通过MOSI输入。
MISO,主机输入从机输出,所有从机通过MISO输出,主机通过MISO输入。
移位示意图

每来一个时钟,主机中的移位寄存器向左移位,从机也是一样。时钟上升沿,主机和从机进行输出,把数据放到MOSI和MISO线上,时钟下降沿,主机和从机进行读取,依次交换字节。
时钟源(波特率发生器)由主机提供,驱动主机的移位寄存器移位,同时通过SCK引脚输出,到从机的移位寄存器。
主机移位寄存器左侧移出的数据,通过MOSI引脚,输入到从机移位寄存器的右边。从机移位寄存器左边移出的数据,通过MISO引脚输入到主机移位寄存器的左侧。
如果SPI主机只想发送数据,不想接收怎么办?
按照交换字节的时序,发送同时接收,但是不读取接收到的内容即可。
SPI时序基本单元
•起始条件:SS从高电平切换到低电平,左侧,代表选中某个从机
•终止条件:SS从低电平切换到高电平,右侧,结束从机选中状态
!!! note “”
CPHA表示时钟相位,决定第一个时钟采样移入还是第二个时钟采样移入。
•交换一个字节(模式0)
•CPOL=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第一个边沿移出数据,第二个边沿移入数据
SPI时序
•发送指令
•向SS指定的设备,发送指令(0x06)
下图,主机用0x06换来了从机的0xFF,但是实际上从机没有输出,0xFF是默认的高电平,没有意义。
•指定地址写
•向SS指定的设备,发送写指令(0x02),随后在指定地址(Address[23:0])下,写入指定数据(Data)
下图,发送的第一个数据0x02,为字节指令,第2(0x12)、3(0x34)、4(0x56)个字节为地址0x123456(W25Q64芯片的地址长度为3个字节),第5个字节为写入的数据,表示在0x123456地址下,写入0x55这个数据。
•指定地址读
•向SS指定的设备,发送读指令(0x03),随后在指定地址(Address[23:0])下,读取从机数据(Data)
下图,发送的第一个数据0x03,为字节指令,第2(0x12)、3(0x34)、4(0x56)个字节为地址0x123456(W25Q64芯片的地址长度为3个字节),第5个字节为0xFF,是为了和从机交换给的数据,此时从机传回0x123456地址下的数据0x55。