串口使用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;
}
}
-
@dsg
【有道云笔记】800x串口DMA接收不定长度数据
https://share.note.youdao.com/s/P3cOOAnQ
参考下这个文件
-
你好,就是参考这个文档来配置的,发现还有一个问题,将fifo设置为1/4触发时,串口接收到的数据长度是4的倍数时,就无法触发超时中断,这个该怎么解决。