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 配合使用、只有几个问题阻碍了我继续使用此微控制器进行测试。 我使用 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/41410eecMISO 引脚上是否有电容器? 此外、您的 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 时变为高电平。
是的、我指的是您圈出的快照。 基于此快照、看起来 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、因为这样可以解决问题。