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.

[参考译文] TMS320F280039C:错误的 SPI 数据

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1163699/tms320f280039c-bad-spi-data

器件型号:TMS320F280039C
主题中讨论的其他器件: PGA411-Q1

您好!  

我的项目主要与 TMS320F280039C 配合使用、只有几个问题阻碍了我继续使用此微控制器进行测试。 我使用 MCU 来控制交流电机并让电机旋转。 项目的结构方式是、我有一个250us ADC 中断、用于触发和执行电机控制。 然后、此中断触发运行100us 的用户中断(请注意、添加的100us 必须小于250us 的总数)。 在250us 中断期间、我使用 SPI FIFO 中断读取旋转变压器两次。 这运行良好、但我似乎得到了一些不良数据、导致速度反馈中产生噪声、有时电机中会产生可闻噪声、因为我在错误的点点火电流。  

下面的 Conv1Debug3显示了 SPI 链路上不良数据的计数-如在1.5秒内所示、我错过了来自旋转变压器的14次传输、您还可以注意到随附的速度毛刺脉冲:  

我想知道这是否是嵌套中断问题?  

我将启动类似这样的 SPI 传输-请注意、我必须添加 EINT、以便在 ADC ISR 期间允许2个 SPI 中断。

// Start sequence of SPI Master read/write register operations to Resolver chip - Blocking
void SpiMaster_StartTransfer(GE_Primary_Container_t *pContainer, uint32_t command)
{
    pContainer->mpSpiMaster->mDataRecv = 0;

    // Reset Rx and Tx Buffers
    SPIMaster_ResetBuffers(pContainer);

    // Set TxData buffer
    pContainer->mpSpiMaster->mTxData[0] = (command >> 24) & 0xFFU;
    pContainer->mpSpiMaster->mTxData[1] = (command >> 16) & 0xFFU;
    pContainer->mpSpiMaster->mTxData[2] = (command >> 8) & 0xFFU;
    pContainer->mpSpiMaster->mTxData[3] = (command & 0xFFU);

    pContainer->mpSpiMaster->mIsTransferCompleted = false;

    // Reset / Setup SPI
    SPIMaster_SetupResetSPI(pContainer);

    // Reset / Setup FIFO
    SPI_disableFIFO(REPC_RES_DSPI_MASTER_BASEADDR);
    SPI_clearInterruptStatus(REPC_RES_DSPI_MASTER_BASEADDR, SPI_INT_TXFF);
    SPI_clearInterruptStatus(REPC_RES_DSPI_MASTER_BASEADDR, SPI_INT_RXFF);
    SPI_enableFIFO(REPC_RES_DSPI_MASTER_BASEADDR);
    SPI_setFIFOInterruptLevel(REPC_RES_DSPI_MASTER_BASEADDR, SPI_FIFO_TXEMPTY, SPI_FIFO_RX4);

    // Enable RxFIFO Interrupt
    SPI_enableInterrupt(REPC_RES_DSPI_MASTER_BASEADDR, SPI_INT_RXFF);

    // Enable SPI
    SPI_enableModule(REPC_RES_DSPI_MASTER_BASEADDR);

    // Clear INTM so that we can trigger another interrupt inside of fast thread
    EINT;

    // Enable interrupts
    Interrupt_enable(INT_SPIB_TX);
    Interrupt_enable(INT_SPIB_RX);

    // Fill FIFO and send data - no interrupt required here
    int i = 0;
    for (i = 0; i < REPC_RES_MASTER_TRANSFER_SIZE; i++)
    {
        SPI_writeDataNonBlocking(REPC_RES_DSPI_MASTER_BASEADDR, ((pContainer->mpSpiMaster->mTxData[i] & 0x00FF) << 8));
    }
}

下面是我初始化 SPI 的方法:  

