文章目录
1. SPI通信概述
SPI(Serial Peripheral Interface)和I2C一样,都是实现主控芯片和外挂芯片之间的数据交流。
I2C 与 SPI 的比较
I2C的缺点:
- 驱动能力差: I2C接口由于线路上拉电阻的电路结构,使得通信总线的驱动能力较弱。当通信线路电压较高时,电阻上的损耗就越大,限制了I2C的最大通信速度。在标准模式下,I2C的最高时钟频率仅为100kHz,相比于SPI要慢得多。
SPI的优点:
- 传输速度高: SPI在设计上更注重速度,其设计简单且灵活,能够支持更高的传输速率。
SPI是一种串行同步通信协议。它通过四根通信线(SCK、MOSI、MISO、SS)进行数据传输。
- 全双工: SPI支持全双工通信,可以同时进行数据发送和接收。
- 多设备支持: SPI支持多设备挂载(主多从),但不支持多主多从。
- 时钟线: SPI使用一根时钟线(SCK)来提供时钟信号。数据的输出和输入都在SCK的上升沿或下降沿进行,由主机提供时钟信号,数据接收由从机来完成。
SPI通信线
- SCK(Serial Clock): 提供时钟信号,由主机控制。数据传输依赖于SCK的时钟信号。
- MOSI(Master Out Slave In): 主机输出,从机输入。用于主设备向从设备发送数据。
- MISO(Master In Slave Out): 从机输出,主机输入。用于从设备向主设备发送数据。
- SS(Slave Select): 片选信号,用于选择从设备。每个从设备都有一个独立的SS线,通过拉低SS信号来选择相应的从设备进行通信。
SPI通信线别称
- SCK: SCLK, CLK, CK
- MOSI: MI, SIO, DO(Data Output)
- MISO: DI(Data Input)
- SS: NSS(Not Slave Select), CS(Chip Select)
时序和数据传输
- 无应答机制: SPI没有应答机制,这意味着主机发送的数据没有确认信号,数据传输的完整性和正确性需要其他手段保障。
- 时钟信号同步: SPI通信依赖时钟信号(SCK)进行数据同步,确保数据位在SCK的时钟沿(上升沿或下降沿)传输。
2. 硬件电路
三个从机,所以SS线需要3根,再加SCK,MOSI,MISO,就是六根。SPI所有通信线都是单端信号,它们的高低电平都是相对GND的电压差,所以单端信号的所有设备还需要共地,如果从机没有独立供电的话,主机还要额外引出电源VCC,给从机供电。
从机选择:主机的SS线都是输出,从机都是输入,SS线是低电平有效,主机想指定谁就把对应的SS输出线置低电平,其它置高,和指定的通信完成后再置回高电平。同一时间,主机只能置一个SS为低电平,只能选中一个从机。
SPI引脚配置:因为输入输出不会冲突所以输出引脚配置为推挽输出,高低电平都有很强的驱动能力,这使得SPI引脚信号的下降沿和上升沿非常迅速,可以达到MHZ的高速传输,I2C下降沿迅速,上升沿缓慢。如图SPI与I2C边沿示意图
SPI冲突点:MISO引脚,主机一个输入,但是从机三个全都是输出,如果三个从机始终都是推挽输出,势必会导致冲突,所以SPI协议规定,当从机的SS引脚为高电平时,也就是从机未被选中时,它的MISO引脚,必须切换为高阻态(相当于引脚断开,不输出任何电平),防止一条线有多个输出而导致的电平冲突问题。在SS为低电平时,MISO才允许变为推挽输出,从机会自动切换,写主机程序不用管。
3. 移位示意图
图中的移位示意图展示了主机和从机的数据交换过程。在每个时钟周期,主机和从机的移位寄存器都会同步向左移动一位,完成数据交换。
移位操作:
- SPI传输时,数据是通过移位寄存器进行传输的。主机和从机各自的移位寄存器在每个时钟脉冲时都会向左移动一位。
- 主机的移位寄存器将数据通过MOSI引脚从左边移出,并输入到从机的移位寄存器的右边。同时,从机的移位寄存器的数据通过MISO引脚从右边移出,输入到主机的移位寄存器的左边。
- 这一过程在每个SCK时钟周期的下降沿或者上升沿进行(取决于SPI模式)。
具体操作:
- 主机发送数据: 当SCK时钟信号产生时,主机的移位寄存器将最高位的数据通过MOSI引脚输出到从机。
- 从机接收数据: 从机的移位寄存器同步接收这个数据,并将其存入自己的移位寄存器中。同时,从机的移位寄存器也将数据通过MISO引脚发送回主机。
- 双向通信: 通过这样的交替传输,SPI实现了同时发送和接收数据的功能。
4. SPI时序基本单元
起始条件:SS从高电平切换到低电平
终止条件:SS从低电平切换到高电平
交换一个字节(模式0)
CPOL=0:空闲状态时,SCK为低电平
CPHA=0:SCK第一个边沿移入数据,第二个边沿移出数据
SPI 模式0 (CPOL=0, CPHA=0):
- CPOL=0: 空闲状态时,SCK 线保持低电平。
- CPHA=0: SCK 的第一个边沿(上升沿)用于将数据移入,第二个边沿(下降沿)用于移出数据。
- 在这种模式下,数据的传输和接收都是在时钟信号的第一个边沿开始进行的。
数据传输过程:
- 在 SCK 的第一个上升沿,主机将数据从 MOSI 线发送到从机,同时从机将数据从 MISO 线发送到主机。数据传输是在时钟信号的上升沿开始,而数据采样则是在下降沿进行的。
- 具体步骤如下:
- SCK 上升沿(第一个边沿): 主机和从机的数据移位寄存器中的最高位 (B7) 开始传输。
- SCK 下降沿(第二个边沿): 数据传输完成,主机和从机在下降沿采样数据。
- 数据移位: 每个 SCK 周期,数据寄存器中的数据位都会左移一位,准备下一个数据位的传输。这个过程会持续 8 次,直到一个字节的数据完全传输。
同步数据交换:
- 图示展示了主机和从机在同一个 SCK 时钟周期内的数据交换过程。主机在每个时钟周期将数据通过 MOSI 线发送,同时通过 MISO 线接收从机发送的数据。
- 示例: 主机发送的数据是 "10101010",从机发送的数据是 "01010101"。在第一个时钟周期,主机的 B7 和从机的 B7 同时传输。在下一个时钟周期,B6 被传输,依此类推,直到 B0。
SPI 有四种模式 (Mode 0 到 Mode 3),由 CPOL 和 CPHA 两个参数决定。每种模式定义了时钟极性和相位的不同组合,适应不同的应用场景。
交换一个字节(模式1)
CPOL=0:空闲状态时,SCK为低电平
CPHA=1:SCK第一个边沿移出数据,第二个边沿移入数据
Mode 1 (CPOL=0, CPHA=1): SCK 的第一个边沿(上升沿)移出数据,第二个边沿(下降沿)移入数据。
交换一个字节(模式2)
CPOL=1:空闲状态时,SCK为高电平
CPHA=0:SCK第一个边沿移入数据,第二个边沿移出数据
Mode 2 (CPOL=1, CPHA=0): 空闲状态时 SCK 为高电平,下降沿移入数据,上升沿移出数据。
交换一个字节(模式3)
CPOL=1:空闲状态时,SCK为高电平
CPHA=1:SCK第一个边沿移出数据,第二个边沿移入数据
Mode 3 (CPOL=1, CPHA=1): 空闲状态时 SCK 为高电平,下降沿移出数据,上升沿移入数据。
5. SPI时序
发送指令
向SS指定的设备,发送指令(0x06)(模式0)
指定地址写
向SS指定的设备,发送写指令(0x02),随后在指定地址(Address[23:0])下,写入指定数据(Data)
指定地址读
向SS指定的设备,发送读指令(0x03),随后在指定地址(Address[23:0])下,读取从机数据(Data)
W25Q64 的地址指针和数据传输
- W25Q64 芯片具有 8M 字节的存储空间,一个字节的 8 位地址显然不够用,因此采用 24 位地址,即三个字节传输。SPI 和 I2C 一样,地址指针每次读写一个字节后自动加 1。这样可以实现从指定地址开始,连续写入多个字节数据。SPI 没有应答机制,发送一个字节后紧接着发送下一个字节。通信中,接收的 MISO 线路保持空闲,只有主机发送时才有数据传输。
SPI 命令传输模式
- W25Q64 的操作遵循特定的命令流,类似于 I2C 的有数据流。SPI 通过发送指令来控制数据读写。首先,主机发送一个操作指令,指令后面紧跟地址和数据。每个指令定义了一组特定的操作,手册中详细列出了指令集。不同的指令可以有不同的功能,读写时需要先发送指令,然后是地址,最后是数据。
6. Flash操作注意事项
写入操作时:
- 写入操作前,必须先进行写使能:
- 为了防止误操作,类似于手机先解锁再使用,写入前必须启用写使能,以避免误操作。
- 每个数据位只能由1改写为0,不能由0改写为1:
- 由于Flash的特性,数据只能从高变低,不能从低变高。因此在写入数据前需要先执行擦除操作。
- 写入数据前必须先擦除:
- 擦除后,所有数据位都变为1。擦除操作是最小单位为扇区。
- 连续写入多字节时,最多写入一页的数据,超过页面尾位置的数据,会回到页面首覆盖写入:
- 一个写入时序最多只能写一页的数据,超过一页的数据会覆盖页面首部。
- 写入操作结束后,芯片进入忙状态,不影响新的读写操作:
- 写入结束后芯片会显示忙(BUSY=1),此时暂时不能写入,需要等待芯片不忙再进行写入。
读取操作时:
- 直接调用读取时序,无需使能,无需额外操作,没有页的限制:
- 读取操作不需要任何额外操作和限制,可以直接读取数据。
- 读取操作结束后不会进入忙状态,但不能在忙状态时读取:
- 读取操作结束后不会使芯片进入忙状态,但在芯片忙时不能进行读取操作。
写操作详解:
- 防止误操作,类似手机先解锁再使用:
- 写入前需要写使能命令,防止误操作。
- Flash不像RAM一样可以直接覆盖之前写入的数据:
- Flash只能实现1变0,不能实现0变1,所以写入前需要擦除。
- 擦除操作是最小擦除单位进行:
- 可以选择整个芯片擦除、按块、按扇区擦除等。最小擦除单位为扇区。
- 每个扇区有4096字节:
- 如果需要修改特定字节,需要将所在扇区整个擦除,再重新写入。
- 写入时序最多只能写一页的数据:
- 一页有256字节,写入超过256字节的数据会覆盖页面首部。
- Flash写入太快会导致数据丢失:
- 写入操作前需要擦除并进入忙状态,等待完成再写入。这样可以保证数据的正确写入。
例子:
- 例如一个Flash扇区为4KB(4096字节),在写入数据前需要擦除整个扇区,才能写入数据。
- 如果想修改0x00这个字节,需要擦除整个扇区,然后再将新的数据写入。
- 为了防止数据丢失,可以将要修改的扇区数据先读出放到RAM中,修改后再写入Flash。
7. SPI外设简介
STM32内部集成了硬件SPI收发电路,可以由硬件自动执行时钟生成、数据收发等功能,减轻CPU的负担
可配置8位/16位数据帧、高位先行/低位先行
时钟频率: fPCLK / (2, 4, 8, 16, 32, 64, 128, 256)
支持多主机模型、主或从操作
可精简为半双工/单工通信
支持DMA
兼容I2S协议
STM32F103C8T6 硬件SPI资源:SPI1、SPI2
8. SPI框图
移位寄存器的操作
- 右移过程:数据从低位一位一位地通过MOSI移出去,同时通过MISO一位一位地移入到数据高位。
- 控制位:移位寄存器的状态由LSBFIRST(帧格式控制位)控制。
- LSBFIRST = 0:先发送MSB(高位)。
- LSBFIRST = 1:先发送LSB(低位)。
数据寄存器
- 发送缓冲区(TDR)和接收缓冲区(RDR):
- TDR:用于发送数据。
- RDR:用于接收数据。
- 这两个寄存器占用同一个地址,统一称为DR。
实现连续数据流
- 发送数据流:
- 首先,将数据写入TDR。
- 当移位寄存器空闲时,TDR的数据转移到移位寄存器,开始移位。
- 转移时置TXE(发送寄存器空标志位)为1,表示可以继续写入下一个数据到TDR。
- 接收数据流:
- 数据通过MISO移入移位寄存器。
- 数据移入完成后,整体转移到RDR,同时置RXNE(接收寄存器非空标志位)为1,表示可以读取数据。
9. SPI基本结构
10. 主模式全双工连续传输
连续传输传输更快,但是操作复杂
11. 非连续传输
非连续传输好处容易封装,好理解,好用
12. 软件/硬件波形对比
硬件数据波形变化紧贴SCK边沿 软件数据变化在边沿后有些延迟。
I2C:SCL低电平期间数据变化,高电平期间数据采样 SPI:SCK下降沿数据移出,上升沿数据移入。 两者最终波形的表现形式都是一样的,无论是下降沿变化还是低电平期间变化,它们都 是一个意思,都可以作为数据变化的时刻。
13. 代码示例
STM32通过SPI软件读写W25Q64
STM32通过SPI硬件读写W25Q64