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.

[参考译文] ADS1218:数据读取问题

Guru**** 2571725 points
Other Parts Discussed in Thread: ADS1218

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

https://e2e.ti.com/support/data-converters-group/data-converters/f/data-converters-forum/623615/ads1218-data-reading-problem

部件号:ADS1218

您好,

我正在尝试使用Arduino板配置我的ADS1218。 我正在使用以下设置:

AVCC = 5伏

单极

1920年的小数

数字滤波器SINC3

我在缓冲器关闭的情况下执行校准,并在校准后将其打开。

我正在通过将MUX设置为0x01,FMOD = 9600 Hz,在通道Ain0和Ain1上应用1.3 Vdc

问题是校准后,无论 输入如何,我都会一直读取0.00 ,其电压范围为0至2伏。

如果我在没有校准的情况下使用它,无论输入如何,我都始终获得2.5 V,输入电压范围从0到2伏不等。

这是我的代码:

/**************************************************************
Aalto_ADS1218.ino
此示例提供了通过
Arduino
|ADS1218引脚标签|引脚功能进行UV连接时AN0和AN1之间的差分电压 |Arduino Connection|
|----------- |:----------- :|----------- :||DRDY
|数据就绪输出引脚| D6. |
|味增 |从机输出 | D12. |
| MOSI |从机进入 | D11. |
| SCLK. |串行时钟 | D13. |
| CS |芯片选择 | D7. |
| DVDD |数字VDD |+5V |
| DGND |数字接地 | GND |
| AN0-AN3 |模拟输入 |模拟输入|
| AVDD |模拟VDD |- |
| AGND |模拟接地 |- **********
/

#include <SPI.h>


#define SPI_MASTER_DUMMY 0xff
#define reset 0x06 //发送reset命令(06h)以确保在通电后正确重置ADS1220
#define start 0x08 //发送启动/同步命令(08h)以在连续转换模式下开始转换

//定义ads1218命令
#define RDATA 0x01 //读取最新的AD转换数据
#define RDATAC 0x03 //连续读取转换的数据
#define STOPC 0x0F //停止连续读取模式
#define RREG 0x10 //用于读取寄存器内容的双字节命令第一个字节:BIT3-bit0 = 0-16;
#define RRAM 0x20 //用于读取第一个字节RAM内容的双字节命令:BIT3-bit0 = 0-16;
#define CREG 0x40 //将寄存器的内容复制到指定的ram bank中,下面三位指定ram页地址
#define CREGA 0x48 //将寄存器的内容复制到所有ram bank中。
#Define WREG 0x50 // 2字节命令,将数据写入寄存器0-15#define
WRAM 0x60 // 2字节指令,将数据写入RAM中的128字节
#define RF2R 0x80 //将指定闪存页的数据读取为128字节的RAM
#define WR2F 0xA0 //将ram中的数据写入指定的闪存页
#define cram 0xC0 //将选定的ram数据复制到配置寄存器中,这将覆盖当前工作寄存器内容
#define CRAMX 0xD0 //在指定的页ram中计算校验和,不包括ID,DRDY DIO
#define CSARAMX 0xD8 //在所有ram中计算校验和,不包括ID, DRDY DIO
#define CSARAM 0xDF //计算配置寄存器的校验和
#define CSRAM 0xE0 //计算指定页面RAM中的校验和,其中包含所有位
#define CSARAM 0xE8 //计算所有RAM中的校验和,其中包含所有位
#define CFL 0xEC //计算所有闪存中的校验和, 包括所有位
#define SCLFCAL 0xF0 //偏移和增益自校准
#define SELFOCAL 0xF1 //偏移自校准
#define SCLFGCAL 0xF2 //增益自校准
#define SYSOCAL 0xF3 //系统偏移校准
#define SYSGCAL0xF4 //系统增益校准
#define DSYNC 0xFC //同步DRDY
#define睡眠模式0xFD
重置0xFE //将寄存器重置为数据的功率,停止连续读取模式, 不影响ram数据

//定义ads1218寄存器地址
#define SETUP_REG_ADRS 0x00
#define MUX_REG_ADRS 0x01
#define ACR_REG_ADRS 0x02
#define IDAC1_REG_AD0x03
#define IDAC2_REG_ADRs_ADREG_ADRs_0x014_ADRs_define #AD0014_ADRs_0x014_ADRs_DEFAST_ADRs_DEF014_AD014_AD014_ADRs_DEF_AD014_AD014_AD014_ADRs_DEFAE #014_AD014_AD014_ADRs_DEFAE #014_AD0_AD014_AD014_AD014_ADRs_DEFAE







0x0C
#define FSR0_REG_ADRS 0x0D
#define FSR1_REG_ADRS 0x0E
#define FSR2_REG_ADRS 0x0F



#define ADS1218_CS_PIN 7
#define ADS1218_DRDY_PIN 6


void writeRegister (uint8_t地址,uint8_t值)
{ uint8_microrep
;

PIN码= 1218_microrep;0
= 12秒;数;数;0
SPI.transfer (WREG |地址);
SPI.transfer (numReg);
SPI.transfer (value);
// delayMicroseconds (500);
digitalWrite (ADS1218_CS_PIN, high);
interrupts();
}

uint8_t readRegister (uint8_t地址)
{
uint8_t data;
uint8_t numReg = 0x01;
noInterrupts();
digitalWrite(ASD1218_CS_PIN, low);
// delayMicroseconds(500);
SPI.transfer (REG |地址);
SPI.transfer (numReg);
delayMicroseconds (20); //所需10 us
数据的延迟= SPI.transfer (SPI_MASTER_DUMMY);
// delayMicroseconds(500);
digitalWrite(ASD1218_CS_PIN, HIGH );
Interrupts();
返回数据;
}


void printAllreg(void)
{
int read_Data0;
for (int i =0;i <=15;I++){
READ_Data0 = readRegister (i);
serial.println (read_Data0,hex);
Delay(10);
}


void SendSELFCALCommand(void)
{
noInterrupts();
digitalWrite(ASD1218_CS_PIN, low);
delayMicroseconds(500);
SPI.transfer(SELFCAL);
delayMicroseconds(500);
digitalWrite(ASD1218_CS_PIN, high );
interrups();delay(2000);


}

void synsyncSerialData(void){

noInterrupts();
digitalWrite(ASD1218_CS_PIN, low);
delayMicroseconds(500);
SPI.transfer(DSYNC);
delayMicroseconds(500);
digitalWrite(ASD1218_CS_PIN, high );
interrupts();
delay(2000);

}

void waitForDataReady(int timeout)//等待数据就绪
{//
等待/DRDY =1
等待((digitalRead(ADS1218_DRDY_PIN))!=低);//

等待/DRDY = 0
等待((INTdigRead(ASD1218_DRDY_PIN))=低);}



UdataForbet=0 (INT_DataFlag)






noInterrupts();
DigitalWrite (ADS1218_CS_PIN,低); //降低CS
// delayMicroseconds(500);

SPI.transfer (RDATA);
DelayMicroseconds(20);
字节msbData = SPI.transfer (SPI_MASTER_DUPY);
字节中间数据= SPI.transfer (SPI_MASTER_DUPY);
字节lsbData = SPI.transfer (SPI_MASTER_DUPY);
// delayMicroseconds(500);
DigitalWrite (ADS1218_CS_PIN,高); //清除CS至高
中断();
dataBits = msbData;
dataBits =(dataBits <<8)| midData;
dataBits =(dataBits <<8)| lsbData;
}
返回dataBits;
}

void setup()
{

digitalWrite(ASD1218_CS_PIN, high );
pinMode(ADS1218_CS_PIN, output);

Serial.begin(9600); //11.52万 5.76万
SPI.begin(); //唤醒SPI总线。
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE1);
SPI.setClockDivider(SPI_CLOCK_DIV64);
writeRegister (0x00,0xFC); //0000 1100,缓冲区已禁用。
DELAY (50);
writeRegister (0x08,0x80);// decimation寄存器1,DEC0
DELAY (50);
writeRegister (0x09,0x77);// decimation寄存器2,Dec1,单极,SINC3过滤器集
延迟(50);
printAllreg();
DELAY (5000);
SendLFC5000命令

writeRegister (0x00, 0xFE);//0000 01110,缓冲区已启用,fmod = 9600
delay(50);
writeRegister (0x08, 0x80);// decimation寄存器1,DEC0
delay(50);
writeRegister (0x09, 0x77);//





同步寄存器2,Dec1,单极,SINUX过滤器集1,串行延迟(50/);数据集x01; xedge();xreach( x01)



void loop()
{

UINT32_t data32=0;


data32 = read_Data(1);



float值=(FLOW(data32)* 2.5 * 100万)/16777216;1677.7216万;

Serial.print("






}bin:");Serial.println(data32, bin); Serial.print("值:");Serial.bin(图


解:32位) 

有什么建议???

提前感谢!

Tanweer

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

    您好,Tanweer,

    欢迎参加论坛!  您是否可以尝试重新张贴示意图?  我认为链接意外地卡在代码部分。

    您是否能够成功地读回寄存器设置,以及寄存器是否设置为您编写这些设置的方式?  我建议使用示波器或逻辑分析器查看SPI通信,以确保通信符合您的预期。  如果可以,请发布这些照片。  我还会用一个示波器来监控DRDY,以确保它以您正在使用的小数点所指定的正确速率脉动。 还要确保引脚(如RESET,PDWN和DSYNC)为逻辑高电平,POL引脚应为逻辑低电平。

    谢谢!

    Bob B

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

    您好,Bob B.

    感谢您的快速响应。

    下面是我的示意图:

    这是我的代码:

    #定义PGA 1
    #定义VREF 2.5
    #define VFSR VREF/GPGA (定义VFSR VREF)
    #define FSR ((((Long int)1<23)-1)
    
    #define SPI_MASTER_DUMMY 0xff
    #define reset 0x06 //发送reset命令(06h)以确保在通电后正确重置ADS1220
    #define start 0x08 //发送启动/同步命令(08h)以在连续转换模式中开始转换
    
    
    #define ADS1218_CS_PIN 7#define
    ADS1218_DRDY_PIN 6
    
    
    void writeRegister (uint8_t address, uint8_t value)
    {uint8_t
    numREG =0x01;
    norupitalts();digReg SPI (ADS
    1218_address, low_transfer)
    
    SPI.transfer (numReg);
    SPI.transfer (value);
    digitalWrite (ADS1218_CS_PIN,high);
    interrups();
    }
    
    uINT8_t readRegister (uint8_t地址)
    {
    uint8_t data;
    uint8_t numReg = 0x01;
    noInterrupts();
    digitalWrite (ADS1218_CS_PIN,低);
    SPI.transfer (RREG |地址);
    SPI.transfer (numReg);
    delayMicroseconds (20); // 10 us所需
    数据的延迟= SPI.transfer(SPI_MASTER_DUMM);
    digitalWrite(ASD1218_CS_PIN, HIGH );
    interrupts();
    return data;}
    
    
    
    void printAllreg (void)
    {
    int read_Data0;
    for (int i =0;i <=15;I++){
    READ_Data0 = readRegister (i);
    serial.println (read_Data0,hex);
    Delay(10);
    }
    
    
    void SendSELFCALCommand(void)
    {
    noInterrupts();
    digitalWrite(ASD1218_CS_PIN, low);
    delayMicroseconds(500);
    SPI.transfer(SELFCAL);
    delayMicroseconds(500);
    digitalWrite(ASD1218_CS_PIN, high );
    interrups();delay(2000);
    
    
    }
    
    void synsyncSerialData(void){
    
    noInterrupts();
    digitalWrite(ASD1218_CS_PIN, low);
    delayMicroseconds(500);
    SPI.transfer(DSYNC);
    delayMicroseconds(500);
    digitalWrite(ASD1218_CS_PIN, high );
    interrupts();
    delay(2000);
    
    }
    
    void waitForDataReady(int timeout)//等待数据就绪
    {//
    等待/DRDY =1
    等待((digitalRead(ADS1218_DRDY_PIN))!=低);//
    
    等待/DRDY = 0
    等待((INTdigRead(ASD1218_DRDY_PIN))=低);}
    
    
    
    UdataForbet=0 (INT_DataFlag)
    
    
    
    
    
    
    noInterrupts();
    DigitalWrite (ADS1218_CS_PIN,低);
    SPI.transfer (RDATA);
    DelayMicroseconds(20);
    字节msbData = SPI.transfer (SPI_MASTER_DUPY);
    字节中间数据= SPI.transfer (SPI_MASTER_DUPY);
    字节lsbData = SPI.transfer (SPI_MASTER_DUPY);
    DigitalWrite (ADS1218_CS_PIN,高);
    中断();
    dataBits = msbData;
    dataBits =(dataBits <<8)| midData;
    dataBits =(dataBits <<8)| lsbData;
    }
    返回dataBits;
    }
    
    void setup()
    {
    
    digitalWrite(ASD1218_CS_PIN, high );
    pinMode(ADS1218_CS_PIN, output);
    
    pinMode (3,输出);
    
    Serial.begin(9600); //11.52万 5.76万
    SPI.begin(); //唤醒SPI总线。
    SPI.setBitOrder(MSBFIRST);
    SPI.setDataMode(SPI_MODE1);
    SPI.setClockDivider(SPI_CLOCK_DIV64);
    writeRegister (0x00,0x0c); //0000 1100,缓冲区已禁用。
    DELAY (50);
    writeRegister (0x08,0x80);// decimation寄存器1,DEC0
    DELAY (50);
    writeRegister (0x09,0x37);// decimation寄存器2,Dec1,单极,SINC3过滤器集
    延迟(50);
    9600 Allreg (50);
    writeRegister (0x00,0x50
    
    );dec080;reimation
    
    寄存器0 (0x50,0x50) 0 (0 (0);缓冲区0 (0) //小数寄存器2,Dec1,单极,SINC3过滤器集
    延迟(50);
    writeRegister (0x01,0x01);//设置MUX
    延迟(50);
    }
    
    void loop()
    {
    
    
    UINT32_t data24=0;
    UINT32_t data32=0;
    
    data24 = read_Data(1);
    
    
    IF (0x80万)
    data24 =(data24 | 0xFF0万); //将24位二的补码转换为32位二的补码
    其他
    data32= data24;
    
    浮点值=(浮点)((data32*VFSR*1000)/FSR); //in mV
    
    Serial.println(value, DEC);
    
    digitalWrite(3, value);
    
    }
    
    
    
    

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

    我的SPI工作正常,我可以根据需要写入和读取寄存器。 串行接收的数据为:

    注册值:

    4C
    1.
    0
    0
    0
    0
    0
    FF
    80
    37.
    0
    0
    0
    24岁
    90
    67

    数据:
    0.0000000000
    74.7066802978
    89.9285125732
    69.1011657714
    28.9744186401
    58.7806167602
    102.5310287475
    76.8572158813
    30.8483886718
    74.0453643798
    84.5700607299
    61.3355712890
    37.1384658813
    50.5206069946
    88.0023880004
    61.4208068847
    36.3436393737
    60.6283607482
    85.2540206909
    69.2382507324
    40.2054214477
    77.8013534545
    98.3891067504
    52.3343772888
    28.5217208862
    63.3314323425
    82.9973907470
    49.8226356506
    51.5481910705
    41.0923385620
    83.2027282714
    69.0388717651
    38.5171203613
    61.8293952941
    88.5644607543
    71.5115737915
    26.4665527343
    95.7369918823
    88.0390472412
    78.0397720336
    31.3851280212
    75.3760452270
    88.1099777221
    86.7533798217
    34.0619735717
    71.8164520263
    105.4191741943

    当我开始将输入信号振幅从2 V (峰值到峰值)降低 到1.2V (峰值到峰值)或更低的ADC读取2.5 (参考电压)时,会一直保持这种状态。以下是数据:

    2500.0000000000
    2500.0000000000
    2500.0000000000
    2500.0000000000
    2500.0000000000
    2500.0000000000
    2500.0000000000
    2500.0000000000
    2500.0000000000
    2500.0000000000
    2500.0000000000
    2500.0000000000
    2500.0000000000
    2500.0000000000

    下面是我的示波器图像:

    如果我做错了,请给出建议。

    此致,
    Tanweer

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

    您好,Tanweer,

    很抱歉我没有更早地作出答复。  与转换的结果相比,使用ADS1218的原始代码通常更容易看到可能发生的情况,因为这样可以消除与数据转换错误相关的任何混淆。  根据返回的寄存器结果,您使用的是双极数据 格式(寄存器地址0x09=37,其中位6为低), 这意味 着正全标度是0x7FFFFFFF。  如果我正确地阅读 了这些镜头,我会从您的示波器镜头中看到0xFFFFFF。   由于输出是二进制2的补码,所以0xFFFFFF的值实际上是-1个代码,或非常接近零。  

    我想你们有几个问题。  第一,您需要确保正确解释返回的代码。  第二个是您输入的2Vpp与您的任何结果都不匹配。  如果2500对应于2.5V,则100对应于100mV,这大约是我看到的最大值。  生成器的输出不能低于AGND,因此必须对生成器进行设置,以便将输出正确引用到AGND并具有直流偏移,从而使信号生成器的输出保持在 ADS1218的正确输入范围内。

    此致,

    Bob B