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.

[参考译文] ADS124S08:在读取操作期间接收所有零

Guru**** 2589275 points
Other Parts Discussed in Thread: ADS124S08

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

https://e2e.ti.com/support/data-converters-group/data-converters/f/data-converters-forum/1069828/ads124s08-receiving-all-zeros-during-read-operation

部件号:ADS124S08

我正在尝试将 ads124s08与 teensy 3.6连接,以读取某些电池中的数据。 编写该代码是为了配置 ADC,使其使用 5V 单极外部参考,增益设置为1,4000 SPS,并使用微控制器的外部时钟。 A 将 Arduino IDE 用于此目的。

我正在附加逻辑分析器输出的图像,逻辑分析器输出在 SPI 通信 /resized-image/__size/320x240/__key/communityserver-discussion-components-files/73/WhatsApp-Image-2022_2D00_01_2D00_18-at-12.12.06-AM.jpeg 期间将 ADC 输出显示为全部零

我还附上了我用于此目的的代码

#include<SPI.h>

//#include <TimerOne.h>

int CS_PIN = 10;
int START_PIN = 5;
int RESET_PIN = 6;
int CKEN_PIN = 13;
int DRDY_PIN = 14;
int lastSample;

int mosi =  11;
int miso =  12;

SPISettings mySPISettings(4000000, MSBFIRST, SPI_MODE1);

#define NUM_REGISTERS 18

//rgeister map 
#define ID_ADDR_MASK        0x00
#define STATUS_ADDR_MASK    0x01
#define INPMUX_ADDR_MASK    0x02
#define PGA_ADDR_MASK       0x03
#define DATARATE_ADDR_MASK  0x04
#define REF_ADDR_MASK       0x05
#define IDACMAG_ADDR_MASK   0x06
#define IDACMUX_ADDR_MASK   0x07
#define VBIAS_ADDR_MASK     0x08
#define SYS_ADDR_MASK       0x09
#define OFCAL0_ADDR_MASK    0x0A
#define OFCAL1_ADDR_MASK    0x0B
#define OFCAL2_ADDR_MASK    0x0C
#define FSCAL0_ADDR_MASK    0x0D
#define FSCAL1_ADDR_MASK    0x0E
#define FSCAL2_ADDR_MASK    0x0F
#define GPIODAT_ADDR_MASK   0x10
#define GPIOCON_ADDR_MASK   0x11

/* Opcode masks (or "Commands" if you will...) */
#define NOP_OPCODE_MASK     0x00
#define WAKE_OPCODE_MASK    0x02
#define SLEEP_OPCODE_MASK   0x04
#define RESET_OPCODE_MASK   0x06
#define START_OPCODE_MASK   0x08
#define STOP_OPCODE_MASK    0x0A
#define SFOCAL_OPCODE_MASK  0x19
#define SYOCAL_OPCODE_MASK  0x16
#define SYGCAL_OPCODE_MASK  0x17
#define RDATA_OPCODE_MASK   0x12
#define REGRD_OPCODE_MASK   0x20
#define REGWR_OPCODE_MASK   0x40

/* Define the ADC positive input channels (MUXP) */
#define ADS_P_AIN0        0x00
#define ADS_P_AIN1        0x10
#define ADS_P_AIN2        0x20
#define ADS_P_AIN3        0x30
#define ADS_P_AIN4        0x40
#define ADS_P_AIN5        0x50
#define ADS_P_AIN6        0x60
#define ADS_P_AIN7        0x70
#define ADS_P_AIN8        0x80
#define ADS_P_AIN9        0x90
#define ADS_P_AIN10       0xA0
#define ADS_P_AIN11       0xB0
#define ADS_P_AINCOM      0xC0

/* Define the ADC negative input channels (MUXN)*/
#define ADS_N_AIN0        0x00
#define ADS_N_AIN1        0x01
#define ADS_N_AIN2        0x02
#define ADS_N_AIN3        0x03
#define ADS_N_AIN4        0x04
#define ADS_N_AIN5        0x05
#define ADS_N_AIN6        0x06
#define ADS_N_AIN7        0x07
#define ADS_N_AIN8        0x08
#define ADS_N_AIN9        0x09
#define ADS_N_AIN10       0x0A
#define ADS_N_AIN11       0x0B
#define ADS_N_AINCOM      0x0C

/* Define PGA control */
#define ADS_PGA_BYPASS    0x00
#define ADS_PGA_ENABLED   0x08
/* Define Gain */
#define ADS_GAIN_1        0x00
#define ADS_GAIN_2        0x01
#define ADS_GAIN_4        0x02
#define ADS_GAIN_8        0x03
#define ADS_GAIN_16       0x04
#define ADS_GAIN_32       0x05
#define ADS_GAIN_64       0x06
#define ADS_GAIN_128      0x07

/System Control register/
#define ADS_SENDSTATUS_DISABLE  0x00
#define ADS_SENDSTATUS_ENABLE   0x01

/Reference Control register/
#define ADS_FLAG_REF_DISABLE  0x00
#define ADS_FLAG_REF_EN_L0    0x40
#define ADS_FLAG_REF_EN_BOTH  0x80
#define ADS_FLAG_REF_EN_10M   0xC0
#define ADS_REFP_BYP_DISABLE  0x20
#define ADS_REFP_BYP_ENABLE   0x00
#define ADS_REFN_BYP_DISABLE  0x10
#define ADS_REFN_BYP_ENABLE   0x00
#define ADS_REFSEL_P0         0x00
#define ADS_REFSEL_P1         0x04
#define ADS_REFSEL_INT        0x08
#define ADS_REFINT_OFF        0x00
#define ADS_REFINT_ON_PDWN    0x01
#define ADS_REFINT_ON_ALWAYS  0x02

/* Flag to signal that we are in the process of collecting data */
#define DATA_MODE_NORMAL  0x00
#define DATA_MODE_STATUS  0x01
#define DATA_MODE_CRC     0x02

