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.

[参考译文] ADS1158:共享 SPI 总线

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

https://e2e.ti.com/support/data-converters-group/data-converters/f/data-converters-forum/1297257/ads1158-shared-spi-bus

器件型号:ADS1158

尊敬的 TI 论坛:

我在共享 SPI 总线上有3个 ADS1158。 我们将其称为 ADC A、B 和 C。我使用2个 GPIO 来切换多路复用器、以便正确设置每个 ADC 的片选引脚。 多路复用器为 SNx4HC139。 每个 DRDY 引脚连接至3个 GPIO、每个 ADC 一个。 ADC A 和 B 的配置相同(现在我们忽略 ADC C):

11月28日13:21:42 raspberrypi acquisition[163587]:[INFO] ADC 0 RESET (参考资料)。
11月28日13:21:42 raspberrypi acquis[163587]:[info] adc 1 reset。
11月28日13:21:42 raspberrypi acquis[163587]:[INFO] ADC 已成功配置。 ADC 配置:
Nov 28 13:21:42 raspberrypi acquisition [163587]:[INFOC]寄存器0x0值0x5e
Nov 28 13:21:42 raspberrypi acquisition [163587]:[INFOC]寄存器0x1值0x31
Nov 28 13:21:42 raspberrypi acquisition [163587]:[INFOC]寄存器0x2值0x0
Nov 28 13:21:42 raspberrypi acquisition [163587]:[INFOC]寄存器0x3值0xF
Nov 28 13:21:42 raspberrypi acquisition [163587]:[INFOC]寄存器0x4值0x0
Nov 28 13:21:42 raspberrypi acquisition [163587]:[INFOC]寄存器0x5值0x0
Nov 28 13:21:42 raspberrypi acquisition [163587]:[INFOC]寄存器0x6值0x0
Nov 28 13:21:42 raspberrypi acquisition [163587]:[INFOC]寄存器0x7值0x7f
Nov 28 13:21:42 raspberrypi acquisition [163587]:[INFOC]寄存器0x8值0x0
Nov 28 13:21:42 raspberrypi acquisition [163587]:[INFOC]寄存器0x9值0x9b

我尝试按以下顺序对 ADC 进行采样(为简单起见、我将忽略 ADC C):

切换 MUX 以选择 ADC A。

2.发送开始采样脉冲到 ADC A (参见下面的代码)。

3.切换 MUX 以选择 ADC B。

4.发送开始采样脉冲到 ADC B。

5.切换 MUX 以选择 ADC A。

6.轮询其 DRDY GPIO、如果该引脚变为0、则使用通道数据读取命令从 ADC A 读取数据(请参阅下面的代码)。

7.切换 MUX 以选择 ADC B。

8.对其 DRDY GPIO 进行轮询,如果它变为0,则使用通道数据读取命令从 ADC B 测试数据。

开始采样脉冲:

字符脉冲= 0b10000000;
SPI_send (handle、&pulse、NULL、sizeof (pulse));

通道数据读取命令:

char TX[]={ 0b00110000、0x00、0x00、0x00 };
SPI_send (handle、TX、Rx、sizeof (TX));

带有超时标志的整个读取通道命令:

