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.

[参考译文] ADS8332:配置和读取CFR寄存器(菊花链)

Guru**** 2560390 points
Other Parts Discussed in Thread: ADS8332

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

https://e2e.ti.com/support/data-converters-group/data-converters/f/data-converters-forum/589865/ads8332-configuration-and-reading-cfr-register-daisy-chain

部件号:ADS8332

您好,

我使用的MCU通过SPI与两个ADS8332's (菊花链)通信,其中MCU是主ADC,两个ADC都是从属ADC。  以下功能显示了CFR寄存器的配置。 两个输入参数(ADS833x_CFR_Reg1和 ADS833x_CFR_Reg2)对应于我要在寄存器中写入的位:

void ADS833x_init(uint16_t ADS833x_CFR_Reg1, uint16_t ADS833x_CFR_Reg2)     //初始化ADS833x

   UINT16_t注册_WORD1;
   UINT16_t注册_文字2;

   UINT16_t ADS833x_Write_COM = 0xE000;
   UINT16_t ADS833x_READ_COM = 0xC000;
   uINT16_t ADS833x_buf[BUF_SIZE];
   
   对于(int i =0;I<BUF_SIZE;I++){
      ADS833x_buf[i]=0;
   }

   REG_WORD1 = ADS833x_Write_COM + ADS833x_CFR_Reg1;
   REG_Word2 = ADS833x_Write_COM + ADS833x_CFR_Reg2;

//清除CS1
   GPIO _PinOutClear (gpioPortB,6);
   USART_TxDouble (USART2,ReG_WORD1);

//等待传输结束
   当(!(USART2->STATUS & USART_STATUSTXC));
   GPIO _PinOutSet (gpioPortB,6);

   while (GPIO_PinOutGet (gpioPortB,6)!=1);

// CS2的过程相同
   GPIO _PinOutClear (gpioPortB,0);
   USART_TxDouble (USART2,ReG_Word2);
   当(!(USART2->STATUS & USART_STATUSTXC));
   GPIO _PinOutSet (gpioPortB,0);

   while (GPIO_PinOutGet(gpioPortB,0)!=1);

//读出CFR寄存器
   GPIO _PinOutClear (gpioPortB,6),GPIO _PinOutClear (gpioPortB,0);

   USART_TxDouble (USART2,ADS833x_READ_COM);
   当(!(USART2->STATUS & USART_STATUSTXC));
   ADS833x_buf[0]=(uint16_t)USART2->RXDOUBLE;

   USART_TxDouble (USART2,ADS833x_READ_COM);
   当(!(USART2->STATUS & USART_STATUSTXC));
   ADS833x_buf[1]=(uint16_t)USART2->RXDOUBLE;

   GPIO_PinOutSet (gpioPortB,0),GPIO _PinOutSet (gpioPortB,6);


   ADS833x_buf[2]= ADS833x_buf[0]和0x0FFF;
   ADS833x_buf[3]= ADS833x_buf[1]和0x0FFF;


   如果((ADS833x_CFR_Reg1!= ADS833x_buf[2])||(ADS833x_CF_Reg2!= ADS833x_buf[3])){
      错误();
   }

}

目前,两个CFR寄存器的读数值都不符合 ADS833x_CFR_Reg1和ADS833x_CFR_Reg2,这就是我的程序在错误循环中结束的原因。 因此,我认为在CFR寄存器中的书写不成功。 我的问题是否有解决方案? 谢谢!!

此致,

