概念
SPI,又称串行外设接口,一种全双工的高速同步总线,没有速度的限定,通常能到10Mbps,并且可以同时接收同时发送,以工作与主机或从机模式,但不支持多主机模式,支持一主机多从机。
硬件原理
SPI通信需要至少4根线(如图一所示),单向传输时是3根线(如图二、三、四所示),它们是MISO(主设备数据输入)、MOSI(主设备数据输出)、SCLK(时钟)和CS/SS(片选)。
图一:

图二:典型的单工模式连接(主机:接收,从机:发送)

图三:典型的单工模式连接(主机:只发送,从机:接收)

图四:典型的双向线连接

MISO/SDI:从机向主机发送数据(接收总线);
MOSI/ SDO:主机向从机发送数据(发送总线);
SCLK:时钟信号,由主设备产生;
CS/SS:选择从机,只有片选信号为预先规定的使能信号时(高电位或低电位),主芯片对此从芯片的操作才有效。
注:时钟极性(CKP/CPOL)和相位(CKE/CPHA)共同决定读取数据的方式,比如信号上升沿读取数据还是信号下降沿读取数据。
多从机模式
有两种方法可以将多个从设备连接到主设备:多片选和菊花链。
方式一:多片选
每个从机都需要一条单独的片选(SS)线。如果要和特定的从机进行通讯,可以将相应的片选信号(NSS)线拉低,并保持其他SS信号线的状态为高电平。
缺点:
如果同时将两个SS信号线拉低,则可能会出现乱码,因为从机可能都试图在同一条MISO线上传输数据,最终导致接收数据乱码。

方式二:菊花链
在设备信号(总线信号或中断信号)以串行的方式从一 个设备依次传到下一个设备,不断循环直到数据到达目标设备的方式被称为菊花链。
缺点:
菊花链的最大缺点是因为是信号串行传输,因为越到下面的设备,优先级越低,所以一旦数据链路中的某设备发生故障的时候,它下面优先级较低的设备就不可能得到服务了,可能将接收不到数据。

工作模式
通信操作模式有4种,区别是定义了在时钟脉冲的哪条边沿发送数据,然而发送数据又取决于 “时钟极性(CKP/CPOL)” 和 “相位(CKE/CPHA)”,如下图所示。
Mode0:CKP=0,CKE =0:当空闲态时,SCK处于低电平,数据采样是在第1个边沿,也就是SCK由低电平到高电平的跳变,所以数据采样是在上升沿(准备数据),(发送数据)数据发送是在下降沿。
Mode1:CKP=0,CKE=1:当空闲态时,SCK处于低电平,数据发送是在第2个边沿,也就是SCK由低电平到高电平的跳变,所以数据采样是在下降沿,数据发送是在上升沿。
Mode2:CKP=1,CKE=0:当空闲态时,SCK处于高电平,数据采集是在第1个边沿,也就是SCK由高电平到低电平的跳变,所以数据采集是在下降沿,数据发送是在上升沿。
Mode3:CKP=1,CKE=1:当空闲态时,SCK处于高电平,数据发送是在第2个边沿,也就是SCK由高电平到低电平的跳变,所以数据采集是在上升沿,数据发送是在下降沿。

SPI优缺点
-
优点
-
无起始位和停止位,因此数据位可以连续传输而不会被中断;
-
没有像I2C这样复杂的从设备寻址系统;
-
数据传输速率比I2C更高(几乎快两倍);
-
分离的MISO和MOSI信号线,因此可以同时发送和接收数据;
-
极其灵活的数据传输,不限于8位,它可以是任意大小的字;
-
非常简单的硬件结构。从站不需要唯一地址(与I2C不同)。
-
从机使用主机时钟,不需要精密时钟振荡器/晶振(与UART不同)。
-
不需要收发器(与CAN不同)。
-
缺点
-
使用四根信号线(I2C和UART使用两根信号线);
-
无法确认是否已成功接收数据(I2C拥有此功能);
-
没有任何形式的错误检查,如UART中的奇偶校验位;
-
只允许一个主设备;
-
没有硬件从机应答信号(主机可能在不知情的情况下无处发送);
-
没有定义硬件级别的错误检查协议;
-
与RS-232和CAN总线相比,只能支持非常短的距离;
与IIC异同点
| IIC | SPI |
|---|---|
| 半双工 | 全双工 |
| 有应答机制 | 无应答机制 |
| 通过向总线广播从机地址来寻址 | 通过向对应从机发送使能信号来寻址 |
| 时钟极性和时钟相位固定 | 时钟极性和时钟相位可调 |
配置方式
spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX; //配置SPI的类型
spi_init_struct.device_mode = SPI_MASTER; //配置为主机或从机模式
spi_init_struct.frame_size = SPI_FRAMESIZE_8BIT; //配置SPI帧的大小
spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE; //配置时钟相位和极性,选择四种模式的一种
spi_init_struct.nss = SPI_NSS_SOFT; //选择SPI的nss控制由硬件或软件
spi_init_struct.prescale = SPI_PSC_32; //选择SPI的时钟分频
spi_init_struct.endian = SPI_ENDIAN_MSB; //选择发送方式(大端序或小端序)
spi_init(SPI5, &spi_init_struct); //对SPI的参数进行初始化
使用方法
qspi_flash_buffer_write(tx_buffer,FLASH_WRITE_ADDRESS,256); //往flash里面写数据
qspi_flash_buffer_read(rx_buffer,FLASH_READ_ADDRESS,256); //从flash里面读数据
1万+

被折叠的 条评论
为什么被折叠?



