You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ESP32与CERES PCB SPI从机通信故障排查求助

CERES PCB(SPI从机)与ESP32通信问题排查与解决

问题背景

我有一块CERES PCB,需要将其作为SPI从机与ESP32通信。我对通信协议了解有限,已完成单条数据传输的SPI代码练习,但实际项目中对地址、MOSI的命令+地址格式存在困惑,不清楚需要发送哪些数据及发送方式,调试始终得到无效数据。

命令参考

Command Reference
Command List

当前代码

#include <SPI.h>

// SPI pins
#define SCK 18
#define MISO 19
#define MOSI 23
#define SS 5

// SPI settings 
const int responseSize = 4;  

void setup() {
  Serial.begin(115200);
  pinMode(SS, OUTPUT);
  SPI.begin(SCK, MISO, MOSI, SS);
  
  SPI.beginTransaction(SPISettings(20000000, MSBFIRST, SPI_MODE0));
  
  byte commandSelAdc2Vdd[] = {0x21, 0x40, 0x84, 0x00, 0x00, 0x02, 0x00};
  byte commandEnAcd2[] = {0x09, 0x40, 0x24, 0x00, 0x20, 0x00, 0x00};
  byte commandReadAcd2[] = {0x05, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00};

  byte* commands[] = {commandSelAdc2Vdd, commandEnAcd2, commandReadAcd2};

  for (int i = 0; i < 3; i++) {

    digitalWrite(SS, LOW);

    SPI.transfer(commands[i], sizeof(commandSelAdc2Vdd)); 

    digitalWrite(SS, HIGH);
    delay(100);
    digitalWrite(SS, LOW); 

    byte response[4]; 
    SPI.transfer(response, sizeof(response)); 
    digitalWrite(SS, HIGH); 

    Serial.print("Response for ");
    if (i == 0) 
    {
      Serial.print("commandSelAdc2Vdd: ");
    } else if (i == 1) 
    {
      Serial.print("commandEnAcd2: ");
    }else{
      Serial.print ("commandReadAcd2: ");
    }
    for (int j = 0; j < 4; j++) {
      Serial.print(response[j],HEX);
      Serial.print(" ");
    }
    Serial.println();
    delay(500);
  }
}

void loop() {

}

问题排查与解决建议

1. 核心逻辑错误:SPI传输方式误用

SPI是全双工同步总线,主机发送数据的同时从机就会回传数据,不需要分两次拉低SS。你当前先发送命令、拉高SS,再拉低SS读响应的操作,会导致从机的响应数据丢失,读取到的是无效的空数据。

正确流程应该是:

  • 拉低SS(选中从机)
  • 发送命令的同时,同步读取从机返回的所有响应字节
  • 拉高SS(释放从机)

2. 命令长度的潜在问题

你用sizeof(commandSelAdc2Vdd)作为所有命令的传输长度,虽然当前三个命令都是7字节,暂时没问题,但后续修改命令长度时会出错。建议改为sizeof(commands[i])或者定义固定的命令长度常量。

3. 命令格式与地址校验

结合你提供的命令参考图,必须逐一核对:

  • 功能码(第一个字节):确认0x21(配置ADC通道)、0x09(使能ADC)、0x05(读数据)是否与CERES手册完全匹配。
  • 寄存器地址:比如ADC2的配置地址是否为0x4084、使能地址是否为0x4024、读数据地址是否为0x0014,地址错误会直接导致无效响应。
  • 控制/校验位:命令末尾的字节(比如commandSelAdc2Vdd的0x02、0x00)是否符合手册中的格式要求,部分设备会有校验位或参数位,错误会导致命令被拒绝。

4. SPI参数适配

  • 时钟速率:你设置的20MHz可能超出CERES PCB的SPI速率上限,建议先降到1MHz测试,确认通信正常后再逐步调高。
  • SPI模式:ESP32用的是SPI_MODE0(CPOL=0,CPHA=0),必须确保CERES的SPI模式与之一致,模式不匹配会导致数据采样错误。

修改后的示例代码

#include <SPI.h>

// SPI pins
#define SCK 18
#define MISO 19
#define MOSI 23
#define SS 5

const int CMD_LENGTH = 7;       // 命令固定为7字节
const int READ_RESP_LENGTH = 4; // 读命令有效响应长度

void setup() {
  Serial.begin(115200);
  pinMode(SS, OUTPUT);
  digitalWrite(SS, HIGH); // 初始状态SS拉高,不选中从机
  SPI.begin(SCK, MISO, MOSI, SS);
  
  // 先以低速率测试,确认兼容性
  SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
  
  // 执行配置命令(写操作)
  runWriteCmd((byte[]){0x21, 0x40, 0x84, 0x00, 0x00, 0x02, 0x00}, "SelAdc2Vdd");
  delay(100);
  runWriteCmd((byte[]){0x09, 0x40, 0x24, 0x00, 0x20, 0x00, 0x00}, "EnAdc2");
  delay(100);
  
  // 执行读命令,获取有效数据
  byte resp[READ_RESP_LENGTH];
  runReadCmd((byte[]){0x05, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00}, resp, "ReadAdc2");

  SPI.endTransaction();
}

void loop() {
  // 循环读取ADC数据
  byte resp[READ_RESP_LENGTH];
  runReadCmd((byte[]){0x05, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00}, resp, "ReadAdc2");
  delay(500);
}

// 执行写命令:发送命令,忽略响应
void runWriteCmd(byte cmd[], const char* cmdName) {
  digitalWrite(SS, LOW);
  byte dummy[CMD_LENGTH];
  SPI.transfer(cmd, dummy, CMD_LENGTH); // 发送命令,同步读取(丢弃响应)
  digitalWrite(SS, HIGH);
  
  Serial.print(cmdName);
  Serial.println(" command executed");
}

// 执行读命令:发送命令,同步读取响应并提取有效部分
void runReadCmd(byte cmd[], byte resp[], const char* cmdName) {
  digitalWrite(SS, LOW);
  byte fullResp[CMD_LENGTH];
  SPI.transfer(cmd, fullResp, CMD_LENGTH); // 发送命令的同时读取完整响应
  digitalWrite(SS, HIGH);
  
  // 提取最后4字节作为有效响应(根据手册调整起始位置)
  memcpy(resp, &fullResp[CMD_LENGTH - READ_RESP_LENGTH], READ_RESP_LENGTH);
  
  Serial.print("Response for ");
  Serial.print(cmdName);
  Serial.print(": ");
  for (int i = 0; i < READ_RESP_LENGTH; i++) {
    Serial.print(resp[i], HEX);
    Serial.print(" ");
  }
  Serial.println();
}

内容的提问来源于stack exchange,提问作者hisyamuddin hamzaini

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 09:42:34