class ADS124S08
{
  // Device command prototypes
  public:
    ADS124S08(void);
    void begin();
    char regRead(unsigned int regnum);
    void readRegs(unsigned int regnum, unsigned int count, uint8_t *data);
    void regWrite(unsigned int regnum, unsigned char data);
    void writeRegs(unsigned int regnum, unsigned int howmuch, unsigned char *data);
    void reStart(void);
    void sendCommand(uint8_t op_code);
    int  rData(uint8_t *dStatus, uint8_t *dData, uint8_t *dCRC);
    int  dataRead(uint8_t *dStatus, uint8_t *dData, uint8_t *dCRC);
    void selectDeviceCSLow(void);
    void releaseChipSelect(void);
    void assertStart(void);
    void deassertStart(void);
    void assertClock(void);
    void deassertClock(void);
    bool converting;
    uint8_t registers[NUM_REGISTERS];
  private:
    bool fStart;
    void DRDY_int(void);
    uint8_t _drdy_pin;
    uint8_t _start_pin;
    uint8_t _reset_pin;
}adc;

ADS124S08::ADS124S08(void) // pin config and reg map 
{
  pinMode( CS_PIN, OUTPUT );
  pinMode( START_PIN, OUTPUT );
  pinMode( RESET_PIN, OUTPUT );
  pinMode( CKEN_PIN, OUTPUT );
  pinMode( DRDY_PIN, INPUT );
  pinMode( mosi, OUTPUT );
  pinMode( miso, INPUT );

  digitalWrite( START_PIN, LOW );
  digitalWrite( RESET_PIN, HIGH );
  digitalWrite( CKEN_PIN, LOW );

  /* Default register settings */
  registers[ID_ADDR_MASK]       = 0x08;
  registers[STATUS_ADDR_MASK]   = 0x80;
  registers[INPMUX_ADDR_MASK]   = 0x01;
  registers[PGA_ADDR_MASK]      = 0x00;
  registers[DATARATE_ADDR_MASK] = 0x14;
  registers[REF_ADDR_MASK]      = 0x10;
  registers[IDACMAG_ADDR_MASK]  = 0x00;
  registers[IDACMUX_ADDR_MASK]  = 0xFF;
  registers[VBIAS_ADDR_MASK]    = 0x00;
  registers[SYS_ADDR_MASK]      = 0x10;
  registers[OFCAL0_ADDR_MASK]   = 0x00;
  registers[OFCAL1_ADDR_MASK]   = 0x00;
  registers[OFCAL2_ADDR_MASK]   = 0x00;
  registers[FSCAL0_ADDR_MASK]   = 0x00;
  registers[FSCAL1_ADDR_MASK]   = 0x00;
  registers[FSCAL2_ADDR_MASK]   = 0x40;
  registers[GPIODAT_ADDR_MASK]  = 0x00;
  registers[GPIOCON_ADDR_MASK]  = 0x00;
  fStart = false;
  releaseChipSelect();
  deassertStart();
}

void ADS124S08::begin() //start transaction 
{
  SPI.begin( );
  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode( SPI_MODE1 );
  SPI.setClockDivider(21); //the system clock can be divided by values from 1 to 255. The default value is 21, which sets the clock to 4 MHz like other Arduino boards.
  #if defined (SPI_HAS_TRANSACTION)
    mySPISettings = SPISettings(4000000, MSBFIRST, SPI_MODE1);
  #endif
}

char ADS124S08::regRead(unsigned int regnum)
{
  int i;
  uint8_t ulDataTx[3];
  uint8_t ulDataRx[3];
  ulDataTx[0] = REGRD_OPCODE_MASK + (regnum & 0x1f);
  ulDataTx[1] = 0x00;
  ulDataTx[2] = 0x00;
  selectDeviceCSLow();

  #if defined (SPI_HAS_TRANSACTION)
    SPI.beginTransaction(mySPISettings);
  #endif

  for(i = 0; i < 3; i++)
    ulDataRx[i] = SPI.transfer(ulDataTx[i]);
  if(regnum < NUM_REGISTERS)
      registers[regnum] = ulDataRx[2];

  #if defined (SPI_HAS_TRANSACTION)
    SPI.endTransaction();
  #endif

  releaseChipSelect();
  //Serial.println("regRead tx: %02x %02x %02x",ulDataTx[0],ulDataTx[1],ulDataTx[2]);
  //Serial.println("regRead rx: %02x %02x %02x",ulDataRx[0],ulDataRx[1],ulDataRx[2]);
  return ulDataRx[2];
}

void ADS124S08::readRegs(unsigned int regnum, unsigned int count, uint8_t *data)
{
  int i;
  uint8_t ulDataTx[2];
  ulDataTx[0] = REGRD_OPCODE_MASK + (regnum & 0x1f);
  ulDataTx[1] = count-1;
  selectDeviceCSLow();
  SPI.transfer(ulDataTx[0]);
  SPI.transfer(ulDataTx[1]);
  for(i = 0; i < count; i++)
  {
    data[i] = SPI.transfer(0);
    if(regnum+i < NUM_REGISTERS)
      registers[regnum+i] = data[i];
  }
  releaseChipSelect();
}

void ADS124S08::regWrite(unsigned int regnum, unsigned char data)
{
  uint8_t ulDataTx[3];
  ulDataTx[0] = REGWR_OPCODE_MASK + (regnum & 0x1f);
  ulDataTx[1] = 0x00;
  ulDataTx[2] = data;
  selectDeviceCSLow();
  SPI.transfer(ulDataTx[0]);
  SPI.transfer(ulDataTx[1]);
  SPI.transfer(ulDataTx[2]);
  releaseChipSelect();
  //Serial.println("regWrite tx: %02x %02x %02x",ulDataTx[0],ulDataTx[1],ulDataTx[2]);
  return;
}