Sebastian

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

    您好,Sebastian:

    -请提供几个示波器图,显示正在配置设备时CS#1,SCLK,SDI,SDO#1的菊花链帧定时。  将示波器探针放在靠近ADC I/O针脚的位置。  SDI是否在SCLK的ring边缘或Falling边缘进行更新?

    --请提供显示菊花链连接的示意图或图表。  MCU读数SDO是否在上升或下降SCLK边缘?

    谢谢,此致,

    路易斯

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

    您好,Luis,

    感谢您的快速回复。 关于您的笔记:

    附加的窗口显示逻辑分析器的结果:

    信道1:CS#2

    信道2:CONVST

    信道3:EC/INT

    信道4:SDI

    信道5:SDO

    信道6:SCLK

    信道7:CS#1

    参考电压:1.65V

    SDI正在SCLK的上升边缘进行更新

    一个周期:

    读取CFR:

    --菊花链连接的示意图:

    MCU正在读取上升SCLK边缘上的SDO。

    谢谢,此致,

    Sebastian

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

    哦,逻辑分析仪的输出图像未成功传输(有关通道描述,请参阅上面的注释)。

    CFR配置和CFR读取:

    仅读取CFR:

    此外,MCU上的SPI配置(USART2是相关的SPI连接):

    void spi_setup (uint8_t spiNumber,uint8_t位置,bool master)

       USART_typedef *SPI;

       /*确定USART */
       交换机(spiNumber)
       {
       案例0:
          SPI = USART0;
          中断;
       案例1:
          SPI = USART1;
          中断;
       案例2:
          SPI = USART2;
          中断;
       默认:
          返回;
       }



       /*设置波特率*/
       SPI->CLKDIV = 128 *(SPI_PERCLK_FREQUENCY / 1200万-2);   //SPI2_BAUDRATE - 2);

       /*配置SPI */
       /*使用同步(SPI)模式*/
       SPI->CTRL = USART_CTRL_SYNC | USART_CTRL_MSBF;
       /* SPI模式0*/
       SPI->CTRL |= USART_CTRL_CLKPOL_IDLELOW;
       SPI->CTRL |= USART_CTRL_CLKPHA_SAMPLEADING;
       /*清除旧的传输/接收并禁用中断*/
       SPI->CMD = USART_CMD_CLEARRX | USART_CMD_CLEARTX;
       SPI->IEN = 0;
       /*启用引脚和设置位置*/
       SPI->route = USART_ROUTE_TXPEN | USART_ROUTE_RXPEN | USART_ROUTE_CLKPEN |(位置<< 8);//已删除CLK,以便可以将延迟添加到TX功能



       /*将GPIO配置设置为从属*/
       GPIO_Mode_typedef gpioModeMosi = gpioModeInput;
       GPIO_Mode_typedef gpioModeMiso = gpioModePushPull;
       GPIO_Mode_typedef gpioModeCs  = gpioModeInput;
       GPIO_Mode_typedef gpioModeClk = gpioModeInput;
       GPIO _模式_类型f gpioModeCS1  = gpioModeInput;
       GPIO_Mode_typedef gpioModeCS2  = gpioModeInput;
       GPIO_Mode_typedef gpioModeConv  = gpioModeInput;
       GPIO _模式_类型f gpioModeEOC = gpioModePushPull;


       /*设置为MASTER和控制CS线*/
       IF (主)
       {
          /*启用主中继器,TX和RX */
          SPI->CMD  = USART_CMD_MASTEREN | USART_CMD_TXEN | USART_CMD_RXEN;
          //SPI->CTRL |= USART_CTRL_AUTOCS;

          /*将GPIO配置设置为master */
          gpioModeMosi = gpioModePushPull;
          gpioModeMiso = gpioModeInput;
          gpioModeClk = gpioModePushPull;
          gpioModeCS1  = gpioModePushPull;
          gpioModeCS2  = gpioModePushPull;
          gpioModeConv  = gpioModePushPull;
          gpioModeEOC = gpioModeInput;
       }
       否则
       {
          /*启用TX和RX */
          SPI->CMD = USART_CMD_TXEN | USART_CMD_RXEN;
       }

       /*清除以前的中断*/
       SPI->Ifc =_USART_Ifc掩码;

       /* IO配置*/
       交换机(spiNumber)
       {
       案例0:交换机(位置)
       {
       案例0:/* IO配置(USART 0,位置#0)*/
          GPIO_PinModeSet (gpioPortE,10,gpioModeMosi,0);/* MOSI */
          GPIO_PinModeSet (gpioPortE,11,gpioModeMiso,0);/* miso */
          GPIO_PinModeSet (gpioPortE,13,gpioModeCs,  0);/* CS */
          GPIO_PinModeSet (gpioPortE,12,gpioModeClk, 0);/*时钟*/
          中断;
       案例1:/* IO配置(USART 0,位置#1)*/
          GPIO_PinModeSet (gpioPortE,7,gpioModeMosi,0); /* MOSI */
          GPIO_PinModeSet (gpioPortE,6,gpioModeMiso,0); /* miso */
          GPIO_PinModeSet (gpioPortE,4,gpioModeCs,  0); /* CS */
          GPIO _PinModeSet (gpioPorte, 5, gpioModeClk, 0); /*时钟*/
          中断;
       案例2:/* IO配置(USART 0,位置#2)*/
          GPIO _PinModeSet (gpioPortC,11,gpioModeMosi,0);/* MOSI */
          GPIO_PinModeSet (gpioPortC,10,gpioModeMiso,0);/* miso */
          GPIO_PinModeSet (gpioPortC, 8,gpioModeCs,  0);/* CS */
          GPIO_PinModeSet (gpioPortC, 9,gpioModeClk, 0);/*时钟*/
          中断;
       默认值:中断;
       }
       中断;
       案例1:开关(位置)
       {
       案例0:/* IO配置(USART 1,位置#0)*/
          GPIO_PinModeSet (gpioPortC,0,gpioModeMosi,0); /* MOSI */
          GPIO_PinModeSet (gpioPortC,1,gpioModeMiso,0); /* miso */
          GPIO_PinModeSet (gpioPortB,8,gpioModeCs,  0); /* CS */
          GPIO_PinModeSet (gpioPortB,7,gpioModeClk, 0); /*时钟*/
          中断;
       案例1:/* IO配置(USART 1,位置1)*/
          GPIO_PinModeSet (gpioPortD,0,gpioModeMosi,0); /* MOSI */
          GPIO_PinModeSet (gpioPortD,1,gpioModeMiso,0); /* miso */
          GPIO_PinModeSet (gpioPortD,3,gpioModeCs,  0); /* CS */
          GPIO_PinModeSet (gpioPortD,2,gpioModeClk, 0); /*时钟*
          中断;
       默认值:中断;
       }
       中断;
       案例2:开关(位置)
       {
       案例0:/* IO配置(USART 2,位置#0)*/
          GPIO_PinModeSet (gpioPortC,2,gpioModeMosi,0); /* MOSI */
          GPIO_PinModeSet (gpioPortC,3,gpioModeMiso,0); /* miso */
          GPIO_PinModeSet (gpioPortC,5,gpioModeCs,  0); /* CS */
          GPIO_PinModeSet (gpioPortC,4,gpioModeClk, 0); /*时钟*/
          中断;
       案例1:/* IO配置(USART 2,位置#1)*/
          GPIO_PinModeSet (gpioPortB,3,gpioModeMosi,0); /* MOSI */
          GPIO_PinModeSet (gpioPortB,4,gpioModeMiso,0); /* miso */
          GPIO _PinModeSet (gpioPortB,6,gpioModeCs1,  0); /* CS1 */
          GPIO _PinModeSet (gpioPortB,0,gpioModeCs2,  0); /* CS2 */
          GPIO_PinModeSet (gpioPortB,5,gpioModeClk, 0); /*时钟*
          GPIO_PinModeSet (gpioPortB,1,gpioModeConv, 0); /* Conv */
          GPIO_PinModeSet (gpioPortB,2,gpioModeEOC, 0); /* EOC */

          GPIO _PinOutSet (gpioPortB, 6);
          GPIO _PinOutSet (gpioPortB, 0);
          GPIO _PinOutSet (gpioPortB,1);
          中断;
       默认值:中断;
       }
       中断;
       默认值:中断;
       }
    }

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

    您好,Sebastian:


    ADS8332能够支持SPI设置CPOL=1,CPHA=0;但是 ,需要注意的是MCU需要足够快的速度,以便在SCLK下降边缘的5ns内采样SDO。
    使用CPOL=1,CPHA=0时 ,主控制器捕获SCLK下降边缘上的Miso数据,MOSI数据输出在下降边缘上。

    请参见下面的计时图,其中TD1为最小5ns:


    它出现,查看提供 的代码和图解,表明您正在使用CPOL=0 CPHA=1。 是否可以尝试使用CPOL=1,CPHA=0?

    您使用的是哪种MCU?  您能否确认SCLK频率?

    请注意,某些MCU的速度不够快,无法在SCLK 下降边缘的5ns内读取SDO,可能需要更长的SDO延迟时间。

    谢谢,此致,

    路易斯

    路易斯

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

    您好,Luis,

    下面您可以看到我的MCU (EFM32WG380F256)的时序图:

    很遗憾,我可以使用CPOL=1,CPHA=0,直到星期二。 但是,"确认SCLK频率"是什么意思? SCLK频率对应于:

    /*设置波特率*/
       SPI->CLKDIV = 128 *(SPI_PERCLK_FREQUENCY / 1200万-2);    

    SPI_PERCLK_FREQUENCY = 4800万 Hz时。

    谢谢,致以诚挚的问候,

    Sebastian

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

    您好,Sebastian:

    感谢您提供MCU定时信息;它似乎应该能够满足ADS8332定时规范。

    请将设置更改为CPOL=1,CPHA=0并告知我们此操作是否解决了问题。 如果问题仍然存在,请在写入/读取CFR时提供新的示波器图以及SCLK,SDI,SDO,CS,CONVST的新设置。

    谢谢,此致,
    路易斯

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

    您好,Luis,

    您可以在下面看到将设置更改为CPOL=1,CPHA=0的计时图,这不能解决问题,尽管主控制器捕获SCLK下降边缘上的Miso和MOSI。 此外,我测试了所有可能的设置,但没有成功。 我非常感谢你们提供更多的意见和建议。  

    在配置我的CFR寄存器(并跳过错误)后,我想读取ADC#1和ADC#2的通道1 (在两个正弦信号上都连接以进行测试)。 下面提供了代码和时间图。 结果数据与窦性信号不一致。 如果您对此问题也有一些建议,我将不胜感激。  

    void startADC(Int16_t ADS833x_result[number_channels][size],int cycle){

       UINT16_t循环计数=0;   //通过空闲循环计数时间
       UINT16_t通道编号= 0;

       //uint16_t ADS833x_CFR_Reg1 = 0b1.1011万111101;11.1101万;
       //uint16_t ADS833x_CFR_Reg2 = 0b1.1011万011101;1.1101万;

       对于(LoopCount=0;LoopCount<=Channel_Number;LoopCount++)
       {
          
          UINT16_t临时缓冲器[2];
          用于(int i =0;I<2;I++){
             TempdBuffer[i]=0;
          }

          Timer_Enable (Timer1,FALSE);
          Timer_CounterSet (TIMER1,0);
          Timer_Enable (Timer1,TRUE);
          GPIO _PinOutClear (gpioPortB,1);
          //最小40 ns的计时
          while (Timer1->CNT<3){
             ;
          }
          Timer_Enable (Timer1,FALSE);
          GPIO _PinOutSet (gpioPortB,1);

          while (GPIO_PinOutGet(gpioPortB,1)!=1){
             ;
          }
          ADS833x_ReadRegister(&tempBuffer[0],0b1101<12);


          ADS833x_result[LoopCount][cycle]= tempBuffer[0];
          ADS833x_Result [LoopCount+8][cycle]= tempBuffer[1];
       }
       //ADS833x_INIT (ADS833x_CFR_Reg1,ADS833x_CFR_Reg2);

    }

    void ADS833x_ReadRegister (uint16_t dataBuffer[2],uint16_t命令)    //读取CFR寄存器



       GPIO _PinOutClear (gpioPortB,6),GPIO _PinOutClear (gpioPortB,0);

       USART_TxDouble (USART2,COMMAND);

       while (!(USART2->status & USART_STATUS_TXBL)){}
       USART_RxDouble (USART2);
       dataBuffer[0]=(uint16_t)USART2->RXDOUBLE;

       USART_TxDouble (USART2,COMMAND);

       while (!(USART2->status & USART_STATUS_TXBL)){}
       USART_RxDouble (USART2);
       dataBuffer[0]=(uint16_t)USART2->RXDOUBLE;

       GPIO _PinOutSet (gpioPortB,6),GPIO _PinOutSet (gpioPortB,0);
    }




    void ADS833x_Channel_Select(uint16_t Data, uint16_t cs)

       数据=数据<12;
       如果(cs){
          GPIO _PinOutClear (gpioPortB,0);
          USART_TxDouble (USART2,数据);
          GPIO _PinOutSet (gpioPortB,0);
       }
       否则{
          GPIO _PinOutClear (gpioPortB,6);
          USART_TxDouble (USART2,数据);
          GPIO _PinOutSet (gpioPortB,6);
       }
    }

    读取数据:

    谢谢,此致,

    Sebastian

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

    我已经切断了SDO (ADC#1)-> CDI (ADC#2)之间的线路,并检查了两侧的给定电压。 在CDI线路上,我测量了3.3V电压(参考电压)。 我假设CFR的配置不成功,这就是为什么CDI引脚似乎是输出而不是输入,并且始终处于高水平的原因。 此外,更改D7或任何其他位不会导致我的时间图中的更改,这也证实了这一点。 您可以在下面看到我的CFR SDI位:

    UINT16_t ADS833x_CFR_Reg1 = 0b1.1011万111101;11.1101万;
    UINT16_t ADS833x_CFR_Reg2 = 0b1.1011万011101;1.1101万;

    不过,我认为这是一个根本性的问题。 与菊花链式中与单个ADC (SPI引脚除外)的电气布线不同?

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

    您好,Sebastian:


    是的,正如您所提到的,我不相信CFR正在制定。  默认情况下,CDI引脚是一个输出,表示EOC, 在转换期间处于活动低电平状态,在设备未转换时为高电平状态。   使用CFR D5=0 (菊花链模式)配置ADC#2后,此引脚将变为输入。  

    我将在工作台上设置此配置,以菊花链模式连接设备。  我将提供具有寄存器设置的两个写入CFR事务编程ADC#1和ADC #2的放大示波器图;然后提供另一组事务以读取CFR设置。


    请留出几个工作日。


    谢谢,此致,

    路易斯

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

    您好,Luis,

    非常感谢您的支持。 我对您的结果感到兴奋。

    此致,

    Sebastian

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

    我已经解决了问题。 它达到了我通过SPI线路发送的位数(16位而不是8位(使用MSB和LSB))。 进一步转换输入位有点奇怪,但它起作用,我从CFR寄存器中得到了正确的值。

    void ADS833x_init(uint16_t ADS833x_CFR_Reg1, uint16_t ADS833x_CFR_Reg2) //初始化ADS833x

    UINT16_t注册_WORD1;
    UINT16_t注册_文字2;

    UINT16_t ADS833x_Write_COM = 0xE000;
    UINT16_t ADS833x_READ_COM = 0xC000;
    uINT16_t ADS833x_buf[BUF_SIZE];
    对于(int i =0;I<BUF_SIZE;I++){
    ADS833x_buf[i]=0;
    }

    REG_WORD1 = ADS833x_Write_COM + ADS833x_CFR_Reg1;
    REG_Word2 = ADS833x_Write_COM + ADS833x_CFR_Reg2;

    UINT16_t REG_Word1MSB = REG_WORD1 >> 8;
    UINT16_t ReG_Word1LSB = ReG_WORD1 & 0xFF;
    UINT16_t ReG_Word2MSB = ReG_Word2 >> 8;
    UINT16_t ReG_Word2LSB = ReG_Word2和0xFF;
    UINT16_t READ_MSB = ADS833x_READ_COM >> 8;
    UINT16_t READ_LSB = ADS833x_READ_COM & 0xFF;


    GPIO _PinOutClear (gpioPortB,6);
    USART_SpiTransfer (USART2,Reg_Word1MSB);
    USART_SpiTransfer (USART2,ReG_Word1LSB);
    GPIO _PinOutSet (gpioPortB,6);

    GPIO _PinOutClear (gpioPortB,0);
    USART_SpiTransfer (USART2,Reg_Word2MSB);
    USART_SpiTransfer (USART2,ReG_Word2LSB);
    GPIO _PinOutSet (gpioPortB,0);


    GPIO _PinOutClear (gpioPortB,6),GPIO _PinOutClear (gpioPortB,0);
    ADS833x_buf[2]= USART_SpiTransfer (USART2, READ_MSB);
    ADS833x_buf[3]= USART_SpiTransfer (USART2, READ_LSB);
    ADS833x_buf[0]= USART_SpiTransfer (USART2,0);
    ADS833x_buf[1]= USART_SpiTransfer (USART2,0);

    GPIO_PinOutSet (gpioPortB,6),GPIO _PinOutSet (gpioPortB,0);

    ADS833x_buf[4]=(ADS833x_buf[0]<7)|0x00FF)&(ADS833x_buf[1]>>1)|0xFF80);
    ADS833x_buf[5]=((ADS833x_buf[2]<7)|0x00FF)&(ADS833x_buf[3]>>>1)|0xFF80);
    ADS833x_buf[6]= ADS833x_buf[4]和0x0FFF;
    ADS833x_buf[7]= ADS833x_buf[5]和0x0FFF;

    如果((ADS833x_CFR_Reg1!= ADS833x_buf[6])||(ADS833x_CFR_Reg2!= ADS833x_buf[7))error();

    }

    谢谢,此致,

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

    您好,Sebastian:

    感谢您的更新,并让我们知道问题已解决。

    此致,

    路易斯