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.

[参考译文] ADS8691:SPI 通信问题。

Guru**** 2555640 points
Other Parts Discussed in Thread: ADS8691

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

https://e2e.ti.com/support/data-converters-group/data-converters/f/data-converters-forum/611314/ads8691-problems-with-spi-communications

器件型号:ADS8691

尊敬的所有人:


我正在尝试从 MCU 上的 ADS8691获取转换的信号。

它似乎执行 ADC 的复位和基本通信、但是在寄存器设置中、为了获得准确的转换数据、似乎存在问题。

我在进入固件中的环路之前设置寄存器、示波器波形看起来正常。 然而、当调用采样率为每秒16、384的转换值时、SPI 通信波形看起来异常。

我在初始寄存器设置中设置器件地址和 ADC 输入范围、并在数据表的表6中设置 DATAOUT_CTL_REG 的值、以便在输出数据字中检查这些值。 (DATAOUT_CTL_REG 的值为0x5508)

观察到与输出数据字相对应的 SPI 通信波形后、确认​​转换结果后的标志值无法正常读取。

此外、还确认转换结果值与初始 ADC 输入范围寄存器值相同、不会输出。 并确认转换结果值的范围与初始设置寄存器值(0000b)相对应、而不是 ADC 输入范围寄存器设置的值。

转换结果后 ADC 输入范围[5:2]的位值似乎不规则、并且之前设置的器件地址值不显示。


我附加了 C 代码和 示波器屏幕截图。

如果您对此 ADC 有任何经验、请告知我出错了。

如果您有一个与此 ADC 或 ADC 以相同方式运行的 C 代码示例、您会与我分享吗? 请将其发送至 midoh.in.here@gmail.com。

======================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================== //

#include "main.h"
#include "stm32f7xx_hal.h"
#include "dma.h"
#include "spi.h"
#include "TIM.h"
#include "USART.h"
#include "gpio.h"

/*用户代码 begin 包括*/
#define CLEAR_HWORD 0x6000
#define READ_HWORD  0xC800
#define 读取                  0x4800
#define WRITE               0xD000
#define WRITE_MS         0xD200
#define WRITE_LS         0xD400
#define SET_HWORD     0xD800

#define DEVICE_ID_REG        0x02 //器件 ID 寄存器
#define RST_PWRCTL_REG  0x04 //复位和电源控制寄存器
#define SDI_CTL_REG           0x08 // SDI 数据输入控制寄存器
#define SDO_CTL_REG          0x0C // SDO-x 数据输入控制寄存器
#define DATAOUT_CTL_REG 0x10 //输出数据控制寄存器
#define RANGE_SEL_REG     0x14 //输入范围选择控制寄存器
#define ALARM_REG             0x20 // ALARM 输出寄存器
#define ALARM_H_TH_REG  0x24 //警报高阈值和迟滞寄存器
#define ALARM_L_TH_REG  0x28 //警报低阈值寄存器


uint16_t ADC_Command = 0;
uint32_t ADC_Result = 0;
/*用户代码末尾包括*/

/*私有变量------------------------------------------------------- *

/*用户代码 begin PV */
/*私有变量------------------------------------------------------- *
extern uint8_t TIM7_Flag;
uint8_t SPI1_ADC_RxBuffer[8]={0};
uint8_t SPI1_ADC_TxBuffer[8]={0};

/*用户代码末尾 PV */

/*私有函数原型------------------------------------------------------- *
void SystemClock_Config (void);
静态空 MX_NVIC_Init (空);

/*用户代码 begin PFP */
/*私有函数原型------------------------------------------------------- *

/*用户代码末尾 PFP */

/*用户代码开始0 */

/*用户代码结束0 */

