Skip to content

USART+DMA+ringbuffer使用手册,高速数据串口解析,不让你的串口再繁忙占用mcu

Notifications You must be signed in to change notification settings

611code/Usart_ringbuffer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

USART+DMA+ringbuffer接收解析数据,配置及使用详解

1.CUBEMX 配置USART1配置:

image-20250729001907377

2.串口DMA配置 image-20250729002038789

3.在st生成的usart.c中,进行重定向(重要!)

/* USER CODE BEGIN 0 */
typedef struct __FILE FILE;

uint8_t uart_rx_buffer[128] = {0};
uint8_t uart_rx_dma_buffer[128] = {0};
/* USER CODE END 0 */

int fputc(int ch, FILE * str)
{
    HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 10);
    return ch;
}

4.在usart.c中(cubemx生成的),usart的初始化api函数,在初始化完成的最后,进行dma的初始化和使能(重要!)

  /* USER CODE BEGIN USART1_Init 2 */
  HAL_UARTEx_ReceiveToIdle_DMA(&huart1, uart_rx_dma_buffer, sizeof(uart_rx_dma_buffer));
  __HAL_DMA_DISABLE_IT(&hdma_usart1_rx ,DMA_IT_HT);
  /* USER CODE END USART1_Init 2 */

5.在usart_user.c中进行定义环形缓冲区,后需要在main.c中进行环形缓冲区初始化,此步之前记得要把文件中的ringbuffer.c和ringbuffer.h放到自己的库文件中

// 定义环形缓冲区和接收缓冲区
ringbuffer_t usart_rb;
uint8_t usart_read_buffer[BUUFER_SIZE];

//在main.c中,初始化调用
ringbuffer_init(&usart_rb);

6.在usart_user.c中,进行dma回调函数构写*(重要!)*,如下:

/**
*@brief UART DMA接收完成回调函数
*将接收到的数据写入环形缓冲区,并清空DMA缓冲区
*@param huart 句柄
*@param	size 接收的数据大小
*@retval None
**/
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
//    printf("dma data:%s\r\n", uart_rx_dma_buffer);
    // 如果环形缓冲区未满
	if(!ringbuffer_is_full(&usart_rb))
    {
    // 将DMA缓冲区中的数据写入环形缓冲区
        ringbuffer_write(&usart_rb, uart_rx_dma_buffer , Size);
    }
    // 清空DMA缓冲区
    	memset(uart_rx_dma_buffer, 0, sizeof(uart_rx_dma_buffer));
		HAL_UARTEx_ReceiveToIdle_DMA(&huart1, uart_rx_dma_buffer, BUUFER_SIZE);
}

7.uart任务函数构写,在此处进行构写解析数据

/**
 * @brief 处理UART接收缓存区中的数据。
 *        本函数在每隔100ms时接收新的数据,将空缓冲区清理。
 * @param  None
 * @retval None
 */
void uart_proc(void)
{
    
    // 如果环形缓冲区为空,直接返回
    if (ringbuffer_is_empty(&uart_rb)) return;
    
    // 从环形缓冲区取出数据并解析(需要自己构写)
    ringbuffer_read(&uart_rb, uart_read_buffer, uart_rb.itemCount);

    //此处已经将环形缓冲区的数据取出到uart_read_buffer;
    printf('ringbuffer data: %s', uart_read_buffer);
    
    // 清空读取缓冲区
    memset(uart_read_buffer, 0, sizeof(uart_read_buffer));
}

About

USART+DMA+ringbuffer使用手册,高速数据串口解析,不让你的串口再繁忙占用mcu

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages