-基于STM32F407Hal库的DMA乒乓缓存机制)
一、概述DMA 乒乓缓存机制主要思路是利用串口的接收空闲中断搭配DMA接收的半传输中断和全传输中断实现。全满中断和半满中断都很好理解就是串口 DMA 的缓冲区填充了一半和填满时产生的中断。而空闲中断是串口在上一帧数据接收完成之后在一个字节的时间内没有接收到数据时产生的中断即总线进入了空闲状态。这对于接收大量数据或不定长数据十分方便。二、应用如下图所示向这个缓冲区大小为 20 的程序传送一个大小为 25 的 数据包它会产生三次中断大体分为三个状态进入半满中断处理缓存区的前半段数据进入传输完成中断处理后半段数据接收停止处理空闲中断数据。这种方式可以实现大量数据的短时间处理也不会丢包/* Rx DMA配置 */ __HAL_RCC_DMA1_CLK_ENABLE();// 低优先级 // __HAL_LINKDMA( g_rs458_handler, hdmarx, g_dma_usart2_rx_handle); /* 将DMA与USART1联系起来(发送DMA) */ g_dma_usart2_rx_handle.Instance DMA1_Stream5; /* 数据流选择 */ g_dma_usart2_rx_handle.Init.Channel DMA_CHANNEL_4; /* DMA通道选择 */ g_dma_usart2_rx_handle.Init.Direction DMA_PERIPH_TO_MEMORY; /* 外设到存储器 */ g_dma_usart2_rx_handle.Init.PeriphInc DMA_PINC_DISABLE; /* 外设非增量模式 */ g_dma_usart2_rx_handle.Init.MemInc DMA_MINC_ENABLE; /* 存储器增量模式 */ g_dma_usart2_rx_handle.Init.PeriphDataAlignment DMA_PDATAALIGN_BYTE; /* 外设数据长度:8位 */ g_dma_usart2_rx_handle.Init.MemDataAlignment DMA_MDATAALIGN_BYTE; /* 存储器数据长度:8位 */ g_dma_usart2_rx_handle.Init.Mode DMA_CIRCULAR; /* 外设流控模式 */ g_dma_usart2_rx_handle.Init.Priority DMA_PRIORITY_MEDIUM; /* 中等优先级 */ g_dma_usart2_rx_handle.Init.FIFOMode DMA_FIFOMODE_DISABLE; /* 关闭FIFO模式 */ g_dma_usart2_rx_handle.Init.FIFOThreshold DMA_FIFO_THRESHOLD_FULL; /* FIFO阈值配置 */ g_dma_usart2_rx_handle.Init.MemBurst DMA_MBURST_SINGLE; /* 存储器突发单次传输 */ g_dma_usart2_rx_handle.Init.PeriphBurst DMA_PBURST_SINGLE; /* 外设突发单次传输 */ // __HAL_LINKDMA( g_rs458_handler, hdmarx, g_dma_usart2_rx_handle); /* 将DMA与USART1联系起来(发送DMA) */ HAL_DMA_Init( g_dma_usart2_rx_handle); // 将DMA与USART1联系起来(接收DMA) HAL_UART_Receive_DMA( g_rs458_handler, g_rcvDataBuf2, MAX_BUF_SIZE); // 开启DMA接收 HAL_DMA_Start( g_dma_usart2_rx_handle, (uint32_t) USART2-DR, (uint32_t) g_rcvDataBuf2, MAX_BUF_SIZE); HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 3, 0); HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn); __HAL_DMA_ENABLE_IT( g_dma_usart2_rx_handle, DMA_IT_TC); __HAL_DMA_ENABLE_IT( g_dma_usart2_rx_handle, DMA_IT_HT);中断处理:printf(DMA1_Stream5中断:%d\r\n,DMA_Cnt); if (__HAL_DMA_GET_FLAG( g_dma_usart2_rx_handle, DMA_FLAG_HTIF1_5)) { __HAL_DMA_CLEAR_FLAG( g_dma_usart2_rx_handle, DMA_FLAG_HTIF1_5); HAL_UART_Transmit_DMA( Usart6_HMI_handler, g_txDataBuf2, MAX_BUF_SIZE/2); printf(清除DMA_FLAG_HTIF1_5\r\n); } if (__HAL_DMA_GET_FLAG( g_dma_usart2_rx_handle, DMA_FLAG_TCIF1_5)) { __HAL_DMA_CLEAR_FLAG( g_dma_usart2_rx_handle, DMA_FLAG_TCIF1_5); // HAL_UART_Transmit_DMA(USART6_handler, g_rcvDataBuf6, PACKET_DATA_LEN); // __HAL_DMA_CLEAR_FLAG( g_dma_usart6_tx_handle, DMA_FLAG_TCIF3_7); HAL_UART_Transmit_DMA( Usart6_HMI_handler, g_txDataBuf2[MAX_BUF_SIZE/2], MAX_BUF_SIZE/2); printf(清除DMA_FLAG_TCIF1_5\r\n); }三测试数据测试数据是间隔1ms发送2000个数据,设置的缓存大小是2000;测试发送个数据无丢包,且主程序.四\程序链接STM32F407基于Hal库的DMA乒乓缓存机制资源-CSDN下载