请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
器件型号: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;
}
}