bool adc_read_channel (int ready、int handle、char* rx){
   uint8_t GPIO = 0;
   uint32_t start = gpioTick ();
   uint32_t current = gpioTick ();
   INT DIFF = CURRENT - START;
   while (GPIO == 1 && diff < TIMEOUT){
      GPIO = gpioRead (就绪);
      电流= gpioTick ();
      DIFF = CURRENT - START;
   }

   如果(diff >= TIMEOUT){
      返回 false;
   }

   //读取采样
   char TX[]={ 0b00110000、0x00、0x00、0x00 };
   SPI_send (handle、TX、Rx、sizeof (TX));

   返回 true;

我经常会在 ADC B 上获得超时(这意味着它的 DRDY 引脚在100ms 内不会变为低电平、或者在处理 ADC A 的 SPI 传输时将其复位)。 我添加了一些日志:

Nov 28 13:13:52 raspberrypi acquis[162518]:[info] adc a channel 0开始采样 drdy a 1 b 1 c 1 cs 0 cs (mux 0b01选择 adc a)
11月28日13:13:52 raspberrypi acquis[162518]:[info] adc b channel 0开始采样 drdy a 1 b 1 c 1 cs 0 cs (mux 0b00选择 adc B)
11月28日13:13:52 raspberrypi acquis[162518]:[info]在信道读取之前 drdy a 0 b 1 c 1 cs 0 cs
11月28日13:13:52 raspberrypi acquis[162518]:[info]通道读取后 drdy a 1 b 1 c 1 cs 0 cs 1 (按预期、ADC A 从低切换到高)
11月28 13:13:52 raspberrypi 采集[162518]:DRDY 引脚26 GPIO 值(低电平有效)上的[ERROR] ADC 超时1个差分100000 (100ms)。
11月28日13:13:52 raspberrypi 采集[162518]:[错误] DRdy a 1 b 1 c 1 (ADC B 的 DRDY 引脚在 while 循环期间从不切换)
11月28日13:13:52 raspberrypi acquis[162518]:[错误] cs 1 0 cs 2 0 (多路复用器选择0b00 adc B)

对于 ADC A、此电路工作正常、但未检测到来自 ADC B 的 DRDY 变为低电平。 或者在进入该环路之前它可能先变为低电平、然后又变为高电平、但我不确定什么可能会复位 DRDY。

Question:

1.当 SCLK 针对另一个 ADC 运行时、即使其 CS 为高电平、DRDY 是否会复位? 这是一个共享的 SPI SCLK、数据表显示 DRDY 在 SCLK 的第一个下降沿恢复为高电平。

ADC B 是否也能从 ADC A 获取命令并在其 CS 处于高电平时对这些命令做出反应?

3、有时能用,有时不能用。 如果我在这里和那里添加一些人为的延迟、但这并不一致、这是有效的。 其他什么因素可能导致 DRDY 复位?

4.我是否应该完全忽略 DRDY 并仅依赖于 STATUS 字节中的新位?

非常感谢!

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

    我还要补充一点、它在以下序列中工作稳定:


    1.开始在 ADC A 上采样

    2.读取 ADC A 中的样本

    切换 MUX 并开始在 ADC B 上采样

    4.读取 ADC B 中的样本

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

    尊敬的 Remus Mihail Prunescu:

    您在上一篇文章中描述的第二个问题作为解决方案是否可以接受? 与仅将每个器件的 START 引脚连接在一起并同时进行切换相比、您是否需要按顺序开始对器件进行采样?

    当然、如果您通过 DRDY 信号进行多路复用、则可能会错过其中一个高电平低电平转换。 从数据表中的图43可以看出 DRDY 脉冲非常短。 通常、您可能希望使用中断驱动型 GPIO 来检测此转换、并让您的数据回读例程知道可以对新数据进行采样

    -Bryan

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

    您好、Bryan:

    感谢您的答复。 这实际上是我需要确认的、即 DRDY 信号是一个脉冲、在读取采样之前不会永远保持高电平(即使 CS 未选择 ADC)。 数据表顶部的第23页显示 DRDY 在第一个 SCLK 下降沿变为高电平、我认为由于 CS 没有选择 ADC、DRDY 将保持低电平、直到我在该 ADC 上运行 SCLK。

    我将重新考虑固件并使用中断。

    谢谢!

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

    尊敬的 Remus Mihail Prunescu:

    DRDY 输出与 CS 无关-请参见数据表第27页的 CS 部分。 因此、假定 ADC 正在转换新数据、DRDY 将指示新数据是否就绪、CS 为低电平或高电平

    如前所述、DRDY 的行为会根据是否发出 SCLK 而变化。 这如第23页的图39所示。  但无论哪种情况、您都是在 DRDY 上寻找从高电平到低电平的转换-这表明数据是新数据。 不同之处在于、如果您发出 SCLK、DRDY 将被强制为高电平、而如果您不发出 SCLK、DRDY 将保持低电平、但图2及其后续表给出了低电平-高电平-低电平脉冲除外。

    -Bryan

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

    您好!

    我已经决定尝试从状态字节中轮询新位、因为中断在我的平台(运行 Linux 的 PI)上具有很大的延迟。 但是、有时在设置新位时、我会读取垃圾数据。 在 ADC 写入数据时、是否存在实际读取数据的危险? 我不发出任何其他脉冲命令来启动转换(仅发出1个脉冲命令、然后我轮询 STATUS 字节)。 以下是我的轮询循环:

    uint32_t start = gpioTick ();
    uint32_t current = gpioTick ();
    INT DIFF = CURRENT - START;
    char TX[]={ 0b00110000、0x00、0x00、0x00 };
    bool new = false;

    while (!new && diff < timeout){
      电流= gpioTick ();
      DIFF = CURRENT - START;
      SPI_send (handle、TX、Rx、sizeof (TX));
      NEW =(Rx[1]&(1<<7))> 0;

    Rx 中的数据噪声非常大。 但是、如果我在检测到新的位设置后进行重新读取:

    while (!new && diff < timeout){
      电流= gpioTick ();
      DIFF = CURRENT - START;
      SPI_send (handle、TX、Rx、sizeof (TX));
      NEW =(Rx[1]&(1<<7))> 0;
      如果(新){
        gpioDelay (20);
        SPI_send (handle、TX、Rx、sizeof (TX));
        Rx[1]|=(1 <<7);
      }

    在这种情况下、数据看起来更干净。

    当 ADC 置位新位时、是整个寄存器被写入还是正在同时写入它?

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

    没关系。 我发现了问题。 我没有在代码中的某个位置使用通道 ID、并且交换了数据。 现在看起来很好。

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

    尊敬的 Remus Mihail Prunescu:

    我很高兴您能够解决此问题、我们现在将考虑将其关闭

    如果您有其他问题、您可以随时启动新主题帖

    -Bryan