// Setup / Reset SPI
void SPIMaster_SetupResetSPI(GE_Primary_Container_t *pContainer)
{
    // Must put SPI into reset before configuring it
    SPI_disableModule(REPC_RES_DSPI_MASTER_BASEADDR);

    // SPI configuration. Use a 12.5MHz SPICLK and 32-bit word size, 25MHz LSPCLK
    // Rising edge SPI
    SPI_setConfig(REPC_RES_DSPI_MASTER_BASEADDR, REPC_RES_DSPI_MASTER_CLK_SRC, SPI_PROT_POL0PHA0,
                  SPI_MODE_MASTER, REPC_RES_TRANSFER_BAUDRATE, 8U);
    SPI_disableLoopback(REPC_RES_DSPI_MASTER_BASEADDR);
    SPI_setEmulationMode(REPC_RES_DSPI_MASTER_BASEADDR, SPI_EMULATION_FREE_RUN);
}

// Init SPI1 Interface to resolver
void SPIMaster_Init(GE_Primary_Container_t *pContainer)
{
    // Register interrupt ISRs
    Interrupt_register(INT_SPIB_TX, &spiBTxFIFOISR);
    Interrupt_register(INT_SPIB_RX, &spiBRxFIFOISR);

    // Setup / Reset SPI
    SPIMaster_SetupResetSPI(pContainer);

    // Configuration complete. Enable the module.
    SPI_enableModule(REPC_RES_DSPI_MASTER_BASEADDR);

	// Init Master Buffers to 0
	SPIMaster_ResetBuffers(pContainer);

	// Init Control Variables
	pContainer->mpSpiMaster->mIsTransferCompleted = false;
}

