TI中文支持网
TI专业的中文技术问题搜集分享网站

ADS131M02: DRDY引脚时钟处于高电平状态,无法得到ADC的输出。

Part Number:ADS131M02

我在初步尝试在arduino内进行编程并使用该模块,目前通过串口我可以得到ID号,我想这说明目前的MCU和adc是可以正常进行SPI通信的。但我遇到的问题是,在我利用信号发生器产生一个±500mv的50hz正弦差分信号输入到ADC的通道1后,ADC的输出始终是一个恒定的值。通过示波器和status寄存器我发现drdy引脚时钟处于高电平状态未发生改变,请问这是什么原因。我已经附上了我的寄存器配置值供您查看。我已经验证过目前的寄存器值被正确写入,因为我通过读取寄存器得到了相应的值与我写入的值相符合。同时我还附上了我的arduino编程代码和相应的库文件,很希望得到您的帮助,十分感激。

.ino
#include <SPI.h>
#include "ADS131M04.h"
#include "registerDefinitions.h"

#define CS_PINWB_SPI_CS// 你的 CS 引脚
#define DRDY_PINWB_IO1// 你把 DRDY 接到哪,就填哪

// SPI 命令定义(参考 ADS131M0x 手册)
#define CMD_RESET0x11
#define CMD_START0x33
#define CMD_STOP0x0A

ADS131M04 adc(CS_PIN, -1, &SPI);
int8_t channelIds[2] = {0, 1};

void sendCommand(uint16_t cmd) {SPI.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE1));digitalWrite(CS_PIN, LOW);SPI.transfer16(cmd);digitalWrite(CS_PIN, HIGH);SPI.endTransaction();
}

void setup() {Serial.begin(115200);while (!Serial);pinMode(CS_PIN, OUTPUT);digitalWrite(CS_PIN, HIGH);pinMode(DRDY_PIN, INPUT);// 初始化 SPISPI.begin();// 初始化 ADC(只做 SPI 设置,不会自动 START)adc.begin();Serial.println("ADC 初始化完成");// 先 RESET 一下,确保回到默认状态sendCommand(CMD_RESET);delay(10);//读一次 STATUS 寄存器uint16_t status = adc.readReg(STATUS);Serial.print("读取 STATUS 寄存器: 0x");Serial.println(status, HEX);//读一次 ID 寄存器uint16_t tmp;tmp = adc.readReg(ID);Serial.print("ID = 0x"); Serial.println(tmp, HEX);// 写寄存器配置adc.writeReg(GAIN1,0x0000);  Serial.println("GAIN1 写入");adc.writeReg(CFG,0x0600);  Serial.println("CFG 写入");adc.writeReg(MODE,0x0514);  Serial.println("MODE 写入");adc.writeReg(CLOCK,0x010E);  Serial.println("CLOCK 写入");adc.writeReg(THRSHLD_MSB,0x0000);  Serial.println("THRSHLD_MSB 写入");adc.writeReg(THRSHLD_LSB,0x0000);  Serial.println("THRSHLD_LSB 写入");adc.writeReg(CH0_CFG,0x0000);  Serial.println("CH0_CFG 写入");adc.writeReg(CH0_OCAL_MSB,0x0000); Serial.println("CH0_OCAL_MSB 写入");adc.writeReg(CH0_OCAL_LSB,0x0000); Serial.println("CH0_OCAL_LSB 写入");adc.writeReg(CH0_GCAL_MSB,0x0000); Serial.println("CH0_GCAL_MSB 写入");adc.writeReg(CH0_GCAL_LSB,0x0000); Serial.println("CH0_GCAL_LSB 写入");adc.writeReg(REGMAP_CRC,  0x0000);  Serial.println("REGMAP_CRC 写入");adc.writeReg(RESERVED,0x0000);  Serial.println("RESERVED 写入");// 再次读寄存器验证Serial.println("\n寄存器回读:");#define RD(reg) \tmp = adc.readReg(reg); \Serial.print(#reg); Serial.print(" = 0x"); Serial.println(tmp, HEX);RD(GAIN1); RD(CFG); RD(MODE); RD(CLOCK);RD(THRSHLD_MSB); RD(THRSHLD_LSB);RD(CH0_CFG); RD(CH0_OCAL_MSB); RD(CH0_OCAL_LSB);RD(CH0_GCAL_MSB); RD(CH0_GCAL_LSB);RD(REGMAP_CRC); RD(RESERVED);#undef RD// 最后发送 START 命令,开始连续转换sendCommand(CMD_START);delay(10);Serial.println("发送 START,开始转换");
}

