SPI Slave Receiver 示例
示例说明
本示例展示了在 ESP-IDF 中如何使用 SPI 从机驱动接收主机发起的事务,并在事务过程中同时向主机返回数据。
运行方法
该示例需要与 Sender 示例 配合使用,两者分别烧录到两块 ESP32 系列芯片,并正确连接信号线,从而实现完整的数据交换。Receiver 在通信中配置为 SPI 从机,被动等待 Sender(SPI 主机)发起传输,并通过握手信号告知主机自身已准备好,从而保证数据传输的正确性与同步性。有关 SPI 从机模式的说明可参考 SPI 从机驱动程序。
示例完整代码见 SPI Slave Receiver 示例。运行前的配置说明、对应 GPIO 引脚、构建与烧录流程详见 spi_slave
目录下的 README.md 文件。
如需自定义配置项及查看默认值,可参考 宏定义说明 部分。
头文件说明
本示例所使用的头文件涵盖了 FreeRTOS 任务管理、日志输出、SPI 驱动以及 GPIO 控制等基础模块。为 SPI 从机初始化、数据传输和任务调度提供支持。
各头文件按功能分类如下:
FreeRTOS 任务调度 :提供任务创建与调度功能。
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
系统工具 :提供标准输入输出、数据类型定义以及日志输出功能。
#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include "esp_log.h"
SPI 从机驱动 :提供 SPI 从机模式的初始化、数据发送与接收功能。
#include "driver/spi_slave.h"
GPIO 控制 :提供 GPIO 引脚配置及电平控制功能。
#include "driver/gpio.h"
宏定义说明
本示例中涉及的宏定义主要用于配置 SPI 外设的引脚、控制器选择以及握手信号引脚,便于后续 SPI 数据传输和任务调度。
宏定义按功能分类如下:
SPI 从机配置
定义 SPI 从机所使用的主机接口,本示例使用
SPI2_HOST
,即 SPI2 外设。#define RCV_HOST SPI2_HOST
定义 SPI 的关键引脚,包括握手、数据输入/输出、时钟以及片选引脚。
#define GPIO_HANDSHAKE 2 // 握手信号 #define GPIO_MOSI 12 // 主机输出,从机输入 #define GPIO_MISO 13 // 主机输入,从机输出 #define GPIO_SCLK 15 // SPI 时钟 #define GPIO_CS 14 // 片选信号
备注
握手引脚用于主机与从机的数据同步控制,可根据硬件设计选择合适 GPIO。
片选引脚用于选择 SPI 从机,保证总线上多从机的正确通信。
任务函数说明
本示例定义了两个 SPI 从机回调函数,用于控制握手引脚的电平,实现主机与从机之间的数据同步。
void my_post_setup_cb(spi_slave_transaction_t *trans);
void my_post_trans_cb(spi_slave_transaction_t *trans);
传入参数 |
参数功能 |
参数说明 |
---|---|---|
|
指向 SPI 事务结构体的指针,包含本次传输的缓冲区、长度等信息。 |
传入有效指针,用于访问本次 SPI 事务信息。 |
备注
在本示例中,并未对传参内容进行访问或修改,仅用于满足 SPI 从机回调函数的函数原型要求。
my_post_setup_cb()
:事务开始前调用,拉高 握手引脚电平,以通知主机从机准备完成。my_post_trans_cb()
:事务完成后调用,拉低 握手引脚电平,以通知主机数据传输结束。
以上函数均通过调用 gpio_set_level()
执行,传入 1 实现拉高电平,传入 0 实现拉低电平。进一步介绍及参数说明可参考 普通 GPIO API。
主函数说明
本示例演示了 SPI 从机的初始化、与主机建立通信并完成数据传输的过程。
定义变量:
定义变量
n
用于记录当前 SPI 事务的序号,便于区分每次发送的数据。定义返回值变量
ret
用于保存 SPI 外设相关函数的返回状态,判断操作是否成功,并可根据返回值进行错误处理或打印提示信息。
配置握手信号 GPIO:在 SPI 从机与主机通信中,为了实现可靠的数据传输,通常会使用一个握手信号(handshake line)来通知主机从机已准备好发送或接收数据。
启用信号线上拉电阻:为 SPI 总线的关键信号线启用上拉电阻,以保证在没有主机驱动信号时线路保持高电平,避免出现悬空或毛刺信号。
调用
gpio_set_pull_mode()
启用信号线上拉电阻,进一步介绍及参数说明可参考 普通 GPIO API:
GPIO_MOSI
上拉,防止因线路悬空导致的误触发或噪声干扰。
GPIO_SCLK
上拉,确保在主机未驱动时,时钟线保持高电平,避免从机错误识别时钟脉冲。
GPIO_CS
上拉,保证在没有主机选中从机时,CS 保持高电平,从机处于非激活状态,防止意外通信。
分配 DMA 内存缓冲区:允许 SPI 外设直接访问内存,不经过 CPU 中转,提高数据传输效率,同时可减少 CPU 占用,适合大数据量或高频率传输场景。
定义变量
sendbuf
用作发送数据缓冲区。定义变量
recvbuf
用作接收数据缓冲区。定义后需调用
spi_bus_dma_memory_alloc()
为缓冲区分配 DMA 支持的内存,以保证 SPI 外设能够高效、直接地进行数据传输。进一步介绍及参数说明可参考 SPI 主机驱动 API。如果分配失败则终止程序。
定义 SPI 事务结构体
t
。初始化缓冲区:
初始化接收数据缓冲区
recvbuf
为0xA5
以便调试。填入数据至发送缓冲区
sendbuf
,其中包含当前传输序号。备注
将接收缓冲区初始化为
0xA5
这种明显的占位值可以清楚区分未接收的数据和有效传输数据,便于快速发现传输异常。
事务完成后,
recvbuf
中保存主机发送的数据,sendbuf
中的数据发送给主机。
打印接收数据:将从机收到的数据输出到控制台。