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.

[参考译文] ADS8867:ADS8867 GPIO/SPI 模式无法获得正确的 ADC 值

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

https://e2e.ti.com/support/data-converters-group/data-converters/f/data-converters-forum/873777/ads8867-ads8867-gpio-spi-mode-can-not-get-correct-adc-value

器件型号:ADS8867
主题中讨论的其他器件: ADS8166ADS8866

大家好、我在使用 ADS8867进行开发时遇到了一些问题、在 GPIO 模式和 SPI 模式下无法获得正确的 ADC 值。

1 /在 GPIO 模式中。

解决方案1.

GPIO 配置:

DIN:输出推挽模式、最大速度50m,高

CONVEST:输出推挽模式、最大速度50m

SCLK:输出推挽模式、最大速度50m

DOUT:输入模式,浮动输入

void bsp_adc_ads8867_init (void)
{
GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.Mode = GPIO_MODE_OUTPSI_PP;
GPIO_InitStructure.Speed = GPIO_SPED_FREQ_HIGH;
GPIO_InitStructure.Pin = ADC_ADS867_PIN_SCK | ADC_ADS867_PIN_CNV;
HAL_GPIO_Init (ADC_ADS867_GPIO_PORT、&GPIO_InitStructure);

GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
GPIO_InitStructure.Speed = GPIO_SPED_FREQ_HIGH;
GPIO_InitStructure.Pull = GPIO_PULLUDOWN;
GPIO_InitStructure.Pin = ADC_ADS867_PIN_SDO;
HAL_GPIO_Init (ADC_ADS867_GPIO_PORT、&GPIO_InitStructure);

TCNV (0);//CONVEST 为低电平
TSCK (0);//SCLK 低
电平}

uint16_t BSP_ADC_ads8867_read (void)
{
uint8_t i;
uint16_t temp = 0;
GPIO_InitTypeDef GPIO_InitStructure;

TCNV (0);//CONVEST 为低电平
ADC_ADS867_CONV_LOW_DELAY ();//CONVEST 低延迟约为16ns
TCNV (1);//CONVEST 高电平并进入转换阶段。
ADC_ADS867_CONV_HIGH_DELAY ();//CONVEST 高延迟约为6000ns 或12000ns
TCNV (0);//CONVEST 为低电平

for (i=0;i<16;i++)
{
温度<<= 1;
TSCK (1);//SCLK 高电平
ADC_ADS867_SCLK_HIGH_DELAY ();//SCLK 高延迟48ns。 f(SCLK)< 16MHz。
TSCK (0);//SCLK 低

电平 IF (TSDO = 1)//读取 DOUT
{
temp |= 0x0001;
}
ADC_ADS867_SCLK_LOW_DELAY ();//SCLK 低延迟48ns.F(SCLK)< 16MHz
。}
返回温度;
} 

定时器2 ISR 函数中调用的 bsp_adc_ads8867_read()函数、定时器2的周期为1ms。

如果 CONVEST 高延迟约6000ns,我无法获得正确的 ADC 值、则所有 ADC 值均为零。

如果 CONVEST 高延迟约为12000ns、我可以获得正确的 ADC 值,但 ADC 值有时为零。

我在示波器上查看时序图、它看起来只有 SCLK 的下降沿、数据是故障和开始输出。

因此、我按如下方式更改代码、但仍然无法解决问题。

解决方案2.

