This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] ADS1298:SPI 未读取

Guru**** 2668435 points

Other Parts Discussed in Thread: ADS1298

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/data-converters-group/data-converters/f/data-converters-forum/1573724/ads1298-spi-not-reading

器件型号:ADS1298


工具/软件:

我不断为所有寄存器读取获得 0x00。ADS1298 连接到 STM32WB55 板、DRDY 引脚每次保持高电平。 它从未停止、但我也没有在 SPI 事务上收到任何错误。
SPI 配置:
数据大小 8 位
MSB 优先
预分频器–128、波特率–250kb/s
CPOL — 低
CPHA - 1 边沿

代码:
ADS1298.c:

#include "ads1298.h"

#include "main.h" // For hspi1

#include <stdio.h>



// External SPI handle

extern SPI_HandleTypeDef hspi1;



// Send SPI command

static void ADS1298_SendCommand(uint8_t cmd)

{

 uint8_t rx[1] = {0};

 ADS1298_CS_LOW();

 HAL_Delay(1); // Ensure 2 µs minimum (t_SDECODE)

 HAL_StatusTypeDef status = HAL_SPI_TransmitReceive(&hspi1, &cmd, rx, 1, 1000);

 ADS1298_CS_HIGH();

 HAL_Delay(1); // Wait 4 t_CLK (~2 µs) before next command

 printf("Command 0x%02X sent, RX: 0x%02X, Status: %d, Error: %ld\r\n", cmd, rx[0], status, HAL_SPI_GetError(&hspi1));

}



// Write register

void ADS1298_WriteRegister(uint8_t reg, uint8_t val)

{

 ADS1298_CS_LOW();

 HAL_Delay(1); // Ensure 2 µs minimum

 HAL_SPI_Transmit(&hspi1, (uint8_t[]){ADS_WREG | reg, 0x00, val}, 3, 1000); // Single register write

 ADS1298_CS_HIGH();

 HAL_Delay(1); // Wait 4 t_CLK (~2 µs)

 printf("Wrote Reg 0x%02X with 0x%02X\r\n", reg, val);

}



// Read register

uint8_t ADS1298_ReadRegister(uint8_t reg)

{

 uint8_t rx[3] = {0};

 ADS1298_CS_LOW();

 HAL_Delay(1); // Ensure 2 µs minimum

 HAL_SPI_Transmit(&hspi1, (uint8_t[]){ADS_RREG | reg, 0x00, 0xFF}, 3, 1000); // Read one register

 ADS1298_CS_HIGH();

 HAL_Delay(1); // Wait 4 t_CLK (~2 µs)

 printf("Read Reg 0x%02X: RX: 0x%02X 0x%02X 0x%02X, Value: 0x%02X\r\n",

 reg, rx[0], rx[1], rx[2], rx[2]);

 return rx[2];

}



// In ADS1298_Init

void ADS1298_Init(void)

{

 printf("ADS1298 Initialization Started\r\n");



 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET); // PWDN HIGH

 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET); // RESET LOW

 HAL_Delay(1); // 1 µs

 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET); // RESET HIGH

 printf("RESET Applied\r\n");



 HAL_Delay(100); // Reduced from 1000 ms for testing

 printf("Post-RESET Delay Complete\r\n");



 ADS1298_SendCommand(ADS_RESET); // Software reset

 HAL_Delay(1); // 1 ms

 printf("SPI RESET Sent\r\n");



 ADS1298_SendCommand(ADS_SDATAC); // Stop continuous mode

 HAL_Delay(1); // 1 ms

 printf("SDATAC Sent\r\n");



 uint8_t id = ADS1298_ReadRegister(ADS_REG_ID);

 uint8_t config2 = ADS1298_ReadRegister(ADS_REG_CONFIG2);

 int channels = 0;

 switch (id & 0x1F) {

 case 0x10: channels = 4; break;

 case 0x11: channels = 6; break;

 case 0x12: channels = 8; break;

 case 0x1E: channels = 8; break;

 default: channels = 0;

 }

 printf("Device ID: 0x%02X, Channels: %d, CONFIG2: 0x%02X\r\n", id, channels, config2);





 ADS1298_SendCommand(ADS_START);

 HAL_Delay(1); // 1 ms

 printf("START Sent\r\n");



 if (ADS1298_DRDY() == GPIO_PIN_SET) {

 printf("DRDY is HIGH (device may not be ready)\r\n");

 } else {

 printf("DRDY is LOW (device ready)\r\n");

 }



 printf("ADS1298 Initialization Complete\r\n");

}






ads1298.h:

#ifndef APPLICATION_USER_STM32_WPAN_APP_ADS1298_H_

#define APPLICATION_USER_STM32_WPAN_APP_ADS1298_H_



#include "stm32wbxx_hal.h"

#include <stdio.h>



// ADS1298 SPI commands

#define ADS_WAKEUP 0x02

#define ADS_STANDBY 0x04

#define ADS_RESET 0x06

#define ADS_START 0x08

#define ADS_STOP 0x0A

#define ADS_RDATAC 0x10

#define ADS_SDATAC 0x11

#define ADS_RDATA 0x12

#define ADS_RREG 0x20

#define ADS_WREG 0x40



// ADS1298 Register Addresses (only relevant ones for now)

#define ADS_REG_ID 0x00

#define ADS_REG_CONFIG2 0x02



// Pin definitions

#define ADS1298_CS_LOW() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET) // PA4

#define ADS1298_CS_HIGH() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET)

#define ADS1298_START_HIGH() HAL_GPIO_WritePin(GPIOE, GPIO_PIN_4, GPIO_PIN_SET) // PE4