int main (空)

 /*用户代码 begin 1 */

 /*用户代码结束1 */

 /* MCU 配置------------------------------------------------------- *

 /*复位所有外设、初始化闪存接口和 SysTick。 *
 HAL_Init();

 /*用户代码 begin Init */

 /*用户代码结束初始化*/

 /*配置系统时钟*/
 SystemClock_Config();

 /*用户代码 begin sysinit */

 /*用户代码结束 sysinit */

 /*初始化所有已配置的外设*/
 mx_GPIO_Init();

 HAL_GPIO_WritePin (GPIOA、GPIO_PIN_4、GPIO_PIN_RESET);                            // SPI1_NSS 引脚变为低电平
 HAL_GPIO_WritePin (GPIOA、GPIO_PIN_5、GPIO_PIN_RESET);                             // SPI1_SCK 引脚变为低电平
 HAL_GPIO_WritePin (ADC_RST_GPIO_Port、ADC_RST_Pin、GPIO_PIN_RESET); // ADC 复位
 HAL_DELAY (100);
 HAL_GPIO_WritePin (ADC_RST_GPIO_Port、ADC_RST_Pin、GPIO_PIN_SET);

 mx_dma_Init();
 mx_SPI1_Init();  // SPI_CS 由硬件控制
 mx_SPI4_Init();
 MX_TIM6_Init();
 MX_TIM7_Init();
 mx_USART1_UART_Init();

 /*初始化中断*/
 mx_NVIC_Init();
 
 HAL_TIM_Base_Start_IT (&htim7); //用于 ADC 采样


 /*用户代码 begin 2 */


  //////// 将器件地址设置为0x05
  ADC_Command =写入+ DEVICE_ID_REG;
  SPI1_ADC_TxBuffer[0]=(uint8_t)(ADC_Command >> 8);
  SPI1_ADC_TxBuffer[1]=(uint8_t) ADC_Command;
  SPI1_ADC_TxBuffer[2]= 0x00;
  SPI1_ADC_TxBuffer[3]= 0x05;

  HAL_SPI_Transmit _DMA (&hspi1、SPI1_ADC_TxBuffer、4);
  while (hspi1.State == HAL_SPI_State_Busy_TX);   

  //------------------------------------------- //

  //////// 设置 ADC 输入范围并禁用内部参考
  ADC_Command =写入+ RANGE_SEL_REG;
  SPI1_ADC_TxBuffer[0]=(uint8_t)(ADC_Command >> 8);
  SPI1_ADC_TxBuffer[1]=(uint8_t) ADC_Command;
  SPI1_ADC_TxBuffer[2]= 0x00;
  //SPI1_ADC_TxBuffer[3]= 0x20;  //±3V * Vref 和内部参考禁用
  SPI1_ADC_TxBuffer[3]= 0x43; // ±1.25V * Vref 和内部参考禁用

  HAL_SPI_Transmit _DMA (&hspi1、SPI1_ADC_TxBuffer、4);
  while (hspi1.State == HAL_SPI_State_Busy_TX);   

  //------------------------------------------- //
  
  //////// 设置 DATAOUT_CTL_REG 值与表6相同。 数据表中
  ADC_Command =写入+ DATAOUT_CTL_REG;
  SPI1_ADC_TxBuffer[0]=(uint8_t)(ADC_Command >> 8);
  SPI1_ADC_TxBuffer[1]=(uint8_t) ADC_Command;
  SPI1_ADC_TxBuffer[2]= 0x55;
  SPI1_ADC_TxBuffer[3]= 0x08;

  HAL_SPI_Transmit _DMA (&hspi1、SPI1_ADC_TxBuffer、4);
  while (hspi1.State = HAL_SPI_State_Busy_TX);
  
  //------------------------------------------- //

  HAL_SPI_MspDeInit (&hspi1);  //软件控制 SPI_CS

