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.

[参考译文] ADS131E08S:SPI 通信不工作

Guru**** 2394305 points
Other Parts Discussed in Thread: ADS131E08S

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

https://e2e.ti.com/support/data-converters-group/data-converters/f/data-converters-forum/1539085/ads131e08s-spi-communication-not-working

器件型号:ADS131E08S

工具/软件:

我尝试 使用 nRF52840 软件狗通过 SPI 配置 ADS131E08S、但 ADC 没有响应。 我向我的 MSO 确认、SPI 命令实际上已经发送出来、但是我无法读取寄存器、因为没有应答、并且数据就绪引脚始终为高电平并且永远不会切换。 我尝试过的方法很简单、只是发送启动命令 0x08、但数据就绪引脚仍然保持不变。 我使用 SPI 模式 1、下面是代码:

#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/spi.h>
#include <zephyr/kernel.h>

// SPI
#define SPI_NODE DT_NODELABEL(spi2)
#define CS_PORT  DT_NODELABEL(gpio0)
#define CS_PIN   20

const struct device *spi_dev = DEVICE_DT_GET(SPI_NODE);
const struct device *cs_dev  = DEVICE_DT_GET(CS_PORT);

// DRDY Pin
#define DATA_READY_NODE DT_NODELABEL(data_ready)
const struct gpio_dt_spec drdy = GPIO_DT_SPEC_GET(DATA_READY_NODE, gpios);

volatile _Bool isr_flag = false;

volatile uint32_t start, end, diff_cycles;
volatile uint64_t diff_us;


// SPI
#define NUM_SAMPLES 1000
#define FRAME_SIZE 27

volatile uint8_t adc_data[NUM_SAMPLES][FRAME_SIZE];
volatile int sample_index = 0;
volatile bool buffer_full = false;

uint8_t rx_buf[FRAME_SIZE];
struct spi_buf rx_buf_struct = {
    .buf = rx_buf,
    .len = sizeof(rx_buf),
};

struct spi_buf_set rx = {
    .buffers = &rx_buf_struct,
    .count = 1,
};


int8_t tx_buf[] = {0x00, 0x00, 0x00};

struct spi_buf tx = {
    .buf = tx_buf,
    .len = sizeof(tx_buf),
};

struct spi_buf_set tx_set = {
    .buffers = &tx,
    .count = 1,
};

struct spi_config spi_cfg = {
    .frequency = 4000000,
    .operation = SPI_WORD_SET(8) | SPI_TRANSFER_MSB | SPI_MODE_CPHA,
};


// Interrupt
static void drdy_cb(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
{
    printk("Interrupt ausgelöst\n");
    start = k_cycle_get_32();
    // ISR: 

    if (buffer_full) return; // keine neuen Daten, wenn Puffer voll

    
    spi_read(spi_dev, NULL, &rx);

    memcpy((void *)adc_data[sample_index], rx_buf, FRAME_SIZE);

    sample_index++;
    if (sample_index >= NUM_SAMPLES) {
        sample_index = 0;
        buffer_full = true;
    }

    // End ISR
    end = k_cycle_get_32();
    printk("Samplenr.: %i\n", sample_index);
    diff_cycles = end - start;
    diff_us = (uint64_t)diff_cycles * 1000000 / sys_clock_hw_cycles_per_sec();
    printk("Zeitdiff: %llu us\n\n", diff_us);
}

static struct gpio_callback drdy_cb_data;



int main(void)
{
    printk("\nInitializaion...\n\n");
    k_msleep(5000);
    int ret;


    // DRDY Pin
    if(!device_is_ready(drdy.port)) {
        printk("GPIO device not ready\n");
    }

    if (!device_is_ready(cs_dev)) {
        printk("CS device not ready\n");
    }

    if(gpio_pin_configure_dt(&drdy, GPIO_INPUT) < 0) {
        printk("Error configuring Data Ready pin\n");
    }


    // Interrupt
    gpio_init_callback(&drdy_cb_data, drdy_cb, BIT(drdy.pin));

    gpio_add_callback(drdy.port, &drdy_cb_data);

    if(gpio_pin_interrupt_configure_dt(&drdy, GPIO_INT_EDGE_FALLING) < 0) {
        printk("Error configuring interrupt\n");
    }
    

    // SPI 
    gpio_pin_configure(cs_dev, CS_PIN, GPIO_OUTPUT_HIGH);  // CS idle high

    if(!device_is_ready(spi_dev)) {
        printk("SPI device not ready\n");
    }

    
    // Sensor initialization
    tx.len = 1;
    tx_buf[0] = 0x06;
    gpio_pin_set(cs_dev, CS_PIN, 0);  // CS low (select)
    ret = spi_write(spi_dev, &spi_cfg, &tx_set);
    k_msleep(1);
    gpio_pin_set(cs_dev, CS_PIN, 1);  // CS high (deselect)

    k_msleep(100);

    tx_buf[0] = 0x11;
    gpio_pin_set(cs_dev, CS_PIN, 0);  // CS low (select)
    ret = spi_write(spi_dev, &spi_cfg, &tx_set);
    k_msleep(1);
    gpio_pin_set(cs_dev, CS_PIN, 1);  // CS high (deselect)

    k_msleep(100);

    tx.len = 3;
    tx_buf[0] = 0x41;
    tx_buf[1] = 0x00;
    tx_buf[2] = 0x96;
    gpio_pin_set(cs_dev, CS_PIN, 0);  // CS low (select)
    ret = spi_write(spi_dev, &spi_cfg, &tx_set);
    k_msleep(1);
    gpio_pin_set(cs_dev, CS_PIN, 1);  // CS high (deselect)

    k_msleep(1000);


    tx.len = 1;
    tx_buf[0] = 0x08;   // start conversions
    gpio_pin_set(cs_dev, CS_PIN, 0);  // CS low (select)
    ret = spi_write(spi_dev, &spi_cfg, &tx_set);
    k_msleep(1);
    gpio_pin_set(cs_dev, CS_PIN, 1);  // CS high (deselect)

    k_msleep(1000);


    
    k_msleep(100);
    printk("----- Device Ready!-----\n\n");

    while (1) {
        /*if(gpio_pin_get(drdy.port, drdy.pin)) {
            printk("DRDY PIN High\n");
        } else {
            printk("DRDY PIN Low\n");
        }*/

        if (buffer_full) {

            // Jetzt Daten verarbeiten (z. B. wandeln und ausgeben)
            for (int i = 0; i < NUM_SAMPLES; i++) {
                printk("Sample %d:\n", i);

                int offset = 3;
                for (int ch = 0; ch < 8; ch++) {
                    uint32_t raw = (adc_data[i][offset] << 16) |
                                (adc_data[i][offset + 1] << 8) |
                                adc_data[i][offset + 2];
                    if (raw & 0x800000) raw |= 0xFF000000;

                    printk("  CH%d = %d\n", ch, (int32_t)raw);
                    offset += 3;
                }
            }

            // Nach Ausgabe ggf. wieder für nächste Sekunde freigeben
            sample_index = 0;
        }

        k_msleep(1000); // kurze Pause, kein Busy-Waiting
        buffer_full = false;
    }
    
}

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

    您好、Michael:

    当您向 ADC 发送命令时、您是否可以发送一个逻辑分析仪图、其中显示了来自 ADC 或发送到 ADC 的通信信号? 您的原理图将非常有用、如果您不想公开共享、您可以通过消息与我共享它。

    BR、

    Dale