uint16_t bsp_adc_ads8867_read (void)
{
uint8_t i;
uint16_t temp = 0;

TCNV (0);//CONVST 低电平
ADC_ADS867_CONV_LOW_DELAY ();//CONVST 低延迟约为16ns
TCNV (1);//CONVST 高电平
ADC_ADS867_CONV_HIGH_DELAY ();//CONVST 高延迟约为12000ns

/***** 为数据启动输出而下降**** /
TSCK (1);//SCLK 高电平
ADC_ADS867_SCLK_HIGH_DELAY ();//SCLK 高延迟约为48ns.f (SCLK)< 16MHz。
/***** 为数据启动输出而下降**** /

TCNV (0);//SCLK 为低电平
ADC_ADS867_CONV_LOW_DELAY ();//SCLK 低电平大约48ns。 f (SCLK)< 16MHz。

/***** 为数据启动输出而下降**** /
TSCK (0);
ADC_ADS867_SCLK_LOW_DELAY ();
/***** 为数据启动输出而下降**** /

for (i=0;i<16;i++)
{
temp <<= 1;
TSCK (1);//SCLK Low
if (TSDO = 1)//读取 DOUT
{
temp |= 0x0001;
}
ADC_ADS867_SCLK_HIGH_DELAY ();//SCLK 高延迟约为48ns.f (SCLK)< 16MHz。
TSCK (0);//SCLK 低电平
ADC_ADS867_SCLK_LOW_DELAY ();//SCLK 低延迟约为48ns.f (SCLK)< 16MHz
。}
返回温度;
} 

这个解决方案 我可以获得正确的 ADC 值,但 ADC 值有时为零。

我想知道在 GPIO 模式下是否错过任何内容?

2/SPI 模式

静态空 MX_SPI2_Init (空)
{
/* SPI1参数配置*/
hspi2.instance = SPI2;
hspi2.Init.Mode = SPI_MODE_MASTER;
hspi2.Init.Direction = SPI_Directure_2LINES_RXONLY;
hspi2.Init.DataSize = SPI_DATASIZE_16BIT;
//hspi2.Init.DataSize = SPI_DATASIZE _8bit;
hspi2.Init.CLKPolarity = SPI_POLICY_HIGH;
//hspi2.Init.CLKPolarity = SPI_POLICY_LOW;
hspi2.Init.CLKPhase = SPI_PHASE_2EDGE;
//hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi2.Init.nss = SPI_NSS_soft;
//hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;//SPI = 8M
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi2.Init.TIMode = SPI_TIMDE_DISABLE;
hspi2.Init.CRCCalcirc= SPI_CRCCALCULATION_DISABLE;
hspi2.Init.CRCPolynomial = 7;
if (HAL_SPI_Init (&hspi2)!= HAL_OK)
{
_Error_Handler (__file__、__line__);
}
}

void HAL_SPI_MspInit (SPI_HandleTypeDef* hspi)
{

GPIO_InitTypeDef GPIO_InitStruct;

#if 1//for_ad_SPI
if (hspi->instance=SPI2)
{
//用户代码开头 SPI1_MspInit 0 *//

////用户代码结尾 SPI1_MspInit 0 *
/*外设时钟启用*/
_HAL_RCC_SPI2_CLK_ENABLE ();

/** SPI2 GPIO 配置
Pb12. ---- >SPI2_NSS
Pb13. ---- > SPI2_SCK
PB14. ---- > SPI2_MISO
PB15. ---- > SPI2_MOSI
*
GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPED_FREQ_HIGH;
HAL_GPIO_Init (GPIOB、&GPIO_InitStructt);

GPIO_InitStruct.Pin = GPIO_PIN_14;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init (GPIOB、&GPIO_InitStructt);

/*用户代码开始 SPI1_MspInit 1 */

/*用户代码结束 SPI1_MspInit 1 */
}
#endif

}
void BSP_ADC_ads8867_init (void)
{
GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.Mode = GPIO_MODE_OUTPSI_PP;
GPIO_InitStructure.Speed = GPIO_SPED_FREQ_HIGH;
GPIO_InitStructure.Pin = ADC_ADS867_PIN_CNV | ADC_ADS867_PIN_DIN;
HAL_GPIO_Init (ADC_ADS867_GPIO_PORT、&GPIO_InitStructure);

TCNV (0);
tDIN (1);
}

