前言:
为了方便查看博客,特意申请了一个公众号,附上二维码,有兴趣的朋友可以关注,和我一起讨论学习,一起享受技术,一起成长。
1.概念介绍
SPI(Serial Peripheral Interface)是串行外围设备接口。是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为 PCB 的布局上节省空间,提供方便,正是出于这种简单易用的特性,现在越来越多的芯片集成了这种通信协议。常用于单片机和 EEPROM、FLASH、实时时钟、数字信号处理器等器件的通信。
2.特点
2.1 连接方式
SPI 是一个环形总线结构,由设备选择线(CS)、时钟线(SCK)、串行输出数据线(MOSI)、串行输入数据线(MISO) 构成,其时序其实很简单,主要是在 sck 的控制下,两个双向移位寄存器进行数据交换。
(1)MOSI: 主器件数据输出,从器件数据输入;
(2)MISO: 主器件数据输入,从器件数据输出;
(3)SCLK : 时钟信号,由主器件产生;
(4)SS(CS): 从器件使能信号,由主器件控制。
2.2 模式
SPI 用主从模式(Master Slave)架构;支持多 slave 模式应用,一般仅支持单 Master。时钟由 Master 控制,在时钟移位脉冲下,数据按位传输,高位在前,低位在后(MSB first);SPI 接口有 2 根单向数据线,为全双工通信,目前应用中的数据速率可达几 Mbps 的水平。
主片在访问某一从片时,必须使该从片的片选信号有效;主片在 SCK 信号的同步下,通过 MOSI 线发出指令、地址信息;如需将数据输出,则接着写指令,由 SCK 同步在 MOSI 线上发出数据;如需读回数据,则接着读指令,由主片发出 SCK,从片根据 SCK 的节拍通过 MISO 发回数据。对具有 SPI 接口的从片器件来讲,SCK、MOSI 是输入信号,MISO 是输出信号。
3. 内部结构
工作原理:主机和从机内部都有一个串行的移位寄存器,主机向其串行移位寄存器中写入一个字节发起传输,寄存器通过 MOSI 信号线将字节发送到从机,从机也将自己的移位寄存器一个字节发送给主机,从而实现两个移位寄存器的一个字节交换。
4. 通信方式
4.1 通信协议
SPI 是单主设备通信协议,这意味着总线中只有一个中心设备能发起通信,当 SPI 主设备想读/写从设备时,它要 拉低从设备对应的 CS 线(CS 是低电平有效的)。主机和从机都有一个串行移位寄存器,主机通过向它的 SPI 串行寄存器写入一个字节来发起一次传输。寄存器通过 MOSI 信号线将字节传送给从机,实现“写”的功能。从机也将自己的移位寄存器中的内容通过 MISO 信号线返回给主机,实现“读”的功能。这样,两个移位寄存器中的内容就被交换,外设的写操作和读操作是同步完成的。如果只进行写操作,主机只需忽略接收到的字节;反之,若主机要读取从机的一个字节,就必须发送一个空字节来引发从机的传输。
4.2 操作模式
SPI 有四种操作模式,模式0、模式1、模式2、模式3 其中使用的最为广泛的是 SPI0 和 SPI3 方式。它们的区别是定义了在时钟脉冲的哪条边沿转换输出信号,哪条边沿采样输入信号,还有时钟脉冲的稳定电平值(就是时钟信号无效时是高还是低)。每种模式都由参数时钟极性 CPOL 和时钟相位 CPHA 刻画。 时钟极性设置时钟空闲时的电平,时钟相位设置读取数据和发送数据的时钟沿。 通信双方必须是工作在同一模式下,CPOL 与 CPHA 的选项可实现时钟信号 180 度的相移以及半个时钟周期的数据延迟。(CPHA = 0 表示在每个周期的第一个时钟沿采样; CPHA = 1 表示在每个周期的第二个时钟沿采样。)
四种模式如下图:
如图:数据采集的电平
主机和从机的发送数据是同时完成的,两者的接收数据也是同时完成的。所以为了保证主从机正确通信,应使得它们的 SPI 具有相同的时钟极性和时钟相位。因为:其一,主设备 SPI 时钟和极性的配置应该由外设来决定;其二,二者的配置应该保持一致,即主设备的 SDO 同从设备的 SDO 配置一致,主设备的 SDI 同从设备的S DI 配置一致。因为主从设备是在 SCK 的控制下,同时发送和接收数据,并通过 2 个双向移位寄存器来交换数据。
4.3 传输时序
四种模式的传输时序如下:
一个完整的传送周期是 16 位,即两个字节,因为,首先主机要发送命令过去,然后从机根据主机的命令准备数据,主机在下一个 8 位时钟周期才把数据读回来。如下图:
4.4 数据传输
在一个 SPI 时钟周期内,会完成如下操作:
(1)主机通过 MOSI 线发送 1 位数据,从机通过该线读取这 1 位数据;
(2)从机通过 MISO 线发送 1 位数据,主机通过该线读取这 1 位数据。
这是通过移位寄存器来实现的。如下图所示,主机和从机各有一个移位寄存器,且二者连接成环。随着时钟脉冲,数据按照从高位到低位的方式依次移出主机寄存器和从机寄存器,并且依次移入从机寄存器和主机寄存器。当寄存器中的内容全部移出时,相当于完成了两个寄存器内容的交换。
如下图,可以清晰明了的看出 SPI 传输的时序:对于模式 0 和 模式 3,传输数据总在上升沿;对于模式 1 和模式 2 ,传输数据总在下降沿。 若采用软件模拟 SPI 时序,可以设计读写代码。
这里给出模式 0 的代码,可根据时序来完成:
//模式0:CPOL=0;CPAH=0
//模拟SPI写数据
//--------------------------------------------------------------------------------------------------------
// 函 数 名: Spi_WriteByte
// 功能说明: spi写一字节数据(模式0)
// 形 参: _ucByte:写入的数据
// 返 回 值: 无
// 日 期: 2020-03-07
// 备 注: 软件模拟方式
// 作 者: b霁风AI
//--------------------------------------------------------------------------------------------------------
#if _CPOL==0&&_CPHA==0
void Spi_WriteByte(uint8_t _ucByte)
{
uint8_t ucDataLen = 0;
for (ucDataLen = 0; ucDataLen < 8; ucDataLen++)
{
SPI_CLK_LOW;//时钟上升沿采样传输数据
//nrf_delay_ms(1); //延时决定了SPI的CLK速率
if(_ucByte & 0x80) //发送数据
{
SPI_MOSI_HIGH;
}
else
{
SPI_MOSI_LOW;
}
SPI_CLK_HIGH;
// nrf_delay_ms(1); //延时决定了SPI的CLK速率
_ucByte <<= 1;
}
}
//--------------------------------------------------------------------------------------------------------
// 函 数 名: Spi_ReadByte
// 功能说明: spi读一字节数据(模式0)
// 形 参: 无
// 返 回 值: ucTmpVal:读取的数据
// 日 期: 2020-03-07
// 备 注: 软件模拟方式
// 作 者: 霁风AI
//--------------------------------------------------------------------------------------------------------
uint8_t Spi_ReadByte(void)
{
uint8_t ucDataLen = 0;
uint8_t ucTmpVal = 0;
SPI_CLK_HIGH;
for(ucDataLen = 0; ucDataLen < 8; ucDataLen++)
{
SPI_CLK_LOW; //下降沿后读取数据
//nrf_delay_ms(1);
ucTmpVal <<= 1;
if(SPI_MISO_READ) //读取IO上的电平
{
ucTmpVal |= 0x01;
}
else
{
ucTmpVal &= 0xfe;
}
SPI_CLK_HIGH;
//nrf_delay_ms(1);
}
return ucTmpVal;
}
#endif
4.5 优缺点
SPI 接口具有如下优点:
(1)支持全双工操作;
(2)操作简单;
(3) 数据传输速率较高。
缺点:
(1) 需要占用主机较多的口线(每个从机都需要一根片选线);
(2)只支持单个主机;
(3) 没有指定的流控制,没有应答机制确认是否接收到数据。
参考:
6.SPI
7.SPI接口扫盲 SPI定义/SPI时序(CPHA CPOL)
10.SPI详解
11.串行外围接口(SPI)