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.

串口dma接收



您好:

        请问为什么我在使用串口dma接收数据的过程中,定义了4K的一个缓冲区,分为a和b两个区域作为ping-pong区,但是每次都发现dma从a+1024和b+1024的地址开始存数据,而且每1024个字节就进一次中断。谢谢。程序代码如下:

static void usart1_rx_dma_cfg(uint8_t *ping, uint8_t *pong, uint32_t size)

{


ROM_UARTFIFOLevelSet(UART1_BASE, UART_FIFO_TX4_8, UART_FIFO_RX4_8);

//enable the uDMA interface for RX channels.
ROM_UARTDMAEnable(UART1_BASE, UART_DMA_RX);

// Put the attributes in a known state for the uDMA UART1RX channel. These
// should already be disabled by default.
ROM_uDMAChannelAttributeDisable(UDMA_CHANNEL_UART1RX,
       UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
       UDMA_ATTR_HIGH_PRIORITY |
       UDMA_ATTR_REQMASK);

ROM_uDMAChannelControlSet(UDMA_CHANNEL_UART1RX | UDMA_PRI_SELECT,
     UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 |
     UDMA_ARB_4);

ROM_uDMAChannelControlSet(UDMA_CHANNEL_UART1RX | UDMA_ALT_SELECT,
      UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 |
      UDMA_ARB_4);


ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART1RX | UDMA_PRI_SELECT,
         UDMA_MODE_PINGPONG,
         (void *)(UART1_BASE + UART_O_DR),
          ping, size);

// Set up the transfer parameters for the UART RX alternate control
// structure. The mode is set to ping-pong, the transfer source is the
// UART data register, and the destination is the receive "B" buffer. The
// transfer size is set to match the size of the buffer.
ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART1RX | UDMA_ALT_SELECT,
      UDMA_MODE_PINGPONG,
      (void *)(UART1_BASE + UART_O_DR),
      pong, size);

// Now the uDMA UART RX channels are primed to start a
// transfer. As soon as the channels are enabled, the peripheral will
// issue a transfer request and the data transfers will begin.
ROM_uDMAChannelEnable(UDMA_CHANNEL_UART1RX);

// Enable the UART DMA RX interrupts.
 ROM_UARTIntEnable(UART1_BASE, UART_INT_DMARX);

}

中断函数如下:

uDMAmode = ROM_uDMAChannelModeGet(UDMA_CHANNEL_UART1RX | UDMA_PRI_SELECT);


if(uDMAmode == UDMA_MODE_STOP)
{
   g_app.dma.buffHalf = 1;
   recv_app_code_time_clear();
   g_recvState = RECV_CODE;


   ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART1RX | UDMA_PRI_SELECT,
                UDMA_MODE_PINGPONG,
                (void *)(UART1_BASE + UART_O_DR),
                g_app.dma.buff, APP_MDA_BUF_HALF_SIZE);
}


uDMAmode = ROM_uDMAChannelModeGet(UDMA_CHANNEL_UART1RX | UDMA_ALT_SELECT);


if(uDMAmode == UDMA_MODE_STOP)
{
   g_app.dma.buffFull = 1;
   recv_app_code_time_clear();
   g_recvState = RECV_CODE;


   ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART1RX | UDMA_ALT_SELECT,
   UDMA_MODE_PINGPONG,
   (void *)(UART1_BASE + UART_O_DR),
   &g_app.dma.buff[APP_MDA_BUF_HALF_SIZE], APP_MDA_BUF_HALF_SIZE);
}
以上程序定义的这个g_app.dma.buff[APP_MDA_BUF_SIZE]是4k的一个缓冲区,
程序里面APP_MDA_BUF_HALF_SIZE = APP_MDA_BUF_SIZE/2即将一个连续的4K缓冲区分为两个2k做ping-pong区。
现出现以下问题:
每次接收数据DMA往缓冲区里面存都是从g_app.dma.buff+1024的地址处和g_app.dma.buff[APP_MDA_BUF_HALF_SIZE+1024]地址处开存1K;
MDA只在以上描述的这两个地址处开始版数据,即MDA每次都是从ping区首地址+1024的内存处开始放数据。pong区也是从首地址+1024的地址开始放数据。且没有数据丢失。
请问这是什么原因造成的。为什么MDA把两个缓冲区的前面1k内存不用。

  • 以上程序定义的这个g_app.dma.buff[APP_MDA_BUF_SIZE]是4k的一个缓冲区,
    程序里面APP_MDA_BUF_HALF_SIZE = APP_MDA_BUF_SIZE/2即将一个连续的4K缓冲区分为两个2k做ping-pong区。
    现出现以下问题:
    每次接收数据DMA往缓冲区里面存都是从g_app.dma.buff+1024的地址处和g_app.dma.buff[APP_MDA_BUF_HALF_SIZE+1024]地址处开存1K;
    MDA只在以上描述的这两个地址处开始版数据,即MDA每次都是从ping区首地址+1024的内存处开始放数据。pong区也是从首地址+1024的地址开始放数据。且没有数据丢失。
    请问这是什么原因造成的。为什么MDA把两个缓冲区的前面1k内存不用。