感谢您的帮助!

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

    当卡只是放在我的办公桌上而不是系统中时、也会发生这种情况。  

    这是良好的数据:  

    这是错误数据:  

    在错误数据中、唯一的错误似乎是放错位置/额外1  

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

    我简要介绍了您的 SPI 配置代码、看起来不错。 您是否在示波器上监控 SPI 总线、以查看是否有任何噪声影响 SPI 事务? 错误位是否总是发生在位6上、还是随机发生。

    此致、

    曼诺伊

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

    嗨、Manoj、  

    我的旋转变压器上的角度发生了变化(在 TI 的 PGA411-Q1上读取)。 现在正是这样才能获得良好的数据:  

    我捕获了50个不良数据点:  

    这里似乎有多种错误数据配置。

    1)位6是随机的- 410eec63

    2) 2)重复标头0x41 - 410e410e/41410eec  

    3)最后一个字节丢失、我们得到下一个传输的第一个字节- 410eec41

    当我最初让 PGA411-Q1与该 MCU 一起工作(我让它与另一家 MCU 供应商合作)时、我认为 MISO 线路在传输之间不会变为低电平是很奇怪的-请参阅示波器上的以下通道3:  

    很难判断哪些数据包损坏。 当我认为有错误数据时、我将驱动 GPIO、以查看数据包是否有任何看起来奇怪的东西。  

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

    是否确保根据 SPI RX 中断读取 SPIRX 数据? 根据第2个故障特征、我觉得您在 SPI 事务的中间读取 SPIRXBUF。

    [引用 userid="365463" URL"~/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1163699/tms320f280039c-bad-spi-data/4376914 #4376914"]2)重复使用标头0x41 - 410e410e/41410eec  

    MISO 引脚上是否有电容器? 此外、您的 SPI 总线为什么看起来是正弦波?

    [引用 userid="365463" URL"~/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1163699/tms320f280039c-bad-spi-data/4376914 #4376914"]很难判断哪些数据包损坏。 当我认为有错误数据时、我将驱动 GPIO、以查看数据包是否有任何看起来奇怪的东西。  [/报价]

    是的、这是确定问题的关键实验。 你有什么

    此致、

    曼诺伊

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

    嗨、Manoj、

    我在接收4个字节后触发中断:  

        SPI_enableFIFO(REPC_RES_DSPI_MASTER_BASEADDR);
        SPI_setFIFOInterruptLevel(REPC_RES_DSPI_MASTER_BASEADDR, SPI_FIFO_TXEMPTY, SPI_FIFO_RX4);

    然后、在中断中、我只复制接收到的数据:  

    void spiRxFIFOISRRoutine(GE_Primary_Container_t *pContainer)
    {
        // Read 32 bit response from PGA411-Q1
        int i = 0;
        for (i = 0; i < REPC_RES_MASTER_TRANSFER_SIZE; i++)
        {
            pContainer->mpSpiMaster->mRxData[i] = (SPI_readDataNonBlocking(REPC_RES_DSPI_MASTER_BASEADDR) & 0x00FF);
        }
    
        pContainer->mpSpiMaster->mIsTransferCompleted = true;
    
        // Ack interrupt
        SPI_clearInterruptStatus(REPC_RES_DSPI_MASTER_BASEADDR, SPI_INT_RXFF);
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP6);
    }
    

    SPI 总线不是正弦波-这是因为我的示波器探针目前未接地。 只需忽略正弦波形。 它不是正弦波。 此外、MISO 引脚上没有电容器。  

    我将使用示波器/GPIO 来尝试在示波器上标记什么是错误数据、以查看它是否实际损坏。  

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

    嗨、Manoj、  

    我捕获了错误数据-在传输过程中、CS 似乎会在1us 内保持高电平。 这是什么原因?  

    以下是良好数据的样子(大部分传输):  

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

    我将仔细查看快照并回复

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

    您好、Manoj、  

    是否知道 CS 为何会在传输过程中变为高电平?  

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

    我猜 SPISTE 引脚被控制为 SPI 引脚。 对吧?

    如果 SPISTE 引脚配置为 SPI 引脚、则 SPISTE 引脚将在 SPI 事务完成后变为高电平(无论发送/接收)

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

    是的、没错。 但您是否未看到示波器跟踪? 它在32位传输的中间变为高电平:  

    圈出的区域在做什么? 为什么会发生这种情况? 这是一个32位传输、CS、MISO、MOSI、CLK 都在中间产生毛刺脉冲。  

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

    当我开始传输时、我将 CS 更改为 GPIO I Pull LOW、然后在中断中设置回1、并且不再发生不良数据干扰  

    不过、我想知道驱动器 CS 在传输过程中出现高干扰的原因。  

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

    您在此处显示的快照看起来不像干扰。 它是正确的信号。 您可能需要检查代码以了解问题的根源。

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

    哪个快照? 我圈出的那个 CS 变为高电平? 我的代码如何驱动芯片选择高电平? 这看起来不像正常的传输。 我刚刚传输了32位、CS 在传输的中间拉高。 在这种情况下、我不控制 CS。  

    我将 CS 切换为 GPIO、这样可以解决我的问题。 我可以处理此问题、但我想了解为什么 CS 在设置为 STE 时变为高电平。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="365463" URL"~/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1163699/tms320f280039c-bad-spi-data/4381585 #4381585">哪个快照? 我圈出的那个 CS 变为高电平? 我的代码如何驱动芯片选择高电平? 这看起来不像正常的传输。 我刚刚传输了32位、CS 在传输的中间拉高。 在这种情况下、我不控制 CS。  [/报价]

    是的、我指的是您圈出的快照。 基于此快照、看起来 SPI 事务已完成。 对于32位传输、我相信您正在进行两个16位传输。 对吧? 您是否正在使用 FIFO?

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

    您好、Manoj、  

    以下是我的初始化代码:  

    // Setup / Reset SPI
    void SPIMaster_SetupResetSPI(GE_Secondary_Container_t *pContainer)
    {
        // Must put SPI into reset before configuring it
        SPI_disableModule(REPC_RES_DSPI_MASTER_BASEADDR);
    
        // SPI configuration. Use a 12.5MHz SPICLK and 32-bit word size, 25MHz LSPCLK
        // Rising edge SPI
        SPI_setConfig(REPC_RES_DSPI_MASTER_BASEADDR, REPC_RES_DSPI_MASTER_CLK_SRC, SPI_PROT_POL0PHA0,
                      SPI_MODE_MASTER, REPC_RES_TRANSFER_BAUDRATE, 8U);
        SPI_disableLoopback(REPC_RES_DSPI_MASTER_BASEADDR);
        SPI_setEmulationMode(REPC_RES_DSPI_MASTER_BASEADDR, SPI_EMULATION_FREE_RUN);
    
        // Reset / Setup FIFO
        SPI_disableFIFO(REPC_RES_DSPI_MASTER_BASEADDR);
        SPI_clearInterruptStatus(REPC_RES_DSPI_MASTER_BASEADDR, SPI_INT_TXFF);
        SPI_clearInterruptStatus(REPC_RES_DSPI_MASTER_BASEADDR, SPI_INT_RXFF);
        SPI_enableFIFO(REPC_RES_DSPI_MASTER_BASEADDR);
        SPI_setFIFOInterruptLevel(REPC_RES_DSPI_MASTER_BASEADDR, SPI_FIFO_TXEMPTY, SPI_FIFO_RX4);
    
        // Enable RxFIFO Interrupt
        SPI_enableInterrupt(REPC_RES_DSPI_MASTER_BASEADDR, SPI_INT_RXFF);
    
        // Enable interrupts
        Interrupt_enable(INT_SPIB_TX);
        Interrupt_enable(INT_SPIB_RX);
    }
    
    // Init SPI1 Interface to resolver
    void SPIMaster_Init(GE_Secondary_Container_t *pContainer)
    {
        // Register interrupt ISRs
        Interrupt_register(INT_SPIB_TX, &spiBTxFIFOISR);
        Interrupt_register(INT_SPIB_RX, &spiBRxFIFOISR);
    
        // Setup / Reset SPI
        SPIMaster_SetupResetSPI(pContainer);
    
        // Configuration complete. Enable the module.
        SPI_enableModule(REPC_RES_DSPI_MASTER_BASEADDR);
    
        // Init Master Buffers to 0
        SPIMaster_ResetBuffers(pContainer);
    
        // Init Control Variables
        pContainer->mpSpiMaster->mIsTransferCompleted = false;
    }

    下面是我启动传输的方式:  

    // Start sequence of SPI Master read/write register operations to Resolver chip - Blocking
    void SpiMaster_StartTransfer(GE_Secondary_Container_t *pContainer, uint32_t command)
    {
        pContainer->mpSpiMaster->mDataRecv = 0;
    
        // Reset Rx and Tx Buffers
        SPIMaster_ResetBuffers(pContainer);
    
        // Set TxData buffer
        pContainer->mpSpiMaster->mTxData[0] = (command >> 24) & 0xFFU;
        pContainer->mpSpiMaster->mTxData[1] = (command >> 16) & 0xFFU;
        pContainer->mpSpiMaster->mTxData[2] = (command >> 8) & 0xFFU;
        pContainer->mpSpiMaster->mTxData[3] = (command & 0xFFU);
    
        pContainer->mpSpiMaster->mIsTransferCompleted = false;
    
        // Clear INTM so that we can trigger another interrupt inside of fast thread
        EINT;
    
        GPIO_writePin(GPIO27_SPIBCS, 0);
    
        // Fill FIFO and send data - no interrupt required here
        int i = 0;
        for (i = 0; i < REPC_RES_MASTER_TRANSFER_SIZE; i++)
        {
            SPI_writeDataNonBlocking(REPC_RES_DSPI_MASTER_BASEADDR, ((pContainer->mpSpiMaster->mTxData[i] & 0x00FF) << 8));
        }
    }

    接收到4个字节后、RX FIFO 中断发生:

    void spiRxFIFOISRRoutine(GE_Secondary_Container_t *pContainer)
    {
        // Read 32 bit response from PGA411-Q1
        int i = 0;
        for (i = 0; i < REPC_RES_MASTER_TRANSFER_SIZE; i++)
        {
            pContainer->mpSpiMaster->mRxData[i] = (SPI_readDataNonBlocking(REPC_RES_DSPI_MASTER_BASEADDR) & 0x00FF);
        }
    
        pContainer->mpSpiMaster->mIsTransferCompleted = true;
        GPIO_writePin(GPIO27_SPIBCS, 1);
    
        // Ack interrupt
        SPI_clearInterruptStatus(REPC_RES_DSPI_MASTER_BASEADDR, SPI_INT_RXFF);
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP6);
    }

    请注意、我现在手动控制 CS。 这可以解决我的错误数据问题。 当我使用 CS 作为 SPIB_STE 并让驱动程序控制它时、即发生"干扰"时。  

        // GPIO27 -> SPIB CS (PGA411 SPI)
        //GPIO_setPinConfig(GPIO_27_SPIB_STE);
        GPIO_setPinConfig(GPIO_27_GPIO27);
        GPIO_setDirectionMode(GPIO27_SPIBCS, GPIO_DIR_MODE_OUT);
        GPIO_setPadConfig(GPIO27_SPIBCS, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(GPIO27_SPIBCS, GPIO_QUAL_ASYNC);
        GPIO_writePin(GPIO27_SPIBCS, 1);

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

    pContainer->mpSpiMaster->mTxData 中只存储了1个字节。 因此、您需要使用以下命令。 对吧?

    SPI_writeDataNonBlocking (REPC_RES_DSPI_MASTER_BASEADDR,(pContainer->mpSpiMaster->mTxData[i]));

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

    我发送了具有以下代码的4个字节:

     

    // Start sequence of SPI Master read/write register operations to Resolver chip - Blocking
    void SpiMaster_StartTransfer(GE_Secondary_Container_t *pContainer, uint32_t command)
    {
        pContainer->mpSpiMaster->mDataRecv = 0;
    
        // Reset Rx and Tx Buffers
        SPIMaster_ResetBuffers(pContainer);
    
        // Set TxData buffer
        pContainer->mpSpiMaster->mTxData[0] = (command >> 24) & 0xFFU;
        pContainer->mpSpiMaster->mTxData[1] = (command >> 16) & 0xFFU;
        pContainer->mpSpiMaster->mTxData[2] = (command >> 8) & 0xFFU;
        pContainer->mpSpiMaster->mTxData[3] = (command & 0xFFU);
    
        pContainer->mpSpiMaster->mIsTransferCompleted = false;
    
        // Clear INTM so that we can trigger another interrupt inside of fast thread
        EINT;
    
        GPIO_writePin(GPIO27_SPIBCS, 0);
    
        // Fill FIFO and send data - no interrupt required here
        int i = 0;
        for (i = 0; i < REPC_RES_MASTER_TRANSFER_SIZE; i++)
        {
            SPI_writeDataNonBlocking(REPC_RES_DSPI_MASTER_BASEADDR, ((pContainer->mpSpiMaster->mTxData[i] & 0x00FF) << 8));
        }
    }

    REPC_RES_MASTER_TRANSFER_SIZE = 4。

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

    您可以尝试用红色代码替换代码并用蓝色代码吗?

     //填充 FIFO 并发送数据-这里不需要中断
       int i = 0;
       对于(I = 0;I < REPC_RES_MASTER_TRANSFER_SIZE;I++)
       {
           SPI_writeDataNonBlocking (REPC_RES_DSPI_MASTER_BASEADDR、((pContainer->mpSpiMaster->mTxData[i]& 0x00FF)<< 8));

           SPI_writeDataNonBlocking (REPC_RES_DSPI_MASTER_BASEADDR,(pContainer->mpSpiMaster->mTxData[i]));
       }

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

    您好、Manoj、  

    我这么做了、但它发送了错误的数据。 我想发送4 8位数据包、并设置 SPI 以执行以下操作:  

        SPI_setConfig(REPC_RES_DSPI_MASTER_BASEADDR, REPC_RES_DSPI_MASTER_CLK_SRC, SPI_PROT_POL0PHA0,
                      SPI_MODE_MASTER, REPC_RES_TRANSFER_BAUDRATE, 8U);
    

    如果我想发送8位、我必须将数据放在16位寄存器的高字节中、如下所示:  

    SPI_writeDataNonBlocking(REPC_RES_DSPI_MASTER_BASEADDR, ((pContainer->mpSpiMaster->mTxData[i] & 0x00FF) << 8));

    如果我这么做、我发送全0

    SPI_writeDataNonBlocking(REPC_RES_DSPI_MASTER_BASEADDR, txPacket[i]);

    最后、我可以将 CS 用作 GPIO、因为这样可以解决问题。