//====================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================

 /*用户代码末尾2 */

 /*无限循环*/
 /*用户代码在*/时开始
 while (1)
 {
 /*用户代码结束,同时*/
 IF (TIM7_Flag)  //由 Timer7启动的标志(16.384kHz)
 {

  HAL_GPIO_WritePin (GPIOA、GPIO_PIN_4、GPIO_PIN_SET);    // SPI_CS 高电平
  SPI1_ADC_RxBuffer[0]= 0;                              // CS 高电平保持和 RxBuffer Init
  SPI1_ADC_RxBuffer[1]= 0;    // CS 高电平保持和 RxBuffer Init
  SPI1_ADC_RxBuffer[2]= 0;    // CS 高电平保持和 RxBuffer Init
  SPI1_ADC_RxBuffer[3]= 0;    // CS 高电平保持和 RxBuffer Init
  HAL_GPIO_WritePin (GPIOA、GPIO_PIN_4、GPIO_PIN_SET); // SPI_CS 高电平
  HAL_GPIO_WritePin (GPIOA、GPIO_PIN_4、GPIO_PIN_RESET); // SPI_CS 低电平
  
  HAL_SPI_Receive_DMA (&hspi1、SPI1_ADC_RxBuffer、4);     //读取转换结果和所有数据标志。

  // 提取转换结果
  ADC_Result =(uint32_t)(SPI1_ADC_RxBuffer[0]<< 10);    
  ADC_Result = ADC_Result +(uint32_t)(SPI1_ADC_RxBuffer[1]<< 2);
  ADC_Result = ADC_Result +(uint32_t)(SPI1_ADC_RxBuffer[2]>> 6);


 TIM7_Flag = 0;
 }
 /*用户代码 begin 3 */

 }
 /*用户代码结束3 */