void loop() {// 等待 DRDY 低电平(新数据准备好)if (digitalRead(DRDY_PIN) == LOW) {int32_t adcData[2] = {0};adc.rawChannels(channelIds, 2, adcData);Serial.print("ADC 数据:");for (uint8_t i = 0; i < 2; i++) {Serial.print("Ch"); Serial.print(channelIds[i]);Serial.print(" = "); Serial.print(adcData[i]);Serial.print("  ");}Serial.println();}// 如果想更精细地控制读取频率,可以在此加个小延时delay(1000);
}
ADS131M04.h
/* This is a library for the ADS131M04 4-channel ADCProduct information:https://www.ti.com/product/ADS131M04Datasheet:https://www.ti.com/lit/gpn/ads131m04This library was made for Imperial College London RocketryCreated by Daniele Valentino Bella
*/

#define CLKIN_SPD 8192000 // Clock speed for the CLKIN pin on the DAC
#define SCLK_SPD 4000000 // SPI frequency of DAC

#ifndef ADS131M04_H
#define ADS131M04_H

#include <Arduino.h>
#include <SPI.h>
#include "registerDefinitions.h"

class ADS131M04 {public:ADS131M04(int8_t _csPin, int8_t _clkoutPin, SPIClass* _spi, int8_t _clockCh = 1);void begin(void);void rawChannels(int8_t * channelArrPtr, int8_t channelArrLen, int32_t * outputArrPtr);int32_t rawChannelSingle(int8_t channel);uint16_t readReg(uint8_t reg);bool writeReg(uint8_t reg, uint16_t data);bool setGain(uint8_t log2Gain0 = 0, uint8_t log2Gain1 = 0, uint8_t log2Gain2 = 0, uint8_t log2Gain3 = 0);bool globalChop(bool enabled = false, uint8_t log2delay = 4);private:int8_t csPin, clkoutPin, clockCh;SPIClass* spi;bool initialised;void spiCommFrame(uint32_t * outputArray, uint16_t command = 0x0000);uint32_t spiTransferWord(uint16_t inputData = 0x0000);int32_t twoCompDeco(uint32_t data);
};

#endif
ADS131M04.cpp
/* This is a library for the ADS131M04 4-channel ADCProduct information:https://www.ti.com/product/ADS131M04Datasheet:https://www.ti.com/lit/gpn/ads131m04This library was made for Imperial College London RocketryCreated by Daniele Valentino Bella & Iris Clercq-Roques
*/

#include <Arduino.h>
#include <SPI.h>
#include "registerDefinitions.h"
#include "ADS131M04.h"

ADS131M04::ADS131M04(int8_t _csPin, int8_t _clkoutPin, SPIClass* _spi, int8_t _clockCh) {csPin = _csPin;clkoutPin = _clkoutPin;spi = _spi;clockCh = _clockCh;initialised = false;
}

void ADS131M04::begin(void) {pinMode(csPin, OUTPUT);digitalWrite(csPin, HIGH);spi->begin();// // Set CLKOUT on the ESP32 to give the correct frequency for CLKIN on the DAC// ledcSetup(clockCh, CLKIN_SPD, 2);// ledcAttachPin(clkoutPin, clockCh);// ledcWrite(clockCh, 2);initialised=true;
}

void ADS131M04::rawChannels(int8_t * channelArrPtr, int8_t channelArrLen, int32_t * outputArrPtr) {/* Writes data from the channels specified in channelArr, to outputArr,in the correct order.channelArr should have values from 0-3, and channelArrLen should be thelength of that array, starting from 1.*/uint32_t rawDataArr[6];// Get dataspiCommFrame(&rawDataArr[0]);// Save the decoded data for each of the channelsfor (int8_t i = 0; i<channelArrLen; i++) {*outputArrPtr = twoCompDeco(rawDataArr[*channelArrPtr+1]);outputArrPtr++;channelArrPtr++;}
}