uint16_t bsp_adc_ads8867_read (void)
{
uint8_t i;
uint16_t temp = 0;
GPIO_InitTypeDef GPIO_InitStructure;


HAL_StatusTypeDef ERR_code = HAL_OK;
uint8_t DATA[2];

TCNV (0);
ADC_ADS867_CONV_LOW_DELAY ();
TCNV (1);
ADC_ADS867_CONV_HIGH_DELAY ();
TCNV (0);

ERR_code = HAL_SPI_Receive (&hspi2、data、1、 1000);//SPI 接收
if (err_code!= HAL_OK)
{
Debug_by_LUOGF_printf (0、"[%d][%s][err_code =%d]\r\n"、__line__、__function__、err_code);
}
temp =(uint16_t)((data[0]<<8)|(data[1]<0)
;return temp
} 

定时器2 ISR 函数中调用的 bsp_adc_ads8867_read()函数、定时器2的周期为1ms。

在 SPI 模式0和 SPI 模式3中、ADC 值不正确、ADC 值不等于零。

我想知道在 SPI 模式下是否错过任何内容?

此致。

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

    您好!

    欢迎来到 TI e2e 社区。

    您在哪种模式下操作器件:3线或4线?  仔细查看您的代码、您似乎在3线/CS 模式下运行;DIN 是否一直保持高电平?

    您应该复制数据表图46中显示的波形。  转换在 CONVST 的上升沿开始。  在这个上升沿之后、当 CONVST 为高电平时、您需要等待转换完成、t-conv-max= 8800nS。  在此延迟之后、您可以将 CONVST 拉为低电平、然后将数据时钟从器件中输出。  ADS8166在 CONVST 的下降沿启动 D15、其余位在 SCLK 的下降沿启动。  如果您在 SCLK 的下降沿捕获(读取)数据、ADC 会将当前值保持在3ns 的最小值。

    请发送显示完整传输帧的4个波形(CONVST、DIN、SCLK 和 DOUT)的示波器图片。  我将查看它、看看一切是否正确。

    此致、
    Keith Nicholas
    精密 ADC 应用

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

    您好!

    Keith Nicholas。

    1/GPIO 模式。

    DIN 在 GPIO 模式、 3线/CS 模式下为高电平。

    CONVEST:绿色

    SCLK:黄色

    DOUT:蓝色

    picure1.f(采样)= 30kHz<100kHz

    pictrue2.f (SCLK)<16MHz

    pictrue3.d15详细信息。

    在 GPIO 模式下、如果在下降沿延迟16ns 后读取 D15、则 D15始终为0 (采样电压可以保证 MSB 为1)、D14~D0正常。

    在 GPIO 模式解决方案1中、我在 SCLK (总共16个 SCLK)的下降沿读取 ADC 数据。

    在 GPIO 模式 解决方案2中、我设计一个下降沿并在 SCLK (总共17个 SCLK)的上升沿读取 ADC。  

    soutlion 1和 soutlion 2都可以读取正确的 ADC 值(ADC 值有时为零、D15~D0为0)。这就是  我认为 只有 SCLK 的下降沿、数据为 vaild、开始输出(可以捕获) 的原因。这与数据表所说的不同。

    我不确定我是否对?

    ADC 数据有时始终为0、下次采样时保持为0、只能通过断电来解决、所以我认为电源会导致这个问题、 我们可以在电源电压低时重现这个问题。

    2/SPI 模式

    在 SPI 模式0和模式3中、我无法获取正确的 ADC 值。

    SPI 模式3和 GPIO 模式解决方案2之间的区别在于、SPI 模式3中的默认 SCLK 电压为高电平、   但 GPIO 模式解决方案2中的默认 SCLK 电压为低电平。

    图4、f (采样)= 60kHz < 100KHz

    Pico 5。 f (SCLK)= 8MHz < 16MHz

    图片6.D15详细信息。

    在 SPI 模式下、我会不会错过任何东西吗? 我将在固件的发布版本中使用 SPI 模式。感谢您的关注。

    谢谢。

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

    您好!

    3线/CS 模式的波形看起来正确。  在图3中、您可以看到 MSB 数据在 CONVST 的下降沿启动、从高阻态变为低电平(0)。  此外、图3显示 ADC 在 SCLK 的下降沿启动其他数据。

    图4确认 CONVST 在12us 内为高电平、这大于所需的最短时间8.8uS。  此外、只要在 CONVST 下降沿之后延迟超过12.3nS、MSB 数据位就会有效。

    只要 MCU 满足设置和保持时间、就可以使用 SCLK 的下降沿来捕获数据。  当前数据位将在 SCLK 下降沿之后的3ns 内保持有效、而下一个数据位将在 SCLK 下降沿之后的13.4nS 内保持有效。

    对于 SPI 模式、SCLK 可以空闲高电平、并且只要3ns 的保持时间满足您的 MCU 要求、您就可以在 SCLK 的下降沿捕获数据。

    关于器件锁定并读取所有零、这可能是由于电气过载事件导致的、超过了绝对最大规格。  这可能是电源引脚、基准引脚或任何数字或模拟输入上的过压。  如果电压导致超过10mA 的电流流动、则器件可能会受到永久损坏。  如果流速小于10mA、通常下电上电会纠正问题并使 ADC 恢复正常运行。

    如果您可以向我发送一份原理图、其中显示了输入放大器、基准、ADS8867和电源连接、我将查看是否有什么可以解释器件锁定的原因。

    此致、
    Keith

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

    您好、Keith。

    感谢您的关注。

    我在数据 格式上犯了错误。在 ADS8867数据表的第15页中、设备输出是二进制补码格式。

    ADS8867 DOUT 输出数据是有符号的16位、在我的硬件设计中、AINP 引脚连接到采样电压、AINN 引脚连接到 GND、所以 MSB 是0。正如您和数据表所说、现在在 GPIO 模式和 SPI 模式0下工作正常。

    如果 AINN = 0V 且 AINP = 采样电压、则 ADC 值介于0和32767之间、因此我仅使用15位来采样电压。 如果我想使用16位来采样电压、如何进行设计?

    图片1、ads8867的硬件设计。

    VREF = 4.096V、AVDD 和 DVDD 连接到3.3V 网络。正常  情况下、AINP 不能超过 VREF、我将在下一版本中设计 AINP 的电压限制以保护 ads8867。

    在我的情况下、对于所有的 ads8867 ADC 值都是0、似乎不是输入信号的过压导致了问题。我想知道 AVDD 和 DVDD 的不稳定电压或低电压是否会导致问题?

    感谢您的关注。

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

    您好!

    很高兴您现在能从器件中获得正确的读数!

    要获得完整的16b、您需要向差分驱动器添加单端驱动器。  下面的模拟工程师电路展示了如何执行此操作。  由于您使用的 VREF=4.096V,因此您希望下图中的 VCM 电压为2.048V 或1/2*VREF。  0V 输入电压将导致负满量程读数、即-32768d。  2.048V 的输入电压将导致 读数为0、4.096V 将为32767d。

    http://www.ti.com/lit/an/sbaa265/sbaa265.pdf

    关于器件的锁定、如果 AVDD 或 DVDD 超过绝对最大值规格、则肯定会导致器件停止工作。  如果电压降至2.7V 以下、但并非一直降至0V、则可能导致内部复位无法正常工作。  在这种情况下、您需要执行全功率循环、其中 AVDD 和 DVDD 一直下降到0V、然后重新加电。

    由于您需要单端输入、因此可能需要考虑 ADS8866。  它是引脚对引脚的、支持单端输入。

    此致、
    Keith

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

    您好!

    感谢您的关注、如果我的15位分辨率不适合我的设计、我将尝试使用 ADS8866。