============================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!
    感谢您提出问题。 我们将很快与您联系。
    此致、
    Cynthia
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 、Young-Kyo Oh、

    您可以读取您已写入的寄存器吗? 确保所有时序都正确并且标志位的寄存器按照您的需要进行设置(DATAOUT_CTL_REG 为0x5508)将会非常有帮助。

    此外、如果可能、请提供已放大的屏幕截图、以便在32个 SCLK 周期的每个周期读取 SDO 行。

    谢谢、

    Reed Kaczmarek

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

    当我重新读取我写入的寄存器时、寄存器值未正常输出。

    我确信在某个地方会出现问题。
    例如、初始化过程或将值写入寄存器的顺序。

    将在几个小时内发布 zoomin 屏幕截图。


    是否有任何技术文档或示例代码可用于使 ADS8691正常工作?

    如果是、请分享。

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

    感谢您的关注-分享放大后的屏幕截图后、我将仔细查看您的时间安排。

    遗憾的是、ADS8691没有示例代码。 我们将需要确认您的计时不违反数据表图3或图4中的示例。

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

    感谢您的重播、

    我在这一问题上取得了一些进展。

    执行了寄存器写入命令以将输入范围调整为±1.25 * Vref、但寄存器值未被保留。
    我在读取每个采样的 ADC 值之前执行了输入范围控制寄存器写入命令、并获得了所需的结果。

    这是一个问题。 如果 ADS8691在复位操作后执行一条寄存器值写入指令、设置的值是否在下一次复位前不会被保持?
    我是否需要在每个 ADC 读取命令之前写入一个寄存器值、就像我已经解决了这个问题一样?

    据我所知、ADS8691知道、在写入函数的寄存器值后、在复位后进入循环之前、它将一直保持到下一次复位。

    我正在准备示波器的屏幕截图、以确定问题的确切原因。
    它将在大约7到8小时内上传。 我真诚地要求您以清晰的信号视图分析您的信号。

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

    下面是我的电阻器设置示例代码和 示波器的屏幕截图。

    mx_GPIO_Init();
    //======================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================== //
    HAL_GPIO_WritePin (GPIOA、GPIO_PIN_4、GPIO_PIN_RESET);          // SPI_NSS 引脚变为低电平
    HAL_GPIO_WritePin (GPIOA、GPIO_PIN_5、GPIO_PIN_RESET);          // SPI_SCK 引脚变为低电平
    HAL_GPIO_WritePin (ADC_RST_GPIO_Port、ADC_RST_Pin、GPIO_PIN_RESET);       // ADC 复位打开
    HAL_DELAY (1000);
    HAL_GPIO_WritePin (ADC_RST_GPIO_Port、ADC_RST_Pin、GPIO_PIN_SET);         // ADC 复位关闭
    HAL_DELAY (1000);
    HAL_GPIO_WritePin (GPIOA、GPIO_PIN_4、GPIO_PIN_SET);          // SPI_NSS 引脚变为高电平
    //======================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================== //
    mx_dma_Init();
    mx_SPI1_Init();
    mx_SPI4_Init();
    MX_TIM6_Init();
    MX_TIM7_Init();
    mx_USART1_UART_Init();

    mx_NVIC_Init();

    ADC_Command = 0xD000 + 0x14  //==(WRITE + RANGE_SEL_REG)
    SPI1_ADC_TxBuffer[0]=(uint8_t)(ADC_Command >> 8);
    SPI1_ADC_TxBuffer[1]=(uint8_t) ADC_Command;
    SPI1_ADC_TxBuffer[2]= 0x00
    SPI1_ADC_TxBuffer[3]= 0x03   //=±5.12V 范围命令

    HAL_SPI_Transmit _DMA (&hspi1、SPI1_ADC_TxBuffer、4); //发送写入命令
    while (hspi1.State = HAL_SPI_State_Busy_TX);       //等待传输完成。

    //===缓冲区初始化===//
    SPI1_ADC_TxBuffer[0]= 0;
    SPI1_ADC_TxBuffer[1]= 0;
    SPI1_ADC_TxBuffer[2]= 0;
    SPI1_ADC_TxBuffer[3]= 0;

    SPI1_ADC_TxBuffer[0]= 0;
    SPI1_ADC_TxBuffer[1]= 0;
    SPI1_ADC_TxBuffer[2]= 0;
    SPI1_ADC_TxBuffer[3]= 0;

    //================================================ //


    ADC_Command = 0xC800 + 0x14  //==(READ_HWORD + RANGE_SEL_REG)
    SPI1_ADC_TxBuffer[0]=(uint8_t)(ADC_Command >> 8);
    SPI1_ADC_TxBuffer[1]=(uint8_t) ADC_Command;
    SPI1_ADC_TxBuffer[2]= 0x00
    SPI1_ADC_TxBuffer[3]= 0x00  

    HAL_SPI_Transmit _DMA (&hspi1、SPI1_ADC_TxBuffer、4); //发送读取半字命令
    while (hspi1.State = HAL_SPI_State_Busy_TX);       //等待传输完成。

    HAL_SPI_recvi_DMA (&hspi1、SPI1_ADC_RxBuffer、4); // SPI 接收
    while (hspi1.State = HAL_SPI_State_Busy_RX);       //等待接收完成。


    HAL_SPI_MspDeInit (&hspi1);                        //更改手动控制 SPI_NSS 引脚的设置。


    //==================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================== //

    //用户代码…… //

    // void main()

     while (1){}



    //==================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================== //


    每  秒16.384k 中断的空 Timer_Callback (TIM_HandleTypeDef * htim)//计时器。

    "读取转换结果命令"

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

    我的第一条评论是、CS/CNVST 信号需要在第32个 SCLK 脉冲之后上升回 DVDD。 请参阅数据表中的图3和图4、了解帧后 CS/CONVST 上升的时序。

    此外、写入命令会在 CS/CONVST 信号的上升沿执行(数据表第41页的底部)、因此、由于 CS/CNVST 在写入命令之后不上升、因此可能无法正确保存 RANGE_SEL_REG。

    请调整您的 CS 信号以匹配数据表中的时序图、然后我们可以继续此调试。

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

    尊敬的 Reed Kaczmarek 先生:

    您的建议非常恰当和准确。

    根据您的建议、我在寄存器写入命令之前和之后添加了 CONVST /CS 信号、现在我将查看 ADS8691、它完全符合我的预期。

    感谢你的建议。

    此致。