int32_t ADS131M04::rawChannelSingle(int8_t channel) {/* Returns raw value from a single channelchannel input from 0-3*/int32_t outputArr[1];int8_t channelArr[1] = {channel};rawChannels(&channelArr[0], 1, &outputArr[0]);return outputArr[0];
}

bool ADS131M04::globalChop(bool enabled, uint8_t log2delay) {/* Function to configure global chop mode for the ADS131M04.INPUTS:enabled - Whether to enable global-chop mode.log2delay- Base 2 log of the desired delay in modulator clocks periodsbefore measurment beginsPossible values are between and including 1 and 16, to give delaysbetween 2 and 65536 clock periods respectivelyFor more information, refer to the datasheet.Returns true if settings were written succesfully.*/uint8_t delayRegData = log2delay - 1;// Get current settings for current detect mode from the CFG registeruint16_t currentDetSett = (readReg(CFG) << 8) >>8;uint16_t newRegData = (delayRegData << 12) + (enabled << 8) + currentDetSett;return writeReg(CFG, newRegData);
}

bool ADS131M04::writeReg(uint8_t reg, uint16_t data) {/* Writes the content of data to the register regReturns true if successful*/uint8_t commandPref = 0x06;// Make command word using syntax found in data sheetuint16_t commandWord = (commandPref<<12) + (reg<<7);digitalWrite(csPin, LOW);spi->beginTransaction(SPISettings(SCLK_SPD, MSBFIRST, SPI_MODE1));spiTransferWord(commandWord);spiTransferWord(data);// Send 4 empty wordsfor (uint8_t i=0; i<4; i++) {spiTransferWord();}spi->endTransaction();digitalWrite(csPin, HIGH);// Get responseuint32_t responseArr[6];spiCommFrame(&responseArr[0]);if ( ( (0x04<<12) + (reg<<7) ) == responseArr[0]) {return true;} else {return false;}
}

bool ADS131M04::setGain(uint8_t log2Gain0, uint8_t log2gainCommand, uint8_t log2Gain2, uint8_t log2Gain3) {/* Function to set the gain of the four channels of the ADCInputs are the log base 2 of the desired gain to be applied to eachchannel.Returns true if gain was succesfully set.Function written by Iris Clercq-Roques*/uint16_t gainCommand=log2Gain3<<4;gainCommand+=log2Gain2;gainCommand<<=8;gainCommand+=(log2gainCommand<<4);gainCommand+=log2Gain0;return writeReg(GAIN1, gainCommand);
}

uint16_t ADS131M04::readReg(uint8_t reg) {/* Reads the content of single register found at address regReturns register value*/uint8_t commandPref = 0x0A;// Make command word using syntax found in data sheetuint16_t commandWord = (commandPref << 12) + (reg << 7);uint32_t responseArr[6];// Use first frame to send commandspiCommFrame(&responseArr[0], commandWord);// Read responsespiCommFrame(&responseArr[0]);return responseArr[0] >> 16;
}

uint32_t ADS131M04::spiTransferWord(uint16_t inputData) {/* Transfer a 24 bit wordData returned is MSB aligned*/uint32_t data = spi->transfer(inputData >> 8);data <<= 8;data |= spi->transfer((inputData<<8) >> 8);data <<= 8;data |= spi->transfer(0x00);return data << 8;
}

void ADS131M04::spiCommFrame(uint32_t * outPtr, uint16_t command) {// Saves all the data of a communication frame to an array with pointer outPtrdigitalWrite(csPin, LOW);spi->beginTransaction(SPISettings(SCLK_SPD, MSBFIRST, SPI_MODE1));// Send the command in the first word*outPtr = spiTransferWord(command);// For the next 4 words, just read the datafor (uint8_t i=1; i < 3; i++) {outPtr++;*outPtr = spiTransferWord() >> 8;}// Save CRC bits// outPtr++;// *outPtr = spiTransferWord();spi->endTransaction();digitalWrite(csPin, HIGH);
}

int32_t ADS131M04::twoCompDeco(uint32_t data) {// Take the two's complement of the datadata <<= 8;int32_t dataInt = (int)data;return dataInt/pow(2,8);
}

Lydia:

您好,

已经收到了您的案例,调查需要些时间,感谢您的耐心等待

赞(0)
未经允许不得转载:TI中文支持网 » ADS131M02: DRDY引脚时钟处于高电平状态,无法得到ADC的输出。
分享到: 更多 (0)