STM32单片机SPI通信详解

文章目录

[1. SPI通信概述](#1. SPI通信概述)

[2. 硬件电路](#2. 硬件电路)

[3. 移位示意图](#3. 移位示意图)

[4. SPI时序基本单元](#4. SPI时序基本单元)

[5. SPI时序](#5. SPI时序)

[6. Flash操作注意事项](#6. Flash操作注意事项)

[7. SPI外设简介](#7. SPI外设简介)

[8. SPI框图](#8. SPI框图)

[9. SPI基本结构](#9. SPI基本结构)

[10. 主模式全双工连续传输](#10. 主模式全双工连续传输)

[11. 非连续传输](#11. 非连续传输)

[12. 软件/硬件波形对比](#12. 软件/硬件波形对比)

[13. 代码示例](#13. 代码示例)


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 线发送到主机。数据传输是在时钟信号的上升沿开始,而数据采样则是在下降沿进行的。
  • 具体步骤如下:
    1. SCK 上升沿(第一个边沿): 主机和从机的数据移位寄存器中的最高位 (B7) 开始传输。
    2. SCK 下降沿(第二个边沿): 数据传输完成,主机和从机在下降沿采样数据。
    3. 数据移位: 每个 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. 写入操作前,必须先进行写使能
    • 为了防止误操作,类似于手机先解锁再使用,写入前必须启用写使能,以避免误操作。
  2. 每个数据位只能由1改写为0,不能由0改写为1
    • 由于Flash的特性,数据只能从高变低,不能从低变高。因此在写入数据前需要先执行擦除操作。
  3. 写入数据前必须先擦除
    • 擦除后,所有数据位都变为1。擦除操作是最小单位为扇区。
  4. 连续写入多字节时,最多写入一页的数据,超过页面尾位置的数据,会回到页面首覆盖写入
    • 一个写入时序最多只能写一页的数据,超过一页的数据会覆盖页面首部。
  5. 写入操作结束后,芯片进入忙状态,不影响新的读写操作
    • 写入结束后芯片会显示忙(BUSY=1),此时暂时不能写入,需要等待芯片不忙再进行写入。

读取操作时:

  1. 直接调用读取时序,无需使能,无需额外操作,没有页的限制
    • 读取操作不需要任何额外操作和限制,可以直接读取数据。
  2. 读取操作结束后不会进入忙状态,但不能在忙状态时读取
    • 读取操作结束后不会使芯片进入忙状态,但在芯片忙时不能进行读取操作。

写操作详解:

  1. 防止误操作,类似手机先解锁再使用
    • 写入前需要写使能命令,防止误操作。
  2. Flash不像RAM一样可以直接覆盖之前写入的数据
    • Flash只能实现1变0,不能实现0变1,所以写入前需要擦除。
  3. 擦除操作是最小擦除单位进行
    • 可以选择整个芯片擦除、按块、按扇区擦除等。最小擦除单位为扇区。
  4. 每个扇区有4096字节
    • 如果需要修改特定字节,需要将所在扇区整个擦除,再重新写入。
  5. 写入时序最多只能写一页的数据
    • 一页有256字节,写入超过256字节的数据会覆盖页面首部。
  6. 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

相关推荐
cjy_Somnr2 小时前
keil5报错显示stm32的SWDIO未连接不能烧录
stm32·单片机·嵌入式硬件
Lay_鑫辰3 小时前
西门子诊断-状态和错误位(“轴”工艺对象 V1...3)
服务器·网络·单片机·嵌入式硬件·自动化
无垠的广袤5 小时前
【工业树莓派 CM0 NANO 单板计算机】本地部署 EMQX
linux·python·嵌入式硬件·物联网·树莓派·emqx·工业物联网
雲烟7 小时前
嵌入式设备EMC安规检测参考
网络·单片机·嵌入式硬件
泽虞7 小时前
《STM32单片机开发》p7
笔记·stm32·单片机·嵌入式硬件
田甲8 小时前
【STM32】 数码管驱动
stm32·单片机·嵌入式硬件
up向上up8 小时前
基于51单片机垃圾箱自动分类加料机快递物流分拣器系统设计
单片机·嵌入式硬件·51单片机
纳祥科技17 小时前
Switch快充方案,内置GaN,集成了多个独立芯片
单片机
单片机日志18 小时前
【单片机毕业设计】【mcugc-mcu826】基于单片机的智能风扇系统设计
stm32·单片机·嵌入式硬件·毕业设计·智能家居·课程设计·电子信息
松涛和鸣19 小时前
从零开始理解 C 语言函数指针与回调机制
linux·c语言·开发语言·嵌入式硬件·排序算法