要确定 ESP32-S3 与 SDNAND 的 SPI 连接是否成功,需要从硬件连通性、驱动初始化和功能验证三个层面逐步排查。以下是系统化的验证方法:
在代码中添加以下测试函数,通过 SPI 发送简单命令并读取响应:
#include "driver/spi_master.h"#include "esp_log.h"#define SDNAND_HOST SPI2_HOST#define PIN_NUM_CS 12esp_err_t test_spi_connection(void){ esp_err_t ret; spi_device_handle_t handle; spi_transaction_t trans = {0}; // 配置SPI设备 spi_device_interface_config_t devcfg = { .clock_speed_hz = 1 * 1000 * 1000, // 降低时钟频率便于调试 .mode = 0, .spics_io_num = PIN_NUM_CS, .queue_size = 1, }; // 添加设备到SPI总线 ret = spi_bus_add_device(SDNAND_HOST, &devcfg, &handle); if (ret != ESP_OK) { ESP_LOGE("SPI", "添加设备失败: %d", ret); return ret; } // 发送测试命令(如0x00)并接收响应 uint8_t cmd = 0x00; uint8_t resp = 0; trans.tx_buffer = &cmd; trans.rx_buffer = &resp; trans.length = 8; // 8位 ret = spi_device_transmit(handle, &trans); if (ret != ESP_OK) { ESP_LOGE("SPI", "传输失败: %d", ret); return ret; } ESP_LOGI("SPI", "测试命令发送成功,响应: 0x%02X", resp); // 移除设备 spi_bus_remove_device(handle); return ESP_OK;}
发送 SDNAND 的标准命令(如读取 ID),检查响应是否符合芯片规格:
esp_err_t test_sdnand_id(void){ esp_err_t ret; spi_device_handle_t handle; spi_transaction_t trans = {0}; uint8_t id[5] = {0}; // 配置SPI设备(同上) // ... // 发送读取ID命令 (0x9F) uint8_t cmd = 0x9F; // 第一阶段:发送命令 trans.tx_buffer = &cmd; trans.length = 8; ret = spi_device_transmit(handle, &trans); if (ret != ESP_OK) return ret; // 第二阶段:接收ID数据(通常5字节) trans.tx_buffer = NULL; // 不再发送数据 trans.rx_buffer = id; trans.length = 5 * 8; // 5字节 ret = spi_device_transmit(handle, &trans); if (ret != ESP_OK) return ret; // 验证ID是否符合SDNAND规格 if (id[0] == 0xEF && id[1] == 0xAA) { // 示例:Winbond芯片ID前缀 ESP_LOGI("SDNAND", "ID验证成功: %02X %02X %02X %02X %02X", id[0], id[1], id[2], id[3], id[4]); return ESP_OK; } else { ESP_LOGE("SDNAND", "ID验证失败: %02X %02X %02X %02X %02X", id[0], id[1], id[2], id[3], id[4]); return ESP_FAIL; }}
信号 | 正常特征 | 异常情况及可能原因 |
---|---|---|
CLK | 频率稳定(如 1MHz),占空比 50%,边沿陡峭(上升 / 下降时间 < 50ns) | 无波形→SPI 总线未初始化;频率错误→时钟配置错误;边沿过缓→上拉 / 下拉电阻不合适或负载过大 |
CS | 命令期间保持低电平,通信结束后拉高 | 提前拉高→软件时序错误;未拉低→片选引脚配置错误 |
MOSI | 发送 0x9F 命令字节,后跟 32 位地址(通常全 0) | 无数据→SPI 主机发送故障;数据错误→发送缓冲区未正确填充 |
MISO | 在命令发送后,返回芯片 ID(如 Winbond 为 0xEF AA XX XX XX) | 无响应→SDNAND 未工作(可能供电 / 复位问题);乱码→SPI 模式(CPOL/CPHA)不匹配或信号干扰 |
通过以上步骤,可逐步定位 SPI 连接失败的具体原因(如硬件断路、驱动配置错误或协议时序不匹配)。