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.

[参考译文] ADS1119:RDATA 不工作

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

https://e2e.ti.com/support/data-converters-group/data-converters/f/data-converters-forum/1245270/ads1119-rdata-not-working

器件型号:ADS1119

您好!

我正在为将来的设计制作试验电路板、并且无法从器件获得回读(我一共两个)。  以下是电路的草图:

我尝试读回 ADC 时的 DRDY 图片:

我将发送以下命令(code、然后是终端):

电源看起来不错、I2C 正常工作、我可以修改和回读寄存器、而 DRDY 会在我回读时显示连续回读和更长的间隔。  但回读(我将变量设置为可能的垃圾数字以完全确保回读数据)始终为 FFFF。

我在此处的调试工作很麻烦-为了验证事物是否工作、最好的后续步骤是什么、以及我可能在哪些方面旋紧了硬件的实施?

提前感谢、

-休·艾森曼

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

    我应注意、这些 ADS1119源自 DigiKey。  我认为、只要我不通过第三方卖家购买、作为原装零件的分销商、他们是相当安全的。

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

    您好、Hugh、

    欢迎来到 E2E 论坛!   您正在使用什么 I2C 地址?  图纸不会显示您正在使用的内容(引脚悬空)。  故障排除的最佳方法是监控 I2C 总线。  您显然正在读取和写入正常、但您使用的命令会有什么不同(i2c_read_word 而不是 i2c_read_Byte)?  READ_WORD 函数返回什么?  是 uint16_t 吗?  验证您是否按照预期获得了包含示波器屏幕截图的数据、并且还收到了正确的 ACK。   

    如果 READ_WORD 返回 uint16_t (例如 uint32_t)以外的值、由于 SCL 继续为 SDA 计时、因此将消除16位数据、仅为较低位数据获取 FFFF、SDA 现在在转换数据传输后仍保持高电平。

    此致、

    鲍勃 B

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

    您好!

    您是正确的、A1/A0是浮动的、我在扫描时看到地址64 (0x40)。

    READ_BYTE 和 READ_WORD 是标准 Wire 库的简单包装器、用于预先降低代码复杂性;以后其他开发人员将使用此包装器、并且我想使主要开发工作保持高效。  此处输入代码:

    uint8_t i2c_read_byte(byte addr)
    {
      byte ack;
      Wire.requestFrom(addr, 1);
      ack = Wire.endTransmission();
      if (ack > 0) return(ack);
      delay(10);
      return(Wire.read());
    }
    uint16_t i2c_read_word(byte addr)
    {
      byte ack;
      uint16_t readback = 57;
      Serial.print("Bad should be 57: ");
      Serial.println(readback);
      Wire.requestFrom(addr, 1);
      ack = Wire.endTransmission();
      if (ack > 0) return(ack);
      delay(10);
      readback = Wire.read() << 8;
      readback |= Wire.read();
      return(readback);
    }

    感谢您的及时回复、

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

    您好、Hugh、

    您不能将地址引脚保持悬空状态。  它们必须连接到某些器件、因为这些是数字 CMOS 输入引脚、并且无法保证它们将悬空到什么值以及 ADS1119将如何响应。

    • 您如何区分 NACK 和数据?  
    • 您是否验证了与示波器的通信?  还是只依赖于代码结果?  
    • 您使用的 SCL 时钟频率是多少?  
    • 您的 I2C 总线上的上拉电阻值是多少?  
    • 您会向输入端施加多大的电压来比较您的结果?

    此致、

    鲍勃 B

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

    您好!

    完全正确、我好像有一个地址引脚接地的试验电路板、另一个没有接地。  固定.

    我依靠 Arduino 中现有的 I2C 实现来处理 Ack/Nack ,只需检查 endTransmission ()的返回值,它将返回任何类型的 NACK 的非零值。  我也依靠 Arduino 来控制流量;我相信默认频率是100KHz。  我正在使用1K 上拉电阻、该上拉电阻来自 Teensy (在本例中、我用于 ADC 的电源电压也是 teensy 的3.3VREG 总线)。  现在、我将0和浮点输入连接到 ADC 模拟输入;在我使用 DAC (我对其进行了很好的通信)生成~2.5V 输入之前。

    下面是一些具有解码的波形。  选择7、将 ADC 设置为 AIN0->GND、增益1、90sps、连续采样、内部基准:

    这里是 RDATA 捕获图:

    我注意到、在读取的第二个字节中有一个非零回读、但解码似乎还显示第二个字节中的 R/W 位设置为 W、因此、也许我需要专门为此 ADC 响应创建一个特殊的回读。

    感谢您的宝贵意见、

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

    我注意到我的代码中有一点错误;我只请求在 read_word 中返回一个字节。

    当我修复后、我看到以下捕获:

    这似乎意味着在我请求和随后对器件进行回读之后的某个时间发生非零回读。  非常有趣。

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

    您好、Hugh、

    请注意、在寄存器读取(RREG)和 RDATA 序列中、有一个无关命令在序列结束时发送。  我 从 RDATA 命令复制了您的数据、下面展示了传输顺序中的哪些错误。

    此无关命令可能是您遇到的问题的一部分。  数据显示为0x0000、您的代码是否报告此值、还是看到不同的东西。

    此致、

    鲍勃 B

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

    尊敬的 Bob:

    我同意这令人困惑。  摆弄我的代码有点增加了混淆:

    这是以下代码的 R/W:

        ADS1119_WRITE_reg (ADS1119_ADDRESS、ADS1119_MUX_PCH0_NGND、ADS1119_GAIN_1、ADS1119_90SPS、ADS1119_CONTINUOUST、 ADS1119_VREF_INT);

    转到函数:

    void ADS1119_write_reg(byte addr, uint8_t mux,uint8_t adc_gain,uint8_t data_rate,uint8_t conversion,uint8_t vref)
    {
      uint8_t to_write = 0x0, rdbk = 0x0;
      uint16_t payload = 0x0;
      
      byte ack = 7;
      to_write |= mux;
      to_write |= adc_gain;
      to_write |= data_rate;
      to_write |= conversion;
      to_write |= vref;
      
      payload = ADS1119_WREG << 8;
      payload |= to_write;
      
      Serial.print("To write: ");
      Serial.println(payload);
    
      Serial.print("Ack of REG0 write: ");
        
      Serial.println(i2c_write_word(ADS1119_ADDRESS, payload));
    
      i2c_write_byte(ADS1119_ADDRESS, ADS1119_RREG0);
      Serial.println("Readback of reg0: ");
      Serial.println(i2c_read_byte(ADS1119_ADDRESS));
      return;
    }

    为了确保不会将多余的信息放在总线上、我修改了 read_Byte 代码:

    uint8_t i2c_read_byte(byte addr)
    {
      byte ack;
      Wire.requestFrom(addr, 1);
      ack = Wire.endTransmission();
      if (ack > 0) return(ack);
      delay(10);
      Serial.print("Readback1: ");
      Serial.println(Wire.read());
      return(Wire.read());
    }

    尝试从行中读取的第一个字节将在 read_Byte 内打印、第二个字节(因为如果我的 uC 发出第二个读取请求、我们应该看到 ADC 布置的另一个字节)将在末尾返回。  我看到的回读为:

    102是正确的(发送了0x66、回读了0x66)、255表示(如上面的波形所示)未从总线读取任何其他有效位。

    我不知道为什么我在示波器上看到了这种幽灵;很显然它在那里、但 ADC 似乎没有对它做出反应、我的 UC 似乎无法从它的发布中获取任何数据。

    此致、

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

    您好、Hugh、

    我在这里也看不到任何明显的东西、但你不能否认可能存在潜在的问题。  您是否使用示波器验证了最后一次实验中事件的顺序?  我猜、由于您看到的数据是0xFF、因此最后一条命令直到您发送第二条 Wire.Read 后才会发送。

    现在回到最初发出的 RDATA 命令、它现在是否能按预期工作?

    此致、

    鲍勃 B

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

    您好!

    出于调试目的、我对设置进行了几处更改、并做了一些 A-B 比较。  我在已知正常工作的线路上还有一个 ADI DAC (之前未通电)、可以使用该代码/器件来验证 I2C。  更改包括:

    • ADS1119和 AD5667BRMZ 现在为5Vdd
    • 慢速 I2C 使用3.3V TTL、通过电平转换器与总线的其余部分通信。  这之前已经过测试、可以看到、仍然可以正常工作。
    • 在开发5667通信时、我以前没有辅助函数 read_Byte/read_word/write_byte/write_word。  现在、我已经尝试在5667上同时使用 write_byte 和扩展代码。

    示例代码:

        case 0:
            ack = i2c_write_byte(AD5667_ADDRESS, AD5667_CMD_REF_SETUP + AD5667_REG_DAC_A);
    /*        Wire.beginTransmission(AD5667_ADDRESS);
            Wire.write(AD5667_CMD_REF_SETUP + AD5667_REG_DAC_A);
            Wire.write(1);
            ack = Wire.endTransmission();
    */        sprintf(buf,"Response: %d",ack);
            Serial.println(buf);
            Wire.beginTransmission(AD5667_ADDRESS);
            Wire.write(AD5667_CMD_REF_SETUP + AD5667_REG_DAC_B);
            Wire.write(1);
            ack = Wire.endTransmission();
            sprintf(buf,"Response: %d",ack);
            Serial.println(buf);
            break;

    DAC A 通过 WRITE_BYTE 启用、DAC B 采用扩展代码(主要仍然仅为 WRITE_BYTE)。  I2C 波形捕获:

    So..functions 工作正常、AD5667似乎没有这种幽灵。

    我将在接下来的几个小时内在 ADS1119上返回尝试一些具有扩展代码与函数的 A-B 比较、并将我的结果发布在此处。

    此致、

    PS 我在 AIN0上设定了1V、并选择了内部基准、所以我认为我应该看到~40%满量程(26214或此处)。  我看到了0。  因此尚未修复。

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

    您好、Hugh、

    请记住、对于 DAC、您只会向器件发送写入数据。  使用 ADS1119、您可以发送一个写入命令、该命令似乎工作正常、但在读取之后、您会看到显示第二次的写入命令。  执行读取操作后的某个时刻、会向器件发送第二个写入命令。  这意味着循环中的某个位置有另一个写入命令正在执行前面的命令内容。

    此致、

    鲍勃 B

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

    尊敬的 Bob:

    你说的对,我犯了一个傻的错误,我不想在很长一段时间内。  Arduino 不需要 endTransmission 后一个请求源;这导致了以前的写命令的无关重新发布(这显然仍然在缓冲区,从上次写入的东西被写入)。

    更新了代码:

    uint16_t i2c_read_word(byte addr)
    {
      byte ack, hbyte = 0, lbyte = 0;
      uint16_t readback = 57;
      Wire.requestFrom(addr, 2);
      //ack = Wire.endTransmission();
      //if (ack > 0) return(ack);
      delay(10);
      Serial.print("Available: ");
      Serial.println(Wire.available());
      hbyte = Wire.read();
      lbyte = Wire.read();
      Serial.println(hbyte);
      Serial.println(lbyte);
      readback = hbyte << 8;
      readback |= lbyte;
      return(readback);
    }

    新范围屏幕截图:

    而仍将得到错误的回读。

    此时、我相当有信心与 IC 正确通信;这更像是硬件问题、而不是软件问题、即使我的软件继续需要改进和改进。

    我认为我将 AVDD 设置为高于 DVDD 的电压、并将 REFP 连接到 AVDD 等等。  ADS1119是否存在能够持续引发供电型通信 ADC 问题的已知条件、一致的0还是一致的 FFFF?

    提前感谢。

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

    您好、Hugh、

    RDATA 命令似乎可以正常运行、但在读取寄存器数据时是否也解决了类似问题?  我建议您验证 RREG 命令也能正常工作、并且数据后面没有重复的命令写入。

    在一些早期示波器截图中、您表明 DRDY 正在切换。  情况仍然如此吗?  将 ADS1119配置为连续转换模式后、需要发出 START/SYNC 命令。  你在干什么?"  ADS1119默认为单次模式。  将寄存器设置为连续模式时、您需要发出 START/SYNC 命令来启动转换。  否则、RDATA 命令将仅返回内部转换结果缓冲区中的内容、不会显示有效的转换数据。

    另一个可能的问题可能与电源有关。  如果在 ADC 开始转换并消耗更多功率时出现电压骤降(可能是电源/接地连接不良)、则 ADC 可能已复位到默认条件。  如果您在 START/SYNC 命令后读取寄存器、则如果看到默认值而不是先前编程的值、则很可能发生器件复位。  ESD 或输入过压也可能导致器件复位。  这些只是使用试验电路板进行原型设计时可能遇到的一些硬件问题。

    此致、

    鲍勃 B

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

    操作成功!  不过、我要逐一阐述一下您的每一个要点。

    我之前检查过 RREG0和 RREG1的回读;它们都能正常工作、I2C 看起来正确、结尾没有多余的写法。

    问题是开始了;我没有做到。  IC 功能开始工作后、我将创建更好的函数来控制 IC 的所有方面。

    我看到的最后一个问题(根本不是大问题)是 VREF_INT 看起来是正确读回电压、VREF_EXT (REFP 连接到 AVDD、REFN 连接到公共 GND)读取 AIN0/2。

    我将在整个 ADC 范围内表征更多的特性、以验证线性等、但我认为确实是这样。  谢谢你,非常,耐心地工作我通过我的愚蠢的错误。

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

    您好、Hugh、

    很高兴听到您取得了进展。  至于您在使用外部基准时读回的值、请记住、您需要在计算中将代码值调整为 AVDD 电源电压。  内部基准为2.048V、施加1V 输入电压时、您将获得约1/2的满量程、但满量程随着基准电压的增大而变化。  这会使返回的代码少得多、因为现在满量程范围会增加、从而使一个代码的值更大。

    LSB (或单个代码的值)=+/- VREF /(2^16 - 1)= 2* VREF / 65535

    即2.048V 基准电压为62.5uV、5V 基准电压为152.6uV。

    此致、

    鲍勃 B

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

    尊敬的 Bob:

    粘贴在下面的特征值:

    DAC V ADC RBK INT ADC V V-V0 ADC RBK EXT ADC V V-V0
    0.0015 12 0.000916 5 0.000763
    0.1 1614 0.12314 0.122225 662 0.101013 0.10025
    0.2 3213 0.245136 0.121996 1317 2009年0月58日 0.099945
    0.3 4811 0.367056 0.12192 1972年 0.300903 0.099945
    0.4 6406 0.488746 0.121691 2626 0.400696 0.099792
    0.5 8002 0.610513 0.121767 3281 0.500641 0.099945
    0.6 9599 0.732357 0.121843 3935 0.600433 0.099792
    0.7 11194 0.854047 0.121691 4589 0.700226 0.099792
    0.8 12790 0.975814 0.121767 5243 0.800018 0.099792
    0.9 14388 1.097734 0.12192 5899 0.900116 0.100098
    1 15988 1.219806 0.122072 6555 1.000214 0.100098
    1.1 17584 1.341573 0.121767 7209 1.100006 0.099792
    1.2 19182 1.463493 0.12192 7864 1.199951 0.099945
    1.3 20781 1.585489 0.121996 8520 1.300049 0.100098
    1.4 22379 1.707408 0.12192 9175 1.399994 0.099945
    1.5 23977 1.829328 0.12192 9830 1.499939 0.099945
    1.6 25574 1.951171 0.121843 10485 1.599884 0.099945
    1.7 27173 2.073167 0.121996 11140 1.699829 0.099945
    1.8 28770 2.19501 0.121843 11795 1.799774 0.099945
    1.9 30367 2.316854 0.121843 12450 1.899719 0.099945
    2 31964年 2.438697 0.121843 13105 1.999664 0.099945
    2.1 32767 2.499962 0.061265 13759 2.099457 0.099792
    2.2 14414 2.199402 0.099945
    2.3 15069 2.299347 0.099945
    2.4 15724 2.399292 0.099945
    2.5 16379 2.499237 0.099945
    2.6 17033 2.59903 0.099792
    2.7 17687 2.698822 0.099792
    2.8 18343 2.79892 0.100098
    2.9 18998 2.898865 0.099945
    3 19673年 3.001862 0.109997
    3.1 20327 3.101654 0.099792
    3.2 20982 3.201599 0.099945
    3.3 21644 3.302612 0.101013
    3.4 22299 3.402557 0.099945
    3.5 22953 3.50235 0.099792
    3.6 23608 3.602295 0.099945
    3.7 24264 3.702393 0.100098
    3.8 24919 3.802338 0.099945
    3.9 25580 3.903198 0.100861
    4 26235 4.003143 0.099945
    4.1 26891 4.103241 0.100098
    4.2 27546 4.203186 0.099945
    4.3 28200 4.302979 0.099792
    4.4 28855 4.402924 0.099945
    4.5 29509 4.502716 0.099792
    4.6 30164 4.602661 0.099945
    4.7 30825 4.703522 0.100861
    4.8 31480 4.803467 0.099945
    4.9 32134 4.903259 0.099792

    我的 DAC 具有~3mV 的偏移、我在3.0V 时对其进行了补偿、这是由于值的轻微跳变。  2.048的内部基准在施加到5V 电压时提供了一个有问题的比例因子(4.096显然是理想之选)。  但外部基准似乎工作得很好、并适用于我将要用于的已熔断的电源电压...嗯、相当多的电源电压。  顺便说一下、线性度对于我公认不是特别精细的应用而言非常好。

    再次感谢您的全力帮助、我现在可以将 CAD 向上升级电路板。