void ADS124S08::writeRegs(unsigned int regnum, unsigned int howmuch, unsigned char *data)
{
  unsigned int i;
  uint8_t ulDataTx[2];
  ulDataTx[0] = REGWR_OPCODE_MASK + (regnum & 0x1f);
  ulDataTx[1] = howmuch-1;
  selectDeviceCSLow();
  SPI.transfer(ulDataTx[0]);
  SPI.transfer(ulDataTx[1]);
  for(i=0; i < howmuch; i++)
  {
    SPI.transfer( data[i] );
    if(regnum+i < NUM_REGISTERS)
      registers[regnum+i] = data[i];
  }
  releaseChipSelect();
  return;
}

void ADS124S08::reStart(void)
{
  sendCommand(STOP_OPCODE_MASK);
  sendCommand(START_OPCODE_MASK);
  return;
}

void ADS124S08::sendCommand(uint8_t op_code)
{
  selectDeviceCSLow();
  SPI.transfer(op_code);
  releaseChipSelect();
  return;
}

int ADS124S08::rData(uint8_t *dStatus, uint8_t *dData, uint8_t *dCRC)
{
  int result = -1;
  selectDeviceCSLow();

  // according to datasheet chapter 9.5.4.2 Read Data by RDATA Command
  sendCommand(RDATA_OPCODE_MASK);

  // if the Status byte is set - grab it
  uint8_t shouldWeReceiveTheStatusByte = (registers[SYS_ADDR_MASK] & 0x01) == DATA_MODE_STATUS;
  if( shouldWeReceiveTheStatusByte )
  {
    dStatus[0] = SPI.transfer(0x00);
    //Serial.print("status: ");
    //Serial.print(dStatus[0]);
  }

  // get the conversion data (3 bytes)
  uint8_t data[3];
  data[0] = SPI.transfer(0x00);
  data[1] = SPI.transfer(0x00);
  data[2] = SPI.transfer(0x00);
  result = data[0];
  result = (result<<8) + data[1];
  result = (result<<8) + data[2];
  //Serial.println(" 1: %02x 2: %02x, 3: %02x = %d", data[0], data[1], data[2], result);

  // is CRC enabled?
  uint8_t isCrcEnabled = (registers[SYS_ADDR_MASK] & 0x02) == DATA_MODE_CRC;
  if( isCrcEnabled )
  {
    dCRC[0] = SPI.transfer(0x00);
  }

  releaseChipSelect();
  return result;
}

int ADS124S08::dataRead(uint8_t *dStatus, uint8_t *dData, uint8_t *dCRC)
{
  uint8_t xcrc;
  uint8_t xstatus;
  int iData;
  selectDeviceCSLow();
  if((registers[SYS_ADDR_MASK] & 0x01) == DATA_MODE_STATUS)
  {
    xstatus = SPI.transfer(0x00);
    Serial.print("0:");
    Serial.print(xstatus);
    dStatus[0] = (uint8_t)xstatus;
  }

  // get the conversion data (3 bytes)
  uint8_t data[3];
  data[0] = SPI.transfer(0x00);
  data[1] = SPI.transfer(0x00);
  data[2] = SPI.transfer(0x00);

  
  Serial.print(" 1:");
  Serial.print(data[0]);
  Serial.print(" 2:");
  Serial.print(data[1]);
  Serial.print(" 3:");
  Serial.println(data[2]);
  

  iData = data[0];
  iData = (iData<<8) + data[1];
  iData = (iData<<8) + data[2];
  if((registers[SYS_ADDR_MASK] & 0x02) == DATA_MODE_CRC)
  {
    xcrc = SPI.transfer(0x00);
    dCRC[0] = (uint8_t)xcrc;
  }
  releaseChipSelect();
  return iData ;
}

void ADS124S08::selectDeviceCSLow(void){
  digitalWrite( CS_PIN, LOW );
}

void ADS124S08::releaseChipSelect(void){
  digitalWrite( CS_PIN, HIGH );
}

void ADS124S08::assertStart()
{
  fStart = true;
  digitalWrite(START_PIN ,HIGH);
}

void ADS124S08::deassertStart()
{
  fStart = false;
  digitalWrite(START_PIN, LOW);
}

void ADS124S08::assertClock()
{
  digitalWrite(CKEN_PIN, 1);
}

void ADS124S08::deassertClock()
{
  digitalWrite(CKEN_PIN, LOW);
}

void setup()
{
  Serial.begin(9600);

  delay(100);
  adc.begin();
  delay(100);
  adc.sendCommand(RESET_OPCODE_MASK);
  delay(100);

  regMap();

  configureAdc();

  Serial.println("After config");
  regMap();
  
}

void loop()
{
  long now = millis();
  //uint8_t status;
  // Check if it's X seconds since last conversion
  if( now - lastSample > 25 ){                     //delay between two conversions taken as 25ms 
    //Serial.print(sampleNumber);
    //Serial.print(" ");
    lastSample = now;
    readData();
  }
}

void configureAdc()
{
  // Make sure the device is awake
  adc.sendCommand( WAKE_OPCODE_MASK );
  // use channel 1 as positive and channel 2 as negative input
  adc.regWrite( INPMUX_ADDR_MASK, ADS_P_AIN0 + ADS_N_AIN1 ); // mux selection reg: AIN0 - +ve and AIN1 - -ve (default)
  // set PGA to 1x
  adc.regWrite( PGA_ADDR_MASK, ADS_PGA_BYPASS  + ADS_GAIN_1 ); //Gain setting reg: PGA bypassed(default), gain set to 1
  // The IDAC will only work if we enable the internal reference (ref Datasheet 9.3.7)
  //adc.regWrite( REF_ADDR_MASK, ADS_REFINT_ON_ALWAYS + ADS_REFSEL_P0 );
  // use channel 3 as IDAC 1 (excitation current source)
  //adc.regWrite( IDACMUX_ADDR_MASK, ADS_IDAC1_A2 + ADS_IDAC2_OFF );  //We are not using internal reference 
  // set IDAC 1 to output 500uA
  //adc.regWrite( IDACMAG_ADDR_MASK, ADS_IDACMAG_500 );
  // Turn on status for debugging
  adc.regWrite( SYS_ADDR_MASK, ADS_SENDSTATUS_ENABLE ); //Status bit while reading data: pg no. 70 in datasheet 
  //Configuring external register
  adc.regWrite( REF_ADDR_MASK, ADS_FLAG_REF_DISABLE +  ADS_REFP_BYP_ENABLE + ADS_REFN_BYP_DISABLE + ADS_REFSEL_P0); //REFP0 and REFN0 as external reference 
  //Configuring the data rate register
  adc.regWrite( DATARATE_ADDR_MASK, ADS_CLKSEL_EXT +  ADS_FILTERTYPE_LL + ADS_DR_4000);
  adc.reStart();
  delay(10);
  //regMap2();
}

