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

ESP32-S3开发板C++环境下NAFE13388通道选择与数据读写异常问题排查

ESP32-S3开发板C++环境下NAFE13388通道选择与数据读写异常问题排查

我刚接触编程不久,最近在ESP32-S3上调试NAFE13388芯片时遇到了通道选择和数据读写的异常问题,想请大家帮忙看看哪里出了问题。

参考依据

我主要参考了芯片 datasheet 的第71-75页内容,同时也借鉴了一些现成的代码来编写配置逻辑。

核心配置代码

我是通过设置指针(SETPOINTER0/SETPOINTER1)来切换通道配置的,以下是初始化时的配置代码:

// 配置指针0对应的通道
writeNAFE16b(0x30, 0x8020, CS_AFE); //SYS_CONFIG0
writeNAFE16b(0x32, 0x0000, CS_AFE); //GLOBALARMENABLE
writeNAFE16b(0x00, 0x0000, CS_AFE); //CMD_SETPOINTER0
//sendCommand16(0x0000);
writeNAFE16b(0x20, 0x11F1, CS_AFE); //CH_CONFIG0
writeNAFE16b(0x21, 0x909B, CS_AFE); //CH_CONFIG1
writeNAFE16b(0x22, 0x4400, CS_AFE); //CH_CONFIG2
writeNAFE16b(0x23, 0xAC10, CS_AFE); //CH_CONFIG3

// 配置指针1对应的通道
writeNAFE16b(0x01, 0x0000, CS_AFE); //CMD_SETPOINTER1
//sendCommand16(0x0001);
writeNAFE16b(0x20, 0x71F1, CS_AFE); //CH_CONFIG0
writeNAFE16b(0x21, 0x909B, CS_AFE); //CH_CONFIG1
writeNAFE16b(0x22, 0x4400, CS_AFE); //CH_CONFIG2
writeNAFE16b(0x23, 0xAC10, CS_AFE); //CH_CONFIG3
writeNAFE16b(0x24, 0x0003, CS_AFE); //CH_CONFIG4

数据读取逻辑

当DRDY引脚触发中断后,我会按以下逻辑读取两个通道的数据:

volatile bool newDataAvailable = false;
volatile int32_t latestRaw1Value = 0;
volatile int32_t latestRaw2Value = 0;

// DRDY中断回调
void IRAM_ATTR dataReady() {
    newDataAvailable = true;
}

// 数据读取逻辑
if (newDataAvailable){
    newDataAvailable = false;
    // 读取指针0对应通道的数据
    writeNAFE16b(0x00, 0x0000, CS_AFE); //CMD_SETPOINTER0
    //sendCommand16(0x0000);
    delayMicroseconds(5);
    int32_t raw1 = readNAFE24b(0x40,CS_AFE);//read channel 0
    // 24位负数符号扩展
    if (raw1 & 0x800000) {
        raw1 |= 0xFF000000;
    }
    latestRaw1Value = raw1; // Save the result

    // 读取指针1对应通道的数据
    writeNAFE16b(0x01, 0x0000, CS_AFE); //CMD_SETPOINTER1
    //sendCommand16(0x0001);
    delayMicroseconds(5);
    int32_t raw2 = readNAFE24b(0x41,CS_AFE);//read channel 1
    // 24位负数符号扩展
    if (raw2 & 0x800000) {
        raw2 |= 0xFF000000;
    }
    latestRaw2Value = raw2; // Save the result
}

遇到的问题

  • 指针切换的逻辑偶尔能生效,但在特定场景下完全失效,有时能明显读到错误寄存器的数据
  • 我尝试过把writeNAFE16b()替换为注释掉的sendCommand16()函数,但问题依然存在
  • 打印寄存器值时发现:一开始pointer1的寄存器值和旧代码一致,注释掉pointer0的配置代码后,几次上传后pointer1的配置才正常;但重新读取所有寄存器时,只有pointer1对应的寄存器值能被正确读回,pointer0的完全读不出来

已尝试的排查动作

  • 切换使用writeNAFE16b()和sendCommand16()两种指令发送方式
  • 注释部分配置代码,观察寄存器值的变化
  • 增加delayMicroseconds(5)确保指令执行完成

最小可复现示例(含依赖)

以下是我整理的最小可复现代码,需要搭配PT100和NAFE13388使用,注:代码末尾有截断:

#include <SPIFFS.h> //to store HTML on flash memory
#include <SPI.h>
#include <cmath>

constexpr uint8_t SPI_MOSI = 11; //6;
constexpr uint8_t SPI_MISO = 13; //5;
constexpr uint8_t SPI_SCK = 12; //4;
constexpr uint8_t CS_AFE = 10; //19;
constexpr uint8_t DRDY = 21;
constexpr uint8_t SYNC = 47; //should be 22; for real thing

#define SPI_CMD_WORD(addr, cmd, dir) (((addr & 0x01) << 15) | (cmd << 1) | (dir<<14))
#define HIGH_BYTE(word) (((word) >> 8) & 0xFF)
#define LOW_BYTE(word) ((word) & 0xFF)

float GAIN = 16;
const float VREF = 10;
volatile int32_t latestRaw1Value = 0;
volatile int32_t latestRaw2Value = 0;
volatile bool newDataAvailable = false; // Flag for new data read
const float IREF = 0.000509; //checked using multimeter

//An interrupt function, means data is ready to be sent from AFE
void IRAM_ATTR dataReady() {
  newDataAvailable = true;
}

void sendCommand16(uint16_t cmd) {
  SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE1));
  digitalWrite(CS_AFE, LOW);
  SPI.transfer((cmd >> 8) & 0xFF); // high byte first
  SPI.transfer(cmd & 0xFF); // low byte
  digitalWrite(CS_AFE, HIGH);
  SPI.endTransaction();
}

void writeNAFE16b(uint16_t reg, uint16_t value, uint8_t cs_pin) {
  uint16_t word = SPI_CMD_WORD(0, reg, 0);
  SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE1));
  digitalWrite(cs_pin, LOW);
  SPI.transfer(HIGH_BYTE(word));
  SPI.transfer(LOW_BYTE(word));
  SPI.transfer(HIGH_BYTE(value));
  SPI.transfer(LOW_BYTE(value));
  digitalWrite(cs_pin, HIGH);
  SPI.endTransaction();
}

int32_t readNAFE24b(uint16_t reg, uint8_t cs_pin) {
  uint16_t word = SPI_CMD_WORD(0, reg, 1);
  SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE1));
  digitalWrite(cs_pin, LOW);
  SPI.transfer(HIGH_BYTE(word));
  SPI.transfer(LOW_BYTE(word));
  uint8_t high_value = SPI.transfer(0x00);
  uin... // 代码此处截断

我怀疑自己在指针选择的逻辑上有根本性错误,只是偶尔蒙对了才让配置有时生效。如果需要补充其他信息,请随时告诉我!

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 08:49:33