STM32F205的串口DMA接收缓冲区里没有数据

2019-07-14 14:20发布

几乎是按照官方例子配出来的程序.  我是想设置4个字节到缓冲区后产生接收传输完成中断. 然后一次处理4个字节,但是PC只要向STM32发送1个字节,DMA_FLAG_TCIF1马上就置位了, 缓冲区里面也没有数据,但是看USART-DR里是收到那个字符的.

下面是初始化代码,为了简化我没有中断,配置好串口后一直查询 DMA_FLAG_TCIF1 标志位.

// 初始化函数,外面会传一个BUF首地址和长度进来作为DMA接收缓冲区
void HAL_UARTDevInit (const UINT8 *p_rec_buf, UINT32 num)
{
    UINT8 err;

    DMA_InitTypeDef dma_init_structure;
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
   
    /* Connect PXx to USARTx_Tx*/
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_USART3);

    /* Connect PXx to USARTx_Rx*/
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_USART3);

    /* Configure USART Tx as alternate function  */
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    /* Configure USART Rx as alternate function  */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    /* USART configuration */
    USART_InitStructure.USART_BaudRate = 115200;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_Init(USART3, &USART_InitStructure);
   
   // USART_ClearFlag(USART3, USART_FLAG_TC | USART_FLAG_RXNE);                   /* 清除已有的标志位, 防止使能后直接进入该中断 */
    USART_Cmd(USART3, ENABLE);
   
    /* 当配置DMA时初始化DMA接收通道 */
    DMA_DeInit(DMA1_Stream1);
   
    dma_init_structure.DMA_Channel            = DMA_Channel_4;
    dma_init_structure.DMA_PeripheralBaseAddr = (uint32_t)(USART3 + 0x04);
    dma_init_structure.DMA_Memory0BaseAddr    = (uint32_t)p_rec_buf;
    dma_init_structure.DMA_DIR                = DMA_DIR_PeripheralToMemory;
    dma_init_structure.DMA_BufferSize         = num;
    dma_init_structure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;
    dma_init_structure.DMA_MemoryInc          = DMA_MemoryInc_Enable;
    dma_init_structure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    dma_init_structure.DMA_MemoryDataSize     = DMA_MemoryDataSize_Byte;
    dma_init_structure.DMA_Mode               = DMA_Mode_Normal;
    dma_init_structure.DMA_Priority           = DMA_Priority_VeryHigh;
    dma_init_structure.DMA_FIFOMode           = DMA_FIFOMode_Disable;
    dma_init_structure.DMA_FIFOThreshold      = DMA_FIFOThreshold_Full;
    dma_init_structure.DMA_MemoryBurst        = DMA_MemoryBurst_Single;
    dma_init_structure.DMA_PeripheralBurst    = DMA_PeripheralBurst_Single;
    DMA_Init(DMA1_Stream1, &dma_init_structure);
   
    USART_DMACmd(USART3, USART_DMAReq_Rx, ENABLE);
    DMA_Cmd(DMA1_Stream1, ENABLE);
}

//测试代码
unsigned char buffer[4];

HAL_UARTDevInit(buffer, 4);
while (DMA_GetFlagStatus(DMA1_Stream1, DMA_FLAG_TCIF1) == RESET)
{
    ;
}   
while(1); // 设个断点程序达到此处后停下来观察内存. 只要串口接受到1个字节就会到这里, buffer里全是0, 而USART3->DR里有我发过来的数据.   详细对比了几遍和例程 USART_TwoBoardsDataExchangeDMA.  几乎没有不同. 我禁止掉了FIFO模式, 如果启用FIFO也是一样

请高人帮忙!
   
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
4条回答
a15055113163
1楼-- · 2019-07-15 01:01
 精彩回答 2  元偷偷看……
东少2016
2楼-- · 2019-07-15 01:29
研究下寄存器的具体意义吧,不要只看官方历程,结合datasheet看嗲吗还是有必要的。
官方的库/例程可以参考,但是不要完全不思考,个人建议
viczeng
3楼-- · 2019-07-15 07:11
遇到同样问题,设置接收buf128个字节
那接收到128个字节才会认为是接收完成啊
怎么第一个字节就进入接收完成中断了,楼主解决没?
2016李勇
4楼-- · 2019-07-15 08:21
将USART_Cmd(USART3, ENABLE);放在DMA_Cmd(DMA1_Stream1, ENABLE);后面试试

一周热门 更多>