void readData()
{
  uint8_t dStatus = 0;
  uint8_t dData;
  uint8_t dCRC = 0;
  int data = 0;

  /* Read out the results  */
  data = adc.dataRead(&dStatus, &dData, &dCRC); //call to dataRead() - the 24 bit data stored in iData will be stored in data 
  /*
   * Need to determine if Status and/or CRC is enabled to transmit as desired
   */
  /*if((adc.registers[SYS_ADDR_MASK] & 0x01) == DATA_MODE_STATUS)  //Not yet completely understood these nested if loops 
  {
    if((adc.registers[SYS_ADDR_MASK] & 0x02) == DATA_MODE_CRC)
    {
      Serial.println("Conversion Data 0x%06x with Status 0x%02x and CRC 0x%02x.", data, dStatus, dCRC);
    }
    else
    {
      //sSerial.println("Conversion Data 0x%06x with Status 0x%02x. DEC %02d", data, dStatus,data);
    }
  }
  else if((adc.registers[SYS_ADDR_MASK] & 0x02) == DATA_MODE_CRC)
  {
    Serial.println("Conversion Data 0x%06x with CRC 0x%02x.", data, dCRC);
  }
  else*/
  //{
    Serial.println(data,DEC);  //This is where the raw conversion result should be available 
  //}

  
  /* Set ADC back to the previous configuration */
  //adc.sendCommand(STOP_OPCODE_MASK);
  //adc.sendCommand(SLEEP_OPCODE_MASK);

  //return dStatus;
}

