主题中讨论的其他器件: SysConfig、 C2000WARE
您好!
我来找你是因为我有一段时间的问题,我似乎不能解决。
我有两个微控制器通过 SPI 彼此通信。 我的 SPI 以全双工模式工作、我的从器件正确地从主器件接收信息并同时发送回数据。 示波器上的信号很干净。
我的问题与在将 TMS320F28388D 配置为主器件并具有 SPI + DMA 的 TMS320F28388D 上的接收有关。
当我启动一个传输/接收时、我接收到的帧的开始从我的接收缓冲区的第4个字节开始。
这里我的 DMA 设置 :
/*********************************/
/* DMA Channel 1, SPI-A transmit */
/*********************************/
GV_sDmaRegs.CH1.MODE.bit.CHINTE = 0; /* 0: Interrupt disabled */
GV_sDmaRegs.CH1.MODE.bit.DATASIZE = 0; /* 0: 16-bit data transfer size */
GV_sDmaRegs.CH1.MODE.bit.ONESHOT = 0;
GV_sDmaRegs.CH1.BURST_SIZE.all = 0; /* 1 word/burst */
GV_sDmaRegs.CH1.SRC_BURST_STEP = 1; /* Move to next word in buffer */
GV_sDmaRegs.CH1.DST_BURST_STEP = 0; /* Don't move destination address */
GV_sDmaRegs.CH1.TRANSFER_SIZE = C_DRVDMA_SIZE - 1U; /* C_DRVDMA_SIZE transfer size in bursts */
GV_sDmaRegs.CH1.SRC_TRANSFER_STEP = 1; /* Move to next word in buffer after each word in a burst */
GV_sDmaRegs.CH1.DST_TRANSFER_STEP = 0; /* Don't move destination address */
GV_sDmaRegs.CH1.SRC_WRAP_SIZE = 0xFFFE; /* Put to maximum - don't want source wrap. */
GV_sDmaRegs.CH1.DST_WRAP_SIZE = 0xFFFE; /* Put to maximum - don't want destination wrap. */
GV_sDmaRegs.CH1.SRC_BEG_ADDR_SHADOW = (Uint32) GV_DRVDMA_transferTxDataCh1; /* Start address = DMA buffer */
GV_sDmaRegs.CH1.SRC_ADDR_SHADOW = (Uint32) GV_DRVDMA_transferTxDataCh1; /* Start address = DMA buffer */
GV_sDmaRegs.CH1.DST_BEG_ADDR_SHADOW = C_DRVSPI_SPIA_ADDR + C_DRVSPI_SPITXBUF_OFFSET; /* Start address */
GV_sDmaRegs.CH1.DST_ADDR_SHADOW = C_DRVSPI_SPIA_ADDR + C_DRVSPI_SPITXBUF_OFFSET; /* Start address */
GV_sDmaClaSrcSelRegs.DMACHSRCSEL1.bit.CH1 = 109; /* 109: SPIA_TXDMA as DMA channel 1 Trigger source */
GV_sDmaRegs.CH1.MODE.bit.PERINTSEL = 1; /* Peripheral interrupt select */
GV_sDmaRegs.CH1.MODE.bit.PERINTE = 1; /* Enable peripheral interrupt event */
GV_sDmaRegs.CH1.CONTROL.bit.PERINTCLR = 1; /* Clear peripheral interrupt event flag. */
/********************************/
/* DMA Channel 2, SPI-A receive */
/********************************/
GV_sDmaRegs.CH2.MODE.bit.CHINTE = 0; /* 0: Interrupt disabled */
GV_sDmaRegs.CH2.MODE.bit.DATASIZE = 0; /* 0: 16-bit data transfer size */
GV_sDmaRegs.CH2.MODE.bit.ONESHOT = 0;
GV_sDmaRegs.CH2.MODE.bit.CONTINUOUS = 0;
GV_sDmaRegs.CH2.BURST_SIZE.all = 0; /* 1 word/burst */
GV_sDmaRegs.CH2.SRC_BURST_STEP = 0; /* Don't move in FIFO */
GV_sDmaRegs.CH2.DST_BURST_STEP = 1; /* Move to next word in destination address */
GV_sDmaRegs.CH2.TRANSFER_SIZE = C_DRVDMA_SIZE - 1U; /* C_DRVDMA_SIZE transfer size in bursts */
GV_sDmaRegs.CH2.SRC_TRANSFER_STEP = 0; /* Don't move source address */
GV_sDmaRegs.CH2.DST_TRANSFER_STEP = 1; /* Move to next word in buffer after each word in a burst */
GV_sDmaRegs.CH2.SRC_WRAP_SIZE = 0xFFFE; /* Put to maximum - don't want source wrap. */
GV_sDmaRegs.CH2.DST_WRAP_SIZE = 0xFFFE; /* Put to maximum - don't want destination wrap. */
GV_sDmaRegs.CH2.SRC_BEG_ADDR_SHADOW = C_DRVSPI_SPIA_ADDR + C_DRVSPI_SPIRXBUF_OFFSET; /* Start address */
GV_sDmaRegs.CH2.SRC_ADDR_SHADOW = C_DRVSPI_SPIA_ADDR + C_DRVSPI_SPIRXBUF_OFFSET; /* Start address */
GV_sDmaRegs.CH2.DST_BEG_ADDR_SHADOW = (Uint32) GV_DRVDMA_transferRxDataCh2; /* Start address = DMA buffer */
GV_sDmaRegs.CH2.DST_ADDR_SHADOW = (Uint32) GV_DRVDMA_transferRxDataCh2; /* Start address = DMA buffer */
GV_sDmaClaSrcSelRegs.DMACHSRCSEL1.bit.CH2 = 110; /* 109: SPIA_RXDMA as DMA channel 1 Trigger source */
GV_sDmaRegs.CH2.MODE.bit.PERINTSEL = 1; /* Peripheral interrupt select */
GV_sDmaRegs.CH2.MODE.bit.PERINTE = 1; /* Enable peripheral interrupt event */
GV_sDmaRegs.CH2.CONTROL.bit.PERINTCLR = 1; /* Clear peripheral interrupt event flag. */
带有:
C_DRVSPI_SPI_ADDR = 0x006100U
C_DRVSPI_SPIRXBUF_OFFSET = 0x07U
c_DRVDMA_size = 40u
这里是我的 SPI 设置、
/* SPI-A Clear SPI Software Reset bit (SPISWRESET= to 0 to force the SPI to the reset state */
/* SPI-A Relinquish SPI from Reset, Reset on, rising edge in input, 8-bit char bits */
GV_sSpiARegs.SPICCR.all = 0x0007U;
/* SPI-A Master mode, normal SPI clocking scheme, enable talk and disable SPI interrupt (flag) */
GV_sSpiARegs.SPICTL.all = 0x0006U;
/* SPI-A Baud Rate is set */
GV_sSpiARegs.SPIBRR.all = 19U;
/* SPI-A FREE bit */
/* Halting on a breakpoint will not halt the SPI */
GV_sSpiARegs.SPIPRI.bit.FREE = 1;
/* SPI-A RX FIFO, RXFIFORESET: Reset the FIFO pointer to zero, and hold in reset. */
GV_sSpiARegs.SPIFFRX.all = 0U;
/* SPI-A TX FIFO, SPIRST: Reset the SPI transmit and receive channels. */
/* The SPI FIFO register configuration bits will be left as is. */
/* TXFIFO: Reset the FIFO pointer to zero, and hold in reset */
GV_sSpiARegs.SPIFFTX.all = 0U;
/* SPI-A RX FIFO interrupt is disabled, FIFO interrupt level bits to default value */
/* SPI-A is ready to receive (RX FIFO) */
GV_sSpiARegs.SPIFFRX.all = 0xE041U;
/* SPI-A Enable TX and RX FIFO and is ready to transmit (TX FIFO) */
GV_sSpiARegs.SPIFFTX.all = 0xE041U;
GV_sSpiARegs.SPIFFCT.all = 1;
/* SPI-A is ready to transmit and receive the next character, set this bit before resuming operation */
GV_sSpiARegs.SPICCR.bit.SPISWRESET = 1;
当我启动传输/接收时:
- 首先启动 RX DMA:
GV_sDmaRegs.CH2.CONTROL.bit.PERINTCLR = 1; GV_sDmaRegs.CH2.CONTROL.bit.RUN = 1;
- 然后选择 TX DMA:
GV_sDmaRegs.CH1.CONTROL.bit.RUN = 1;
系统地、在启动时、DMA 缓冲区的前3个字节是 SPIRXBUF 的当前状态重复3次、然后是从我的帧中丢失的4个字节(= 0)、然后是我的预期帧的一部分。
示例:

预期值:
- [0]--> 0x5A
- [1]--> 0 (计数器)
- [2]--> 2
- [3]--> 3
- [4]--> 4
- [5]--> 5
- [6]--> 6
- [7]--> 7
- ...
- [37]--> 37
- [38]--> 0 (相同计数器)
- [39]--> 0xA5
所有下一个传输/接收,我有:

我在[4]的计数器与在[1]的计数器相同,因此我解释说我已经接收了整个帧,但我的 DMA 已经开始在第4个字节写入并循环(即使我没有设置换行)。
在调试中、激活 DMA RX 之后和 DMA TX 之前的断点显示无 DMA RX 触发、仅当我激活 TX 时。
如果你有任何线索,我无法理解这个问题。 谢谢!








