7.5.7 SPI 使用指南
硬件支持
- 如果 SPI 使用 DMA 传输,必须保证以下限制:
- 传输长度需要保证8字节对齐,否则会出现数据越界的问题;
- 发送和接收数据的 buffer 地址必须对齐为64字节;
- Channel 单次传输数据量不能超过4096字节;
- 支持 SPI 作为 Slave 功能;
- Mcu 侧 SPI 做 Slave 时,速率大于9M,只能采用 DMA 模式;
- 当 MCU 作为 SPI 从设备时,其通信时钟由主设备提供。因此,从设备必须对主设备的每一次数据传输请求做出即时响应。若采用中断处理模式,需确保 SPI 中断服务程序的执行时间足够短。若中断被阻塞过久,未能及时处理数据寄存器,将导致接收缓冲区溢出。为此,强烈推荐使用 DMA 传输模式,以硬件方式自动完成数据搬运,从而保障通信的实时性与可靠性。
- Mcu 侧 SPI 在8位模式下工作时,具有以下限制:
- 1个 SPI 并行收发最大速度: 50M;
- 2个 SPI 并行收发最大速度: 33.3M;
- 3个 SPI 并行收发最大速度: 25M;
- 4个 SPI 并行收发最大速度: 20M;
- 5个 SPI 并行收发最大速度: 15.6M;
- 6个 SPI 并行收发最大速度: 12.5M;
- SPI 外设只支持 MSB;
- SPI SpiCsPolarity 和 spitimeclk2c 都不支持配置,SpiCsPolarity 默认为低电平有效。
- SPI SpiCsToggleEnable 配置使能后,Spi 传输完一个 frame 后,会拉高 CS 引脚,仅支持 TRAILING 模式,LEADING 模式不支持。
- SPI DMA 模式相对于非 DMA 模式,消耗 CPU 负载更低。
- 当 SPI 采用非 DMA 方式发送数据时,若系统负载比较大,会因为 SPI 中断响应不及时导致 SPI FIFO 未能及时写入,从而导致 CS 引脚短暂拉高,此时推荐采用 DMA 模式。
- 如果使用场景是多个 Sequence 使用同一个 SPI IP 进行异步传输,且 Sequence 之间并没有传输完成先后顺序,则会存在 Sequence 传输排队的现象,此时需要在 SchM_Spi.c 文件中实现关中断临界区保护。
代码路径
McalCdd/Spi/inc/Spi.h:SPI 驱动程序的头文件McalCdd/Spi/inc/Spi_Lld.h:SPI 底层驱动程序的头文件McalCdd/Spi/src/Spi.c:SPI 驱动程序的源文件McalCdd/Spi/src/Spi_Lld.c:SPI 底层驱动程序的源文件McalCdd/Common/Register/inc/Spi_Register.h:SPI 寄存器定义文件Platform/Schm/SchM_Spi.h:SPI 模块的调度管理头文件Config/McalCdd/gen_xxx/Spi/inc/Spi_Board.h:SPI 板级配置头文件Config/McalCdd/gen_xxx/Spi/inc/Spi_Cfg.h:SPI 配置头文件Config/McalCdd/gen_xxx/Spi/inc/Spi_PBcfg.h:SPI PB 配置头文件Config/McalCdd/gen_xxx/Spi/src/Spi_board.c:SPI 板级配置源文件Config/McalCdd/gen_xxx/Spi/src/Spi_PBcfg.c:SPI PB 配置源文件samples/Spi/SPI_sample/Spi_sample.c:SPI sample 代码samples/Spi/SPI_sample/Spi_common.c:SPI sample 代码
应用 sample
软件操作流程
一般的软件操作流程如下:
-
初始化
- 修改
ChannelCfgArrayPtr,JobCfgArrayPtr,SeqCfgArrayPtr,HwCfgPtr,PhyCfgPtr等配置结构体,将 SPI 对应 instance 配置为自己需要的波特率和传输模式,可参考 SPI 配置说明Spi 配置说明 - 调用
Spi_Init(&Spi_Config)或者Spi_Init(NULL),当传入为 NULL 时,使用Spi_PBcfg.c中的默认配置 - 驱动程序遍历 ,根据配置信息初始化内部数据结构(如
Spi_ChannelState,Spi_JobState,Spi_HwQueueArray等)和物理 SPI 硬件单元(根据Spi_PhyCfgType和Spi_IpCfg设置寄存器)
- 修改
-
设置传输模式:
- 应用程序通过
Spi_SetAsyncMode()选择使用中断模式还是轮询模式。
- 应用程序通过
-
数据准备:
- 应用程序通过
Spi_WriteIB()或Spi_SetupEB()函数将要发送的数据放入通道关联的缓冲区中。
- 应用程序通过
-
传输请求:
- 应用程序调用
Spi_AsyncTransmit(sequence)或Spi_SyncTransmit(sequence)来启动一个序列的传输。
- 应用程序调用
-
驱动处理:
- 驱动程序根据
sequence ID找到对应的Spi_SeqCfg - 根据
Spi_SeqCfg.JobIndexList获取作业列表。 - 对于序列中的每个作业:
- 根据
Spi_JobCfg.HWUnit确定要使用的物理 SPI 硬件单元。 - 根据
Spi_JobCfg.HwCfgPtr获取该作业对应的外部设备通信参数。 - 根据
Spi_JobCfg.ChannelIndexList获取通道列表。 - 遍历通道列表,从
Spi_ChannelCfg.BufferDescriptor指向的缓冲区中获取发送数据。 - 配置物理 SPI 硬件单元。
- 启动硬件传输。
- 驱动程序根据
-
传输完成:
- 对于异步传输,硬件完成传输后(通过中断或轮询检测),驱动程序会调用相应的通知函数
- 对于同步传输,函数会等待传输完成。
-
状态查询:
- 应用程序可以通过
Spi_GetJobResult(),Spi_GetSequenceResult()等函数查询传输状态。
- 应用程序可以通过
提示
- SPI 只需要在 INIT 之后配置一次
set_AsyncMode(),不需要反复调用,反复调用会导致传输异常。 - 当传输发生异常的时候,SPI 的状态机不会自动复位,需要手动调用
Spi_Cancel()函数复位传输状态机。 - Sample 里用了 DMA,但没进行初始化,这是因为在
Target/Target-hobot-lite-freertos-mcu1/target/HorizonTask.c文件中已经完成了初始化。
单片选使用示例
spi_test 命令用于测试 SPI(Serial Peripheral Interface,串行外设接口)功能。该命令支持初始化和参数设置、显示当前参数以及执行 SPI 数据传输测试。
命令语法
spi_test <operation> [bus_id] [sync_mode] [trans_mode]
参数说明
- operation: 指定要执行的操作。
- 0: 初始化和参数设置。
- 1: 显示当前设置的参数。
- 2: 执行 SPI 测试(异步或同步)。
- bus_id (仅当 operation 为 0 时需要): 指定要使用的 SPI 总线。
- 取值范围: 2 到 6,分别对应 SPI2 到 SPI6。
- sync_mode (仅当 operation 为 0 时需要): 指定 SPI 通信的同步模式。
- 0: 异步模式 (async)
- 1: 同步模式 (sync)
- trans_mode (仅当 operation 为 0 时需要): 指定 SPI 数据传输的底层机制。
- 0: 轮询模式 (polling)
- 1: 中断模式 (interrupt)
提示
应用层配置与底层配置应保持一致,否则会出现错误。
以 SPI3 为例,将 SPI3的 MISO 和 MOSI 短接,运行以下命令,设置传输参数
D-Robotics:/$ spi_test 0 3 0 0
[055.578172 0]Init&&Parameter setting
[055.578428 0]Show Spi parameter
[055.578792 0]spi_bus = 3
[055.579085 0]sync_mode = async
[055.579443 0]trans_mode = polling
运行以下命令,测试
D-Robotics:/$ spi_test 2
[059.643996 0]Sequence: 1, transfer_length = 128 spi_framesize = 16
[059.673978 0]
RxChBuf0 (256 bytes):
0CBD2A80: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | ................
0CBD2A90: 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F | ................
0CBD2AA0: 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F | !"#$%&'()*+,-./
0CBD2AB0: 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F | 0123456789:;<=>?
0CBD2AC0: 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F | @ABCDEFGHIJKLMNO
0CBD2AD0: 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F | PQRSTUVWXYZ[\]^_
0CBD2AE0: 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F | `abcdefghijklmno
0CBD2AF0: 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F | pqrstuvwxyz{|}~.
0CBD2B00: 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F | ................
0CBD2B10: 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F | ................
0CBD2B20: A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF | ................
0CBD2B30: B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF | ................
0CBD2B40: C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF | ................
0CBD2B50: D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF | ................
0CBD2B60: E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF | ................
0CBD2B70: F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF | ................
[059.687954 0]
TxChBuf0 (256 bytes):
0CBD2B80: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | ................
0CBD2B90: 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F | ................
0CBD2BA0: 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F | !"#$%&'()*+,-./
0CBD2BB0: 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F | 0123456789:;<=>?
0CBD2BC0: 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F | @ABCDEFGHIJKLMNO
0CBD2BD0: 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F | PQRSTUVWXYZ[\]^_
0CBD2BE0: 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F | `abcdefghijklmno
0CBD2BF0: 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F | pqrstuvwxyz{|}~.
0CBD2C00: 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F | ................
0CBD2C10: 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F | ................
0CBD2C20: A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF | ................
0CBD2C30: B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF | ................
0CBD2C40: C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF | ................
0CBD2C50: D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF | ................
0CBD2C60: E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF | ................
0CBD2C70: F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF | ................
[059.702104 0]=====SPI ASYNC TEST SUCCESS=====