SPI Slave Receiver 示例

[English]

示例说明

本示例展示了在 ESP-IDF 中如何使用 SPI 从机驱动接收主机发起的事务,并在事务过程中同时向主机返回数据。

运行方法

该示例需要与 Sender 示例 配合使用,两者分别烧录到两块 ESP32 系列芯片,并正确连接信号线,从而实现完整的数据交换。Receiver 在通信中配置为 SPI 从机,被动等待 Sender(SPI 主机)发起传输,并通过握手信号告知主机自身已准备好,从而保证数据传输的正确性与同步性。有关 SPI 从机模式的说明可参考 SPI 从机驱动程序

示例完整代码见 SPI Slave Receiver 示例。运行前的配置说明、对应 GPIO 引脚、构建与烧录流程详见 spi_slave 目录下的 README.md 文件。

如需自定义配置项及查看默认值,可参考 宏定义说明 部分。

头文件说明

本示例所使用的头文件涵盖了 FreeRTOS 任务管理、日志输出、SPI 驱动以及 GPIO 控制等基础模块。为 SPI 从机初始化、数据传输和任务调度提供支持。

各头文件按功能分类如下:

  1. FreeRTOS 任务调度 :提供任务创建与调度功能。

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
  1. 系统工具 :提供标准输入输出、数据类型定义以及日志输出功能。

#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include "esp_log.h"
  1. SPI 从机驱动 :提供 SPI 从机模式的初始化、数据发送与接收功能。

#include "driver/spi_slave.h"
  1. GPIO 控制 :提供 GPIO 引脚配置及电平控制功能。

#include "driver/gpio.h"

宏定义说明

本示例中涉及的宏定义主要用于配置 SPI 外设的引脚、控制器选择以及握手信号引脚,便于后续 SPI 数据传输和任务调度。

宏定义按功能分类如下:

  1. 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);
参数解释

传入参数

参数功能

参数说明

trans

指向 SPI 事务结构体的指针,包含本次传输的缓冲区、长度等信息。

传入有效指针,用于访问本次 SPI 事务信息。

备注

在本示例中,并未对传参内容进行访问或修改,仅用于满足 SPI 从机回调函数的函数原型要求。

  • my_post_setup_cb():事务开始前调用,拉高 握手引脚电平,以通知主机从机准备完成。

  • my_post_trans_cb():事务完成后调用,拉低 握手引脚电平,以通知主机数据传输结束。

以上函数均通过调用 gpio_set_level() 执行,传入 1 实现拉高电平,传入 0 实现拉低电平。进一步介绍及参数说明可参考 普通 GPIO API

主函数说明

本示例演示了 SPI 从机的初始化、与主机建立通信并完成数据传输的过程。

  1. 定义变量:

  • 定义变量 n 用于记录当前 SPI 事务的序号,便于区分每次发送的数据。

  • 定义返回值变量 ret 用于保存 SPI 外设相关函数的返回状态,判断操作是否成功,并可根据返回值进行错误处理或打印提示信息。

  1. 配置 SPI 总线

  2. 配置/初始化 SPI 从机接口

  3. 配置握手信号 GPIO:在 SPI 从机与主机通信中,为了实现可靠的数据传输,通常会使用一个握手信号(handshake line)来通知主机从机已准备好发送或接收数据。

  1. 启用信号线上拉电阻:为 SPI 总线的关键信号线启用上拉电阻,以保证在没有主机驱动信号时线路保持高电平,避免出现悬空或毛刺信号。

  • 调用 gpio_set_pull_mode() 启用信号线上拉电阻,进一步介绍及参数说明可参考 普通 GPIO API

    • GPIO_MOSI 上拉,防止因线路悬空导致的误触发或噪声干扰。

    • GPIO_SCLK 上拉,确保在主机未驱动时,时钟线保持高电平,避免从机错误识别时钟脉冲。

    • GPIO_CS 上拉,保证在没有主机选中从机时,CS 保持高电平,从机处于非激活状态,防止意外通信。

  1. 分配 DMA 内存缓冲区:允许 SPI 外设直接访问内存,不经过 CPU 中转,提高数据传输效率,同时可减少 CPU 占用,适合大数据量或高频率传输场景。

  • 定义变量 sendbuf 用作发送数据缓冲区。

  • 定义变量 recvbuf 用作接收数据缓冲区。

  • 定义后需调用 spi_bus_dma_memory_alloc() 为缓冲区分配 DMA 支持的内存,以保证 SPI 外设能够高效、直接地进行数据传输。进一步介绍及参数说明可参考 SPI 主机驱动 API

  • 如果分配失败则终止程序。

  1. 定义 SPI 事务结构体 t

  2. 初始化缓冲区:

  • 初始化接收数据缓冲区 recvbuf0xA5 以便调试。

  • 填入数据至发送缓冲区 sendbuf,其中包含当前传输序号。

备注

将接收缓冲区初始化为 0xA5 这种明显的占位值可以清楚区分未接收的数据和有效传输数据,便于快速发现传输异常。

  1. 设置事务信息并执行

  • 事务完成后,recvbuf 中保存主机发送的数据,sendbuf 中的数据发送给主机。

  1. 打印接收数据:将从机收到的数据输出到控制台。

  2. 暂停后重启从机