#define ADS1298_START_LOW() HAL_GPIO_WritePin(GPIOE, GPIO_PIN_4, GPIO_PIN_RESET)

#define ADS1298_DRDY() HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_15) // PA15



// Functions

void ADS1298_Init(void);

void StartEcgPrintTask(void *argument);

uint8_t ADS1298_ReadRegister(uint8_t reg);

void ADS1298_WriteRegister(uint8_t reg, uint8_t val);



#endif /* APPLICATION_USER_STM32_WPAN_APP_ADS1298_H_ */

“你怎么来了?“


  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Naveen:

    感谢您发送编修。

    您是否遵循第 10.1 节中推荐的初始化序列?  第 11 节还介绍了电源斜升和上电复位、建议使用这两个步骤以确保正确初始化 ADS1298。  

    为了读取/写入寄存器、您首先需要发送 SDATAC 命令。

    对于多字节事务、有必要在整个 SPI 帧中将/CS 保持为低电平。

    此致、

    Ryan

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    void ADS1298_Init(void)
    {
        printf("ADS1298 Initialization Started\r\n");
    
        // Power-On Reset Sequence
        ADS1298_PWDN_LOW();    // PWDN low during power-up
        HAL_Delay(100);        // Allow power stabilization
        ADS1298_PWDN_HIGH();   // PWDN high
        HAL_Delay(100);        // Transition time
    
        ADS1298_RESET_LOW();   // RESET low
        HAL_Delay(10);         // 10 ms > 0.976 µs
        ADS1298_RESET_HIGH();  // RESET high
        HAL_Delay(1000);       // ≥1s for oscillator stabilization
    
        printf("Power-On and RESET Sequence Complete\r\n");
    
        // Verify SPI
        if (hspi1.State != HAL_SPI_STATE_READY) {
            printf("SPI not ready, State: %d\r\n", hspi1.State);
            return;
        }
        printf("SPI initialized correctly\r\n");
    
        // Check control pin states
        printf("PWDN: %d, RESET: %d, START: %d, DRDY: %d\n",
               HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7),
               HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6),
               HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_4),
               ADS1298_DRDY());
    
        // Send SDATAC to stop read-continuous mode
        uint8_t sdatac_response = ADS1298_SendCommand(ADS1298_CMD_SDATAC);
        printf("SDATAC Response: 0x%02X\r\n", sdatac_response);
        HAL_Delay(10);
    
        // Configure CONFIG1 (example: 250 SPS)
        uint8_t config1[] = {ADS1298_CMD_WREG | ADS1298_REG_CONFIG1, 0x00, 0x00}; // 250 SPS
        ADS1298_CS_LOW();
        HAL_SPI_Transmit(&hspi1, config1, 3, 1000);
        ADS1298_CS_HIGH();
        HAL_Delay(10);
    
        // Set START pin and send START command
        if (HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_4) != GPIO_PIN_SET) {
            ADS1298_START_HIGH();
            printf("START forced HIGH\r\n");
        }
        uint8_t start_response = ADS1298_SendCommand(ADS1298_CMD_START);
        printf("START Response: 0x%02X, DRDY: %d\n", start_response, ADS1298_DRDY());
        HAL_Delay(100);
    
        // Verify initialization
        ADS1298_ReadID();
        ADS1298_ReadConfig1();
        ADS1298_ReadConfig2();
        printf("ADS1298 Initialization Complete\r\n");
    }




    这是我的初始化代码。 希望这遵循顺序。 SPI 仍然读取 0x00.. 应该检查 ADS1298 的电源吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Ryan Andrews 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Naveen — 您是否能够读取任何器件寄存器? 尝试读取 ID 寄存器或任何非零默认值的地址。

    此致、

    Ryan

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Ryan Andrews No 当我尝试读取寄存器 00h 这是为了读取 ID。 我得到 0x00 作为响应

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Naveen:

    您是否还可以尝试按照此 E2E 常见问题解答中概述的建议调试步骤进行操作:  

    (+)【常见问题解答】ADS129x:如何验证 ADS129x 器件是否仍然正常工作? -数据转换器论坛 — 数据转换器- TI E2E 支持论坛

    多少个电路板/器件显示了这种行为?

    此致、

    Ryan

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我会检查一下、告诉您

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Ryan Andrews 我的坏时钟相位应该是 2 边。 我现在可以读取器件 ID ... 您能为我提供从 ECG 模拟器读取数据的参考吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Naveen、

    我们没有提供从 ECG 模拟器读取数据的具体参考资料。 但是、ADS1298 数据表的“9.5 节:编程“提供了 与 ADS1298 连接的详细说明。 具体而言、“RDATA"命令“命令说明了如何 从器件读取 ECG 数据。

    此致、

    Payton

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    谢谢、我会进行研究

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    HI Naveen — 为了进行澄清,必须在每个 SPI 帧的开头发送 RDATA 命令、然后发送足够的 0x00 字节来读取所有通道数据。 相反、您可以使用 RDATAC 模式(默认)、数据在每个/DRDY 下降沿之前自动加载到输出移位寄存器中。

    此致、

    Ryan

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好瑞恩,谢谢阅读的工作,但我得到了一个非常不寻常的模式,而读取数据。 不、不是硬件噪音。 上图(如果来自 config2 寄存器)(内部测试信号生成)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Naveen:  

    您是否使用示波器或逻辑分析仪检查了 SPI 事务时序?  必须确保在下一个/DRDY 中断之前完成整个帧。 否则、数据将被覆盖和损坏(RDATAC 模式)、或者您将完全错过下一次采样(RDATA 模式)。  

    是否使用内部基准电压? 能否检查 VREFP 和所有电源以确保电路板上没有周期性干扰?

    此致、

    Ryan