串口使用DMA接收不定长数据时,第一次接收的数据没有进入中断



  • 串口使用DMA接收不定长数据时,使用串口第一次发送数据后,若短时间内没收到回复数据,第一次的数据会跟着第二次的数据一起出来,通过日志打印,发现是第一次接收的数据未进入中断处理函数,以下是我的串口部分相关代码,麻烦帮忙看下是哪里的问题
    void Uart1Init(void)
    {
    __SYSTEM_UART1_CLK_ENABLE();

    GPIO_InitTypeDef 	GPIO_Handle = {0}; 
    /* init GPIO Alternate Function */
    GPIO_Handle.Pin       = GPIO_PIN_6|GPIO_PIN_7;
    GPIO_Handle.Mode      = GPIO_MODE_AF_PP;
    GPIO_Handle.Pull      = GPIO_PULLUP;
    GPIO_Handle.Alternate = GPIO_FUNCTION_5;
    gpio_init(GPIO_A, &GPIO_Handle);
    
    /* init uart1 */   
    Uart1_handle.UARTx = Uart1;
    Uart1_handle.Init.BaudRate   = 115200;
    Uart1_handle.Init.DataLength = UART_DATA_LENGTH_8BIT;
    Uart1_handle.Init.StopBits   = UART_STOPBITS_1;
    Uart1_handle.Init.Parity     = UART_PARITY_NONE;
    Uart1_handle.Init.FIFO_Mode  = UART_FIFO_ENABLE;
    uart_init_ex(&Uart1_handle);
    
    __UART_INT_RX_ENABLE(Uart1_handle.UARTx);
    NVIC_EnableIRQ(UART1_IRQn);
    
    /* init uart1 rx DMA */ 
    
    DMA_Chan2.Channel               = DMA_Channel2;
    DMA_Chan2.Init.Data_Flow        = DMA_P2M_DMAC;
    DMA_Chan2.Init.Request_ID       = 3;
    DMA_Chan2.Init.Source_Inc       = DMA_ADDR_INC_NO_CHANGE;
    DMA_Chan2.Init.Desination_Inc   = DMA_ADDR_INC_INC;
    DMA_Chan2.Init.Source_Width     = DMA_TRANSFER_WIDTH_8;
    DMA_Chan2.Init.Desination_Width = DMA_TRANSFER_WIDTH_8;
    dma_init(&DMA_Chan2);
    
    __SYSTEM_DMA_CLK_ENABLE();
    NVIC_EnableIRQ(DMA_IRQn);
    uart_receive_DMA(&Uart1_handle);
    __UART_RxFIFO_THRESHOLD((&Uart1_handle), 1);//Set RxFIFO 1/4 full  
    
    dma_start(&DMA_Chan2, (uint32_t)&Uart1_handle.UARTx->DATA_DLL.DATA,(uint32_t)Checkbuf, 200, DMA_BURST_LEN_4, DMA_BURST_LEN_1);
    

    }
    void DMA_disable(DMA_HandleTypeDef hdma)
    {
    /
    Disable the channel /
    DMA->Misc_Reg.ChEnReg = (DMA->Misc_Reg.ChEnReg&(~(1 << hdma->Channel))) | (1 << (hdma->Channel + 8));
    /
    Clear Transfer complete status /
    dma_clear_tfr_Status(hdma->Channel);
    /
    channel Transfer complete interrupt disable */
    dma_tfr_interrupt_disable(hdma->Channel);
    }
    attribute((section("ram_code"))) void uart1_isr(void)
    {
    uint32_t isr_id;

    volatile struct_UART_t * const uart_reg_ram = (volatile struct_UART_t *)UART1_BASE;
    
    isr_id = __UART_INT_GET_ID(Uart1_handle.UARTx);
    if((isr_id & 0x0f) == 0x0c)
    {
    	if(dma_recv_idx == 0)
    	{
    		dma_recv_idx = DMA->Channels[DMA_Chan2.Channel].CTL2.BLOCK_TS;
    		co_printf("dma_recv_idx:%d\r\n",dma_recv_idx);
    	}
    	while(uart_reg_ram->LSR.LSR_BIT.DR)
    	{
    		Checkbuf[dma_recv_idx++] = (uint8_t)uart_reg_ram->DATA_DLL.DATA;
    	}
    	recv_done= 1;
    }
    

    }
    主循环中
    while(1)
    {
    if(recv_done)
    {
    recv_done = 0;
    DMA_disable(&DMA_Chan2);
    dma_start(&DMA_Chan2, (uint32_t)&Uart1_handle.UARTx->DATA_DLL.DATA,(uint32_t)Checkbuf, 200, DMA_BURST_LEN_4, DMA_BURST_LEN_1);
    co_printf("recv done:%d\r\n",dma_recv_idx);
    show_reg(Checkbuf,dma_recv_idx,1);
    dma_recv_idx = 0;
    }
    }


  • Global Moderator

    @dsg
    【有道云笔记】800x串口DMA接收不定长度数据
    https://share.note.youdao.com/s/P3cOOAnQ
    参考下这个文件



  • 你好,就是参考这个文档来配置的,发现还有一个问题,将fifo设置为1/4触发时,串口接收到的数据长度是4的倍数时,就无法触发超时中断,这个该怎么解决。