void regMap(void)
{
  unsigned int index;
  char cTemp;
  Serial.println("Register Contents");
  Serial.println("---------------------");
  for(index=0; index < 18 ; index++)
  {
    cTemp = adc.regRead(index);
    Serial.println(index, cTemp);
  }
}

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

    您好,阿维纳什·普拉巴胡,

    欢迎参加 E2E 论坛!  很难阅读您发送的图像,但它似乎是萨莱亚的一张照片。  如果您可以将数据保存到文件并附加文件,那么我更容易进行故障排除。

    一些考虑因素。  第一个是您对数据的期望是什么?  实际上,您正在重复发送 NOC。  相反,我建议发送 RREG 命令并从寄存器中读取默认值,以验证通信是否正常。  下一步是编写所需的寄存器配置,然后再读回配置以验证其写入是否正确。

    此外,确保您没有违反任何时间安排。  例如,确保 CS 低至第一个 SCLK 边线处于所需的正时内,同时也确保最后一个 SCLK 边线至 CS 的正时高。  此信息如 ADS124S08数据表第15页的图1所示。

    至于您的代码,我建议您将重置销设置为低,然后将 CLK 销设置为低,然后再将重置销重新设置为高。  根据 CLK 针脚的内部状态,重置后针脚过低的设置实际上可能会禁用内部时钟。  因此,除重置引脚外的所有引脚状态都应处于所需的初始状态,然后重置引脚才会进入高位。

    此致,

    鲍勃·B

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

    #include<SPI.h>
    
    //#include <TimerOne.h>
    
    int CS_PIN = 10;
    int START_PIN = 5;
    int RESET_PIN = 6;
    int CKEN_PIN = 13;
    int DRDY_PIN = 14;
    int lastSample;
    
    int mosi =  11;
    int miso =  12;
    
    SPISettings mySPISettings(4000000, MSBFIRST, SPI_MODE1);
    
    #define NUM_REGISTERS 18
    
    //rgeister map 
    #define ID_ADDR_MASK        0x00
    #define STATUS_ADDR_MASK    0x01
    #define INPMUX_ADDR_MASK    0x02
    #define PGA_ADDR_MASK       0x03
    #define DATARATE_ADDR_MASK  0x04
    #define REF_ADDR_MASK       0x05
    #define IDACMAG_ADDR_MASK   0x06
    #define IDACMUX_ADDR_MASK   0x07
    #define VBIAS_ADDR_MASK     0x08
    #define SYS_ADDR_MASK       0x09
    #define OFCAL0_ADDR_MASK    0x0A
    #define OFCAL1_ADDR_MASK    0x0B
    #define OFCAL2_ADDR_MASK    0x0C
    #define FSCAL0_ADDR_MASK    0x0D
    #define FSCAL1_ADDR_MASK    0x0E
    #define FSCAL2_ADDR_MASK    0x0F
    #define GPIODAT_ADDR_MASK   0x10
    #define GPIOCON_ADDR_MASK   0x11
    
    /* Opcode masks (or "Commands" if you will...) */
    #define NOP_OPCODE_MASK     0x00
    #define WAKE_OPCODE_MASK    0x02
    #define SLEEP_OPCODE_MASK   0x04
    #define RESET_OPCODE_MASK   0x06
    #define START_OPCODE_MASK   0x08
    #define STOP_OPCODE_MASK    0x0A
    #define SFOCAL_OPCODE_MASK  0x19
    #define SYOCAL_OPCODE_MASK  0x16
    #define SYGCAL_OPCODE_MASK  0x17
    #define RDATA_OPCODE_MASK   0x12
    #define REGRD_OPCODE_MASK   0x20
    #define REGWR_OPCODE_MASK   0x40
    
    /* Define the ADC positive input channels (MUXP) */
    #define ADS_P_AIN0        0x00
    #define ADS_P_AIN1        0x10
    #define ADS_P_AIN2        0x20
    #define ADS_P_AIN3        0x30
    #define ADS_P_AIN4        0x40
    #define ADS_P_AIN5        0x50
    #define ADS_P_AIN6        0x60
    #define ADS_P_AIN7        0x70
    #define ADS_P_AIN8        0x80
    #define ADS_P_AIN9        0x90
    #define ADS_P_AIN10       0xA0
    #define ADS_P_AIN11       0xB0
    #define ADS_P_AINCOM      0xC0
    
    /* Define the ADC negative input channels (MUXN)*/
    #define ADS_N_AIN0        0x00
    #define ADS_N_AIN1        0x01
    #define ADS_N_AIN2        0x02
    #define ADS_N_AIN3        0x03
    #define ADS_N_AIN4        0x04
    #define ADS_N_AIN5        0x05
    #define ADS_N_AIN6        0x06
    #define ADS_N_AIN7        0x07
    #define ADS_N_AIN8        0x08
    #define ADS_N_AIN9        0x09
    #define ADS_N_AIN10       0x0A
    #define ADS_N_AIN11       0x0B
    #define ADS_N_AINCOM      0x0C
    
    /* Define PGA control */
    #define ADS_PGA_BYPASS    0x00
    #define ADS_PGA_ENABLED   0x08
    /* Define Gain */
    #define ADS_GAIN_1        0x00
    #define ADS_GAIN_2        0x01
    #define ADS_GAIN_4        0x02
    #define ADS_GAIN_8        0x03
    #define ADS_GAIN_16       0x04
    #define ADS_GAIN_32       0x05
    #define ADS_GAIN_64       0x06
    #define ADS_GAIN_128      0x07
    
    /*System Control register*/
    #define ADS_SENDSTATUS_DISABLE  0x00
    #define ADS_SENDSTATUS_ENABLE   0x01
    
    /*Reference Control register*/
    #define ADS_FLAG_REF_DISABLE  0x00
    #define ADS_FLAG_REF_EN_L0    0x40
    #define ADS_FLAG_REF_EN_BOTH  0x80
    #define ADS_FLAG_REF_EN_10M   0xC0
    #define ADS_REFP_BYP_DISABLE  0x20
    #define ADS_REFP_BYP_ENABLE   0x00
    #define ADS_REFN_BYP_DISABLE  0x10
    #define ADS_REFN_BYP_ENABLE   0x00
    #define ADS_REFSEL_P0         0x00
    #define ADS_REFSEL_P1         0x04
    #define ADS_REFSEL_INT        0x08
    #define ADS_REFINT_OFF        0x00
    #define ADS_REFINT_ON_PDWN    0x01
    #define ADS_REFINT_ON_ALWAYS  0x02
    
    /* Flag to signal that we are in the process of collecting data */
    #define DATA_MODE_NORMAL  0x00
    #define DATA_MODE_STATUS  0x01
    #define DATA_MODE_CRC     0x02
    
    /*DataRate Register*/
    #define ADS_GLOBALCHOP      0x80
    #define ADS_CLKSEL_EXT      0x40
    #define ADS_CONVMODE_SS     0x20
    #define ADS_FILTERTYPE_LL   0x10
    
    /* Define the data rate */
    #define ADS_DR_2_5      0x00
    #define ADS_DR_5        0x01
    #define ADS_DR_10       0x02
    #define ADS_DR_16       0x03
    #define ADS_DR_20       0x04
    #define ADS_DR_50       0x05
    #define ADS_DR_60       0x06
    #define ADS_DR_100      0x07
    #define ADS_DR_200      0x08
    #define ADS_DR_400      0x09
    #define ADS_DR_800      0x0A
    #define ADS_DR_1000     0x0B
    #define ADS_DR_2000     0x0C
    #define ADS_DR_4000     0x0D
    
    class ADS124S08
    {
      // Device command prototypes
      public:
        ADS124S08(void);
        void begin();
        char regRead(unsigned int regnum);
        void readRegs(unsigned int regnum, unsigned int count, uint8_t *data);
        void regWrite(unsigned int regnum, unsigned char data);
        void writeRegs(unsigned int regnum, unsigned int howmuch, unsigned char *data);
        void reStart(void);
        void sendCommand(uint8_t op_code);
        int  rData(uint8_t *dStatus, uint8_t *dData, uint8_t *dCRC);
        int  dataRead(uint8_t *dStatus, uint8_t *dData, uint8_t *dCRC);
        void selectDeviceCSLow(void);
        void releaseChipSelect(void);
        void assertStart(void);
        void deassertStart(void);
        void assertClock(void);
        void deassertClock(void);
        bool converting;
        uint8_t registers[NUM_REGISTERS];
      private:
        bool fStart;
        void DRDY_int(void);
        uint8_t _drdy_pin;
        uint8_t _start_pin;
        uint8_t _reset_pin;
    }adc;
    
    ADS124S08::ADS124S08(void) // pin config and reg map 
    {
      pinMode( CS_PIN, OUTPUT );
      pinMode( START_PIN, OUTPUT );
      pinMode( RESET_PIN, OUTPUT );
      pinMode( CKEN_PIN, OUTPUT );
      pinMode( DRDY_PIN, INPUT );
      pinMode( mosi, OUTPUT );
      pinMode( miso, INPUT );
    
      digitalWrite( RESET_PIN, LOW); 
      digitalWrite( START_PIN, LOW );
      digitalWrite( CKEN_PIN, LOW );
      digitalWrite( RESET_PIN, HIGH );
    
      /* Default register settings */
      registers[ID_ADDR_MASK]       = 0x08;
      registers[STATUS_ADDR_MASK]   = 0x80;
      registers[INPMUX_ADDR_MASK]   = 0x01;
      registers[PGA_ADDR_MASK]      = 0x00;
      registers[DATARATE_ADDR_MASK] = 0x14;
      registers[REF_ADDR_MASK]      = 0x10;
      registers[IDACMAG_ADDR_MASK]  = 0x00;
      registers[IDACMUX_ADDR_MASK]  = 0xFF;
      registers[VBIAS_ADDR_MASK]    = 0x00;
      registers[SYS_ADDR_MASK]      = 0x10;
      registers[OFCAL0_ADDR_MASK]   = 0x00;
      registers[OFCAL1_ADDR_MASK]   = 0x00;
      registers[OFCAL2_ADDR_MASK]   = 0x00;
      registers[FSCAL0_ADDR_MASK]   = 0x00;
      registers[FSCAL1_ADDR_MASK]   = 0x00;
      registers[FSCAL2_ADDR_MASK]   = 0x40;
      registers[GPIODAT_ADDR_MASK]  = 0x00;
      registers[GPIOCON_ADDR_MASK]  = 0x00;
      fStart = false;
      releaseChipSelect();
      deassertStart();
    }
    
    void ADS124S08::begin() //start transaction 
    {
      SPI.begin( );
      SPI.setBitOrder(MSBFIRST);
      SPI.setDataMode( SPI_MODE1 );
      SPI.setClockDivider(21); //the system clock can be divided by values from 1 to 255. The default value is 21, which sets the clock to 4 MHz like other Arduino boards.
      #if defined (SPI_HAS_TRANSACTION)
        mySPISettings = SPISettings(4000000, MSBFIRST, SPI_MODE1);
      #endif
    }
    
    char ADS124S08::regRead(unsigned int regnum)
    {
      int i;
      uint8_t ulDataTx[3];
      uint8_t ulDataRx[3];
      ulDataTx[0] = REGRD_OPCODE_MASK + (regnum & 0x1f);
      ulDataTx[1] = 0x00;
      ulDataTx[2] = 0x00;
      selectDeviceCSLow();
      delay(10);
    
      #if defined (SPI_HAS_TRANSACTION)
        SPI.beginTransaction(mySPISettings);
      #endif
    
      for(i = 0; i < 3; i++)
        ulDataRx[i] = SPI.transfer(ulDataTx[i]);
      if(regnum < NUM_REGISTERS)
          registers[regnum] = ulDataRx[2];
    
      #if defined (SPI_HAS_TRANSACTION)
         SPI.endTransaction();
      #endif
      delay(10);
      releaseChipSelect();
      //Serial.println("regRead tx: %02x %02x %02x",ulDataTx[0],ulDataTx[1],ulDataTx[2]);
      //Serial.println("regRead rx: %02x %02x %02x",ulDataRx[0],ulDataRx[1],ulDataRx[2]);
      return ulDataRx[2];
    }
    
    void ADS124S08::readRegs(unsigned int regnum, unsigned int count, uint8_t *data)
    {
      int i;
      uint8_t ulDataTx[2];
      ulDataTx[0] = REGRD_OPCODE_MASK + (regnum & 0x1f);
      ulDataTx[1] = count-1;
      selectDeviceCSLow();
      SPI.transfer(ulDataTx[0]);
      SPI.transfer(ulDataTx[1]);
      for(i = 0; i < count; i++)
      {
        data[i] = SPI.transfer(0);
        if(regnum+i < NUM_REGISTERS)
          registers[regnum+i] = data[i];
      }
      releaseChipSelect();
    }
    
    void ADS124S08::regWrite(unsigned int regnum, unsigned char data)
    {
      uint8_t ulDataTx[3];
      ulDataTx[0] = REGWR_OPCODE_MASK + (regnum & 0x1f);
      ulDataTx[1] = 0x00;
      ulDataTx[2] = data;
      selectDeviceCSLow();
      SPI.transfer(ulDataTx[0]);
      SPI.transfer(ulDataTx[1]);
      SPI.transfer(ulDataTx[2]);
      releaseChipSelect();
      //Serial.println("regWrite tx: %02x %02x %02x",ulDataTx[0],ulDataTx[1],ulDataTx[2]);
      return;
    }
    
    void ADS124S08::writeRegs(unsigned int regnum, unsigned int howmuch, unsigned char *data)
    {
      unsigned int i;
      uint8_t ulDataTx[2];
      ulDataTx[0] = REGWR_OPCODE_MASK + (regnum & 0x1f);
      ulDataTx[1] = howmuch-1;
      selectDeviceCSLow();
      SPI.transfer(ulDataTx[0]);
      SPI.transfer(ulDataTx[1]);
      for(i=0; i < howmuch; i++)
      {
        SPI.transfer( data[i] );
        if(regnum+i < NUM_REGISTERS)
          registers[regnum+i] = data[i];
      }
      releaseChipSelect();
      return;
    }
    
    void ADS124S08::reStart(void)
    {
      sendCommand(STOP_OPCODE_MASK);
      sendCommand(START_OPCODE_MASK);
      return;
    }
    
    void ADS124S08::sendCommand(uint8_t op_code)
    {
      selectDeviceCSLow();
      SPI.transfer(op_code);
      releaseChipSelect();
      return;
    }
    
    int ADS124S08::rData(uint8_t *dStatus, uint8_t *dData, uint8_t *dCRC)
    {
      int result = -1;
      selectDeviceCSLow();
    
      // according to datasheet chapter 9.5.4.2 Read Data by RDATA Command
      sendCommand(RDATA_OPCODE_MASK);
    
      // if the Status byte is set - grab it
      uint8_t shouldWeReceiveTheStatusByte = (registers[SYS_ADDR_MASK] & 0x01) == DATA_MODE_STATUS;
      if( shouldWeReceiveTheStatusByte )
      {
        dStatus[0] = SPI.transfer(0x00);
        //Serial.print("status: ");
        //Serial.print(dStatus[0]);
      }
    
      // get the conversion data (3 bytes)
      uint8_t data[3];
      data[0] = SPI.transfer(0x00);
      data[1] = SPI.transfer(0x00);
      data[2] = SPI.transfer(0x00);
      result = data[0];
      result = (result<<8) + data[1];
      result = (result<<8) + data[2];
      //Serial.println(" 1: %02x 2: %02x, 3: %02x = %d", data[0], data[1], data[2], result);
    
      // is CRC enabled?
      uint8_t isCrcEnabled = (registers[SYS_ADDR_MASK] & 0x02) == DATA_MODE_CRC;
      if( isCrcEnabled )
      {
        dCRC[0] = SPI.transfer(0x00);
      }
    
      releaseChipSelect();
      return result;
    }
    
    int ADS124S08::dataRead(uint8_t *dStatus, uint8_t *dData, uint8_t *dCRC)
    {
      uint8_t xcrc;
      uint8_t xstatus;
      int iData;
      selectDeviceCSLow();
      if((registers[SYS_ADDR_MASK] & 0x01) == DATA_MODE_STATUS)
      {
        xstatus = SPI.transfer(0x00);
        Serial.print("0:");
        Serial.print(xstatus);
        dStatus[0] = (uint8_t)xstatus;
      }
    
      // get the conversion data (3 bytes)
      uint8_t data[3];
      data[0] = SPI.transfer(0x00);
      data[1] = SPI.transfer(0x00);
      data[2] = SPI.transfer(0x00);
    
      
      Serial.print(" 1:");
      Serial.print(data[0]);
      Serial.print(" 2:");
      Serial.print(data[1]);
      Serial.print(" 3:");
      Serial.println(data[2]);
      
    
      iData = data[0];
      iData = (iData<<8) + data[1];
      iData = (iData<<8) + data[2];
      if((registers[SYS_ADDR_MASK] & 0x02) == DATA_MODE_CRC)
      {
        xcrc = SPI.transfer(0x00);
        dCRC[0] = (uint8_t)xcrc;
      }
      releaseChipSelect();
      return iData ;
    }
    
    void ADS124S08::selectDeviceCSLow(void){
      digitalWrite( CS_PIN, LOW );
    }
    
    void ADS124S08::releaseChipSelect(void){
      digitalWrite( CS_PIN, HIGH );
    }
    
    void ADS124S08::assertStart()
    {
      fStart = true;
      digitalWrite(START_PIN ,HIGH);
    }
    
    void ADS124S08::deassertStart()
    {
      fStart = false;
      digitalWrite(START_PIN, LOW);
    }
    
    void ADS124S08::assertClock()
    {
      digitalWrite(CKEN_PIN, 1);
    }
    
    void ADS124S08::deassertClock()
    {
      digitalWrite(CKEN_PIN, LOW);
    }
    
    void setup()
    {
      Serial.begin(9600);
    
      delay(100);
      adc.begin();
      delay(100);
      adc.sendCommand(RESET_OPCODE_MASK);
      delay(100);
      /*uint8_t STATUS_REG = adc.regRead(STATUS_ADDR_MASK); //Reading Status register before config using RREG command 
      Serial.println( STATUS_REG, HEX );
      delay(10);
      uint8_t INPMUX_REG = adc.regRead(INPMUX_ADDR_MASK); //Reading Input mux register before config using RREG command 
      Serial.println( INPMUX_REG, HEX );
      delay(10);
      uint8_t PGA_REG = adc.regRead(PGA_ADDR_MASK); //Reading Gain register before config using RREG command 
      Serial.println( PGA_REG, HEX );
      delay(10);
      uint8_t DATARATE_REG = adc.regRead(DATARATE_ADDR_MASK); //Reading datarate register before config using RREG command 
      Serial.println( DATARATE_REG, HEX );
      delay(10);
      uint8_t REF_REG = adc.regRead(REF_ADDR_MASK); //Reading reference control register before config using RREG command 
      Serial.println( REF_REG, HEX );
      delay(10);
       /*digitalWrite(RESET_PIN, LOW); 
       delay(100);
       digitalWrite(RESET_PIN, HIGH);*/
      regMap2();
    
      configureAdc();
    
      Serial.println("After config");
      delay(100);
      /*STATUS_REG = adc.regRead(STATUS_ADDR_MASK); //Reading Status register after config using RREG command 
      Serial.println( STATUS_REG, HEX );
      delay(10);
      INPMUX_REG = adc.regRead(INPMUX_ADDR_MASK); //Reading Input mux register after config using RREG command 
      Serial.println( INPMUX_REG, HEX );
      delay(10);
      PGA_REG = adc.regRead(PGA_ADDR_MASK); //Reading Gain register after config using RREG command 
      Serial.println( PGA_REG, HEX );
      delay(10);
      DATARATE_REG = adc.regRead(DATARATE_ADDR_MASK); //Reading datarate after before config using RREG command 
      Serial.println( DATARATE_REG, HEX );
      delay(10);
      REF_REG = adc.regRead(REF_ADDR_MASK); //Reading reference control register after config using RREG command 
      Serial.println( REF_REG, HEX );
      delay(10);*/
      
      regMap2();
      
    }
    
    void loop()
    {
      long now = millis();
      //uint8_t status;
      // Check if it's X seconds since last conversion
      if( now - lastSample > 25 ){                     //delay between two conversions taken as 25ms 
        //Serial.print(sampleNumber);
        //Serial.print(" ");
        lastSample = now;
        readData();
      }
    }
    
    void configureAdc()
    {
      // Make sure the device is awake
      //adc.sendCommand( WAKE_OPCODE_MASK );
      // use channel 1 as positive and channel 2 as negative input
      adc.regWrite( INPMUX_ADDR_MASK, ADS_P_AIN0 + ADS_N_AIN1 ); // mux selection reg: AIN0 - +ve and AIN1 - -ve (default)
      // set PGA to 1x
      adc.regWrite( PGA_ADDR_MASK, ADS_PGA_BYPASS  + ADS_GAIN_1 ); //Gain setting reg: PGA bypassed(default), gain set to 1
      // The IDAC will only work if we enable the internal reference (ref Datasheet 9.3.7)
      //adc.regWrite( REF_ADDR_MASK, ADS_REFINT_ON_ALWAYS + ADS_REFSEL_P0 );
      // use channel 3 as IDAC 1 (excitation current source)
      //adc.regWrite( IDACMUX_ADDR_MASK, ADS_IDAC1_A2 + ADS_IDAC2_OFF );  //We are not using internal reference 
      // set IDAC 1 to output 500uA
      //adc.regWrite( IDACMAG_ADDR_MASK, ADS_IDACMAG_500 );
      // Turn on status for debugging
      adc.regWrite( SYS_ADDR_MASK, ADS_SENDSTATUS_ENABLE ); //Status bit while reading data: pg no. 70 in datasheet 
      //Configuring external register
      adc.regWrite( REF_ADDR_MASK, ADS_FLAG_REF_DISABLE +  ADS_REFP_BYP_ENABLE + ADS_REFN_BYP_DISABLE + ADS_REFSEL_P0); //REFP0 and REFN0 as external reference// int ref for checking 
      //DataRate register 
      adc.regWrite( DATARATE_ADDR_MASK, ADS_CLKSEL_EXT +  ADS_FILTERTYPE_LL + ADS_DR_4000 );
      adc.reStart();
      delay(10);
      //regMap2();
    }
    
    void readData()
    {
      uint8_t dStatus = 0;
      uint8_t dData;
      uint8_t dCRC = 0;
      int data = 0;
    
      /* Read out the results  */
      data = adc.dataRead(&dStatus, &dData, &dCRC); //call to dataRead() - the 24 bit data stored in iData will be stored in data 
      /*
       * Need to determine if Status and/or CRC is enabled to transmit as desired
       */
      /*if((adc.registers[SYS_ADDR_MASK] & 0x01) == DATA_MODE_STATUS)  //Not yet completely understood these nested if loops 
      {
        if((adc.registers[SYS_ADDR_MASK] & 0x02) == DATA_MODE_CRC)
        {
          Serial.println("Conversion Data 0x%06x with Status 0x%02x and CRC 0x%02x.", data, dStatus, dCRC);
        }
        else
        {
          //sSerial.println("Conversion Data 0x%06x with Status 0x%02x. DEC %02d", data, dStatus,data);
        }
      }
      else if((adc.registers[SYS_ADDR_MASK] & 0x02) == DATA_MODE_CRC)
      {
        Serial.println("Conversion Data 0x%06x with CRC 0x%02x.", data, dCRC);
      }
      else*/
      //{
        Serial.println(data,DEC);  //This is where the raw conversion result should be available 
      //}
    
      
      /* Set ADC back to the previous configuration */
      //adc.sendCommand(STOP_OPCODE_MASK);
      //adc.sendCommand(SLEEP_OPCODE_MASK);
    
      //return dStatus;
    }
    
    /*void regMap(void)
    {
      unsigned int index;
      char cTemp;
      Serial.println("Register Contents");
      Serial.println("---------------------");
      for(index=0; index < 18 ; index++)
      {
        cTemp = adc.regRead(index);
        Serial.println(index, cTemp);
      }
    }*/
    void regMap2(void)
    {
      unsigned int index;
      uint8_t cTemp[18];
      adc.readRegs(0,18,cTemp);
      Serial.println("Register Contents");
      Serial.println("---------------------");
    
      for(index=0; index < 18 ; index++)
      {
        Serial.println("");
        Serial.print(index,":" );
        Serial.println( cTemp[index], HEX );
      }
    }

    感谢您的快速响应

    我们实施了您提到的更改,并尝试测试代码,但当尝试读取寄存器的内容时,我们在写入寄存器之前和之后都会收到所有的1。 我在此附上逻辑分析器生成的 csv 文件(更新的代码),等待您的响应

    e2e.ti.com/.../5340.digital.csv

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

    您好,

    不幸的是,csv 文件需要大量的数据操作才能读取它。  如果您使用的是 Saleae,我可以更轻松地查看.logicdata 或.Sal 文件(取决于所使用的软件版本)。

    验证 ADS124S08电源是否以额定工作电压(AVDD/AVSS,IOVDD 和 DVDD)工作。  如果其中一个电源处于非活动状态,ADC 将保持重置状态。  同时检查复位销是否也是逻辑偏高。  不要仅仅假设代码有效,而是使用电压表,范围或逻辑探测器进行验证。

    您所显示的分析仪屏幕截图中正在发生什么情况尚不清楚。  你能解释一下应该发生什么?  另请注意传输的第4个字节上的短脉冲。  SCLK 上升边缘的数据应发生变化,下降边缘的数据应保持稳定。  另请注意,逻辑分析器不会对第5个字节进行解码。  在最后一个 SCLK 结束之前,CS 正处于高位。

    最后,通信未按您的预期工作。  查看您的注册阅读代码,我们发现这些值似乎正确,但您需要验证传输是否正确。  状态寄存器的单个寄存器读数应显示为0x21,0x00,0x00 (用于 MOSI 上的传输),启动后,状态寄存器在 SCLKs 的第三字节的 miso 上应显示为0x80。

    在进行故障诊断时,请尽量不要对代码执行太多操作。  一次执行一步操作并进行验证。  例如,确保在开头正确传输了 reset 命令。  如果此命令显示正确,请添加一个非零寄存器读取,如 ID 或状态寄存器。  完成每个功能,直到您验证了正确的操作。

    在故障排除过程中,要尽早验证的另一件事是 SPI 计时。  您似乎打算使用4MHz 的 SCLK 频率,但如果您在逻辑分析器上查看周期,则它看起来接近100kHz (大约10个时钟,以0.1毫秒为单位)。

    此致,

    鲍勃·B