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.

[参考译文] 在 MSP432P401R 的 SPI 通信中接收数据时出现问题

Guru**** 2560080 points
Other Parts Discussed in Thread: ADS1292R, ADS1292, ADS1292RECG-FE

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1041966/problem-receiving-data-in-spi-comunication-on-the-msp432p401r

主题中讨论的其他器件:ADS1292RADS1292ADS1292RECG-FE

 大家好、

我尝试将数字模拟前端(ADS1292R)与 MSP432P401开发板集成、但接收数据时遇到一些问题、因为通过中断、我检查从板发送的内容。 在分析数据时、我验证它是否响应用于标识读取寄存器的命令。 但是、我立即发送一条命令来执行从器件芯片识别、它只给我0。 我怀疑我的 SPI 通信集成不良。 由于这是一个原型、我需要对这个问题进行快速分析、所以我使用 driverlib 进行开发、这不是我的重点。 然后、我需要一个知识更丰富的人来为我提供一些关于可能出现的问题的提示。 我发送生成的代码

.e2e.ti.com/.../adsInterface.zip

提前感谢

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

    您好、Armando、

    有相当多的代码可供浏览以了解所有正在发生的情况。  我只会看到执行 SPI 操作的函数调用后出现几个10uec 延迟。  禁用 ADS1292芯片选择时、该延迟是否过短且 SPI 未完成数据传输?

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

    尊敬的 Dennis:  

    感谢您的回答。  我已经更改了延迟值、但没有得到任何更改。 我查看了硼和 Launch Pad 之间的所有连接、并且所有连接都正确。

    在分步调试模式下、我检查了变量以及发送到从器件的命令、但我没有通过 SPI 获得响应。 在变量 RX_DATA 中断后传输信息时、应该接收到一个十六进制值0x73、这将是确认芯片 ID 的值、但我只接收0。

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

    您好、Armando、

    您能否在示波器或逻辑探头上捕获一个正常工作的 SPI 事务、以及一个不起作用的 SPI 事务?

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

    SPI_RW ()依赖 EUSCI_SPI_Transmit_interrupt (TXIFG)来决定字节是否已发送、但 EUSCI 的双缓冲意味着该字节仅在此时开始。 如果 BRW=12、则对于另一个8*12=96个 CPU 时钟、它不完整、因此您将过早获取 RX_DATA。  

    尝试用 以下内容替换第二个 SPI_getInterruptStatus()检查:

    > while (SPI_isBusy (EUSCI_B0_BASE))/* empty*/;  //等待缓冲字节完成

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

    您好 Dennis,  

    这是我使用逻辑分析仪获得的信号

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

    在第一条迹线中、使能(我假设这是/CS)未被置为有效。

    第二个布线仅显示前两个字节(看起来正确)、但不显示第三个字节、其中包含 RREG 响应。 您能再"挤压"一下迹线吗?

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

    Bruce、您好!  

    这是具有前三个字节的整个跟踪、但只有前两个字节具有值...

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

    因为您从未实际读取数据。

    uint8_t SPI_RW(uint8_t TXData){
          while (!(SPI_getInterruptStatus(EUSCI_B0_BASE,EUSCI_SPI_TRANSMIT_INTERRUPT)));
    
          SPI_transmitData(EUSCI_B0_BASE, TXData);
    
          while (!(SPI_getInterruptStatus(EUSCI_B0_BASE,EUSCI_SPI_TRANSMIT_INTERRUPT)));
    
          return Rx_data;
    }
    

    RX_DATA 是一个全局变量、你永远不会将来自 RXBUF 的数据放入其中。 发送数据后、您应该在 RXIFG 上等待。 另请注意,如果只使用 SPI_RW(),则 TXIFG 的初始检查将始终为真,无需执行。 类似这样的东西。 (请注意、我不使用驱动程序库、因此我的器件上的详细信息是猜测的。)

    uint8_t SPI_RW(uint8_t TXData){
              SPI_transmitData(EUSCI_B0_BASE, TXData);
    
          while (!(SPI_getInterruptStatus(EUSCI_B0_BASE,EUSCI_SPI_RECEIVE_INTERRUPT)));
    
          return SPI_receviceData(EUSCI_B0_BASE);
    }
    

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

    David Schultz

    感谢您参加本次讨论。  我用您建议的代码段替换了我的代码段、但代码锁定在:

    while (!(SPI_getInterruptStatus (EUSCI_B0_BASE、EUSCI_SPI_receive_interrupt)));

    这样、程序就不会从那里通过

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

    我犹豫不同意 David 的说法、但在本例中、RXIFG 被 ISR 吸收(也捕获 RX_DATA)、即使它被捕获、也会是错误的 RXIFG。 I (仍然)建议等待 SPI 进入空闲状态(请参阅上文)。 [我实际上建议您不要使用中断、但这会是一个更大的变化。]

    更重要的是,/CS 过早取消置位(意味着过早读取 RX_Data),没有 RREG 响应的证据--至少0x8C 位应该为0。 [参考数据表(SBAS502B)第39页]。 您是否相当确定加电/复位序列?

    [编辑:基于此跟踪、您应该读取0xFF、但您报告您正在读取0x00。 也许检查您的接线?]

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

    Bruce  我保留了建议的代码片段、获得了如下代码:

    uint8_t SPI_RW(uint8_t TXData){
          while (!(SPI_getInterruptStatus(EUSCI_B0_BASE,EUSCI_SPI_TRANSMIT_INTERRUPT)));
          SPI_transmitData(EUSCI_B0_BASE, TXData);
          while (SPI_isBusy(EUSCI_B0_BASE));
          return Rx_data;
    }

    我不想使用中断、但不幸的是、我不知道如何执行这样的过程、所以我选择了中断。 另一方面、CS 器件我认为可以在数据传输之前保持低电平来控制、根据图、数据序列如下。 我认为我已成功执行该序列

    抱歉,我忘记更新您的"Rx_DATA"状态,现在返回值为255,按我的计数,它应该是115。
    提前感谢
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我在代码中没有足够远的时间来查看 ISR。 假设传输是轮询、那么接收也是如此、我很傻。

    应删除 ISR、因为它是一个异常。 最糟糕的情况是从 ISR 内发送串行数据(长时间操作)。

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

    这很奇怪。 通常、人们会说中断太复杂而无法使用。

    SPI_RW()的轮询版本要容易得多,您知道返回的数据是发送该特定字节时收到的数据。

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

    如何设置 CLKSEL 引脚? 我看不到任何生成(外部)时钟的代码、因此我想它= 1?

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

    Bruce McKenney47378、  

    在 ADS1292R 原型板上, 在 CLK 上,我添加了一个连接到3.3V 的10KOhm 电阻器,这将激活板上的内部振荡器,使其在512Khz 时振荡,这是= 1

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

    流程图表明、一旦时钟开始、DRDY 应在512/256=2kHz 时振荡。 您是否能够观察到这一点? 该器件似乎没有提供大量 反馈、因此您应该查找任何生命体征。

    ----------

    正如 David 所说的、在快速 SPI 上使用旋转环路而不是中断来处理短事务实际上更简单、更快、更可靠。 我会不时在论坛上提供:

    uint8_t spix(uint8_t c)
    {
      while (!(UCB0IFG & UCTXIFG)) /*EMPTY*/;
      UCB0TXBUF = c;
      while (!(UCB0IFG & UCRXIFG)) /*EMPTY*/;
      c = UCB0RXBUF;
      return(c);
    }

    每个 Tx 字节都会返回一个相应的 Rx 字节;如果该 Rx 字节不有趣、您可以将其丢弃。 它(有意)避免填充 Tx 流水线、因此可避免 Rx 溢出。 当它返回时、SPI 处于空闲状态、因此(如果适用)您可以取消使/CS 无效。 正如 David 指出的、第一行是可选的(如果您承诺仅使用此函数来驱动 SPI)。

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

    Bruce 感谢您的回答、

    我已经更改了函数 SPI_RW(), 在最后一个程序停止时, 我等待。

    接收来自 RX 的响应、但不返回。 此外、添加了一根导线来检查 DRDY 的状态、我 看不到任何变化

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

    您删除了此行吗?

    > SPI_enableInterrupt (EUSCI_B0_BASE、EUSCI_SPI_Receive_interrupt);

    如前所述、如果启用了 ISR、ISR 将"吸收" Rx 中断、但自旋环路形式会使 ISR 变得不必要。

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

    Bruce、您好!  

    我看到了一些进展、回答了您的问题、是的、在谷歌上读了一段关于轮询的内容、之后我做了一些更改、以实现代码的新生命。 在 SPI 实现(SPI_init())上,我删除了一些代码行,例如:

     >SPI_enableInterrupt (EUSCI_B0_BASE、EUSCI_SPI_Receive_interrupt);

     >Interrupt_enableInterrupt (INT_EUSCIB0);

     >MAP_Interrupt_enableMaster()

    之后、我运行代码和数字分析器并观察符号、 我已修复发送的第一个字节为0x11、在新代码更改之前、我从未看到此字节。

    在 MSO 线上、我没有收到合格的 dado、我开始怀疑这个原型电路板是否损坏

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

    在发送最后一个字节之前、它(仍然)看起来使能被取消置位。 您能否显示 SPI_RW 和 ADS1292R_REG 现在的样子? 您是否仅使用 SPI_RW 驱动 SPI? (我在那里看到了一些其他功能。)

    我仍然不知道 DRDY 是否出现波动、至少直到您发送 SDATAC 时。  

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

    SPI_RW()如下所示:

    uint8_t SPI_RW(uint8_t TXData){
        
           while(!(EUSCI_B0->IFG & EUSCI_B_IFG_TXIFG));
            EUSCI_B0->TXBUF = TXData;
            while(!(EUSCI_B0->IFG & EUSCI_B_IFG_RXIFG));
            return (TXData);
    }

    是的、现在我已经将中断置于一边、我使用 SPI_SW 来驱动所有 SPI 性能。  

    ADS1292R_REG 的发送方式与我发送给您的方式相同。

    uint8_t ADS1292R_REG(uint8_t cmd, uint8_t data){
        GPIO_setOutputLowOnPin(ADS1292R_CS_PORT,ADS1292R_CS_PIN);
        delay_us(10);
        ADS1292R_SPI_RW(cmd);
        ADS1292R_SPI_RW(0x00);
        if((cmd & 0x20)==0x20){
            ADS1292R_SPI_RW(0x00);
        }else{
            ADS1292R_SPI_RW(data);
        }
        delay_us(10);
        GPIO_setOutputHighOnPin(ADS1292R_CS_PORT,ADS1292R_CS_PIN);
        return Rx_data;
    }
    

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

    >返回(TXData);

    这应该更像:

    > RX_DATA = EUSCI_B0->RXBUF; //捕获数据并清除 RXIFG
    >返回(rx_data);

    RX_DATA 实际上并不需要是全局变量、而是用于调用方的逻辑。

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

    Bruce、您好!

    更多新闻,我一直在逐步处理代码和调试,我已经进行了一些升级,如监控 START 和 DRDY 引脚。

    因此、当启动程序时、START 引脚变为高电平、但 DRDY 和 MISO 没有变化。 DRDY 正常、因为只有在芯片 ID 读取且数据等于0x73后、代码才会执行、之后 DRDY 应根据每次转换更改信号。 问题似乎已逐步解决、但 MISO 引脚仍无响应、这是新的传输...

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

    好的、SPI 看起来正常、剩下的是 ADS1292似乎没有启动。

    根据流程图[数据表(SBAS502B)图63 (您在上面粘贴)、DRDY 切换应在(内部)时钟启动后立即启动、设置 start=1后大约8ms (在 ADS1292R_Init 中、在您读取 ID 之前很久)。 这似乎与 RDATAC 行为相符。 然后应设置 PWDN=1 (在 ADS1292R_PowerOnInit()早期)。

    但是、这似乎与图62相冲突、图62建议在上电时立即发生 PWDN=1。 这实际上看起来是合理的、因为 PWDN=0会将器件保持在复位状态、这将防止器件切换 DRDY。 尝试将 ADS1292R_Init 的最后一行更改为:

    >   GPIO_setOutputHighOnPin (ADS1292R_PWDN_PORT、ADS1292R_PWDN_PIN);//超出复位范围(根据 DS 图62)(不同意图63]

    >   DELAY_ms (8+200);  //距 DS 表17 8ms 加上大量的 slop

    [编辑:此外、您使用的是什么板? 它是 ADS1292RECG-FE 吗? 我认为原理图可能有用。]

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

    是的、通过图看来、SPI 正常。 你的建议是正确的、我会做一些更改。

    我一直在寻找您所讲数字的参考资料、我得出结论、您正在使用的书目已经过时、因为已经有新版本(SBAS502C–2011年12月–2020年4月修订) .No、my friend I not using the ADS1292RECG-FE。 它是一个中央电路板 ADS1292R、在"连接"中、我添加了原理图...

    e2e.ti.com/.../7750.pc_5F00_ads1292r_5F00_brk_5F00_v3.pdf

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

    这就是我添加文档版本号的原因。 修订版 C 中的相关引用似乎是图44和72以及表29。

    您是否尝试过我的建议?

    数据转换器论坛有一个常见问题解答、其中指出:

    https://e2e.ti.com/support/data-converters-group/data-converters/f/data-converters-forum/775288/faq-ads129x-how-do-i-verify-that-my-ads129x-device-is-still-functional/2868597#2868597

    它提到提高启动水平、但未(明确)提及 PWDN。 他们可能会在那里得到上拉电阻器?

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

    是的、 我已经尝试过您建议的操作、但不会为我们已升级的先前代码带来任何新功能。 我在 ADS1292R_PowerOnInit()上集成了在"断电高电平"之后和"启动引脚低电平"之前的 ADS1292R_work ()函数...

    void ADS1292R_Work(void){
        MAP_GPIO_setAsInputPin(ADS1292R_ADC_RDY_PORT, ADS1292R_ADC_RDY_PIN);
        MAP_GPIO_setAsInputPinWithPullUpResistor(ADS1292R_ADC_RDY_PORT, ADS1292R_ADC_RDY_PIN);
        MAP_GPIO_interruptEdgeSelect(ADS1292R_ADC_RDY_PORT,ADS1292R_ADC_RDY_PIN, GPIO_HIGH_TO_LOW_TRANSITION);
        MAP_GPIO_clearInterruptFlag(ADS1292R_ADC_RDY_PORT, ADS1292R_ADC_RDY_PIN);
        MAP_GPIO_enableInterrupt(ADS1292R_ADC_RDY_PORT, ADS1292R_ADC_RDY_PIN);
        MAP_Interrupt_enableInterrupt(INT_PORT4);
    }

    您是否建议在"开始"引脚中使用上拉电阻器? 10公里?

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

    尝试将 ADS1292R_Init 的最后一行更改为:

    >   GPIO_setOutputHighOnPin (ADS1292R_PWDN_PORT、ADS1292R_PWDN_PIN);//根据 DS 图72取消复位(不同意图44]

    >   DELAY_ms (8+200);  //距 DS 表29 8ms 加上大量的 slop

    在 PWDN 上放置一个上拉电阻器可能不会对您有所帮助、因为您将其驱动为输出(低电平)。  

    我在链接的检查清单中注意到的一点是、数据转换器人员也认为看到 DRDY 切换非常重要(步骤5)。

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

    我终于 查看了数据转换器论坛中发布的常见问题解答以及 ADS1292R 的常见问题解答:

    Vcap1 = AVSS + 1.2V=> Vcap1 = 0 + 1.2 = 1.2V

    Vcap2 = AVDD +1.9V=> Vcap2 = 3.32 + 1.9 = 5.22V  

    但在电路板中验证 Vcap1= 1.09V 和 Vcap2= 2.54V 的值。 第3步 显示"根据数据表规格启用内部主时钟或提供外部主时钟"。 如果代码未通过需要芯片 ID 的部件、如何启用内部时钟。  可能是某些连接出现故障、只有 CLK 和 GPIO 引脚 未连接、这是对内部振荡器未运行的独特解释。  我们已经查看了所有内容、最后不尝试的是 CLK 和 GPIO 引脚、问题是如何激活内部振荡器、而不运行代码、因为如果您未正确配置代码、振荡器将永远无法工作!

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

    根据启动流程图[DS Fig44、上面发布]中的步骤3、您可以通过设置 CLKSEL=1来启动内部时钟。 CLKSEL=1吗?

    这在您读取 ID 寄存器之前很长时间发生。  

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

    您好、Armando、

    几天以来,我们都没有听到您的声音,因此我假设您能够解决您的问题。
    我要将此帖子的状态更改为“已解决”,但如果不是这种情况,请单击“这不能解决我的问题”按钮,并使用更多信息回复此主题。
    如果此主题锁定、请单击"提出相关问题"按钮、然后在新主题中描述您的问题的当前状态以及您可能需要帮助我们帮助解决您的问题的任何其他详细信息。