串口环形缓冲区DMA收发

发布时间:2024年01月24日

概要

使用环形缓冲区可以解决HAL库接受中断的数据接受不完整问题,由于中断的速度不够快,会导致接受的数据被快速覆盖。

STM32CubeMX设置

在这里插入图片描述在这里插入图片描述在这里插入图片描述

代码解析

环形缓冲区代码

详见下面链接

https://blog.csdn.net/m0_72065741/article/details/135630825?spm=1001.2014.3001.5501

usart部分代码

 static circle_buffer Rxbuffer;//定义环形缓冲区结构体变量
 static uint8_t Getbuffer[100];//定义环形缓冲区
 static uint8_t g_recvchar;//定义存储接收数据的字节变量
 static volatile uint32_t g_Tx_sign = 0;//定义发送完成标志位,必须定义volatile类型,否则改变量会被编译器优化
 static volatile uint32_t g_Rx_sign = 0;//定义接收完成标志位,必须定义volatile类型,否则改变量会被编译器优化


void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)//发送完成回调函数
{
	g_Tx_sign = 1;//标志位置1表示发送完成
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)//接收完成回调函数
{
	g_Rx_sign = 1;//标志位置1表示接收完成
	Circle_Write(&Rxbuffer,g_recvchar);//将接收到的数据逐字节写入环形缓冲区
	HAL_UART_Receive_DMA(&huart1,&g_recvchar,1);//使能串口DMA中断

}
void Wait_Tx_Complete(void)//等待发送完成函数
{
	while(g_Tx_sign == 0);
	g_Tx_sign = 0;
}
void Wait_Rx_Complete(void)//等待接收完成函数
{
	while(g_Rx_sign == 0);
	g_Rx_sign = 0;
}

void Get_Buffer_Init(void)//初始化
{
	Circle_Buffer_Init(&Rxbuffer,100,Getbuffer);//环形缓冲区初始化
	HAL_UART_Receive_DMA(&huart1,&g_recvchar,1);//使能串口DMA中断
}

int UART_GetChar(uint8_t *pVal)//得到一个字节
{
	return Circle_Read(&Rxbuffer,pVal);//读取字节并返回值
}


main.c代码

int main(void)
{
  /* USER CODE BEGIN 1 */
	char data1[] = "hello world\r\n";
	char data2[] = "Input:";
	uint8_t c = 0;
	uint8_t getdata;
	uint8_t getbuffer[10];//定义一个缓冲区用于保存数据,可用此来控制外设
  int i = 0;
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
	Get_Buffer_Init();

	HAL_UART_Transmit(&huart1,(uint8_t *)data1,strlen(data1),1000);
	HAL_UART_Transmit_DMA(&huart1,(uint8_t *)data2,strlen(data2));
	Wait_Tx_Complete();
  while (1)
  {

		while (0 != UART_GetChar(&getdata));//如果读函数能够读取数据则返回0
		getbuffer[i] = getdata;//将字节存入缓冲区
		i++;
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		if(i == 10)//如果缓冲区满了
		{
			i = 0;
			HAL_UART_Transmit_DMA(&huart1,getbuffer,10);//将缓冲区十个字节的数据发送
			Wait_Tx_Complete();
			HAL_UART_Transmit(&huart1,(uint8_t *)"\r\n",1,1000);
			HAL_UART_Transmit_DMA(&huart1,(uint8_t *)data2,7);
			Wait_Tx_Complete();

		}

  }
  /* USER CODE END 3 */
}

运行结果

在这里插入图片描述

文章来源:https://blog.csdn.net/m0_72065741/article/details/135764242
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。