stm32串口使用DMA模式接收发送数据

stm32串口使用DMA模式接收发送数据

在cubeMX中调整DMA相关设置
在DMA Setting里点击Add添加USART1_TX,Mode有两种模式,
一种是普通模式,使用一次发送语句就发一次;
另一种是循环模式,使用一次发送会一直发送。
这里发送我选择普通模式,接收选择循环模式。
在这里插入图片描述
在这里插入图片描述
省略之前串口相关设置,想了解的可以看我之前串口的相关文章

生成代码,

定义相关变量

#define RXBUFFERSIZE  256     //最大接收字节数
char RxBuffer[RXBUFFERSIZE];   //接收数据
uint8_t aRxBuffer;			//接收中断缓冲
uint8_t Uart1_Rx_Cnt = 0;		//接收缓冲计数

在main函数中打开串口DMA循环接收

/* USER CODE BEGIN 2 */
HAL_UART_Receive_DMA(&huart1, (uint8_t *)&aRxBuffer, 1);
/* USER CODE END 2 */

while循环中添加发送函数

HAL_Delay(1000);
HAL_UART_Transmit_DMA(&huart1, (uint8_t *)"test\n", 5); 	

重写接收中断回调函数,功能是把收到的数据再发送出去

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(huart);
  /* NOTE: This function Should not be modified, when the callback is needed,
           the HAL_UART_TxCpltCallback could be implemented in the user file
   */
 
	if(Uart1_Rx_Cnt >= 255)  //溢出判断
	{
		Uart1_Rx_Cnt = 0;
		memset(RxBuffer,0x00,sizeof(RxBuffer));
		HAL_UART_Transmit(&huart1, (uint8_t *)"数据溢出", 10,0xFFFF); 	
        
	}
	else
	{
		RxBuffer[Uart1_Rx_Cnt++] = aRxBuffer;   //接收数据转存
	
		if((RxBuffer[Uart1_Rx_Cnt-1] == 0x0A)&&(RxBuffer[Uart1_Rx_Cnt-2] == 0x0D)) //判断结束位
		{
			HAL_UART_Transmit(&huart1, (uint8_t *)&RxBuffer, Uart1_Rx_Cnt,0xFFFF); //将收到的信息发送出去
      		while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX);//检测UART发送结束
			Uart1_Rx_Cnt = 0;
			memset(RxBuffer,0x00,sizeof(RxBuffer)); //清空数组
		}
	}
	
	//HAL_UART_Receive_DMA(&huart1, (uint8_t *)&aRxBuffer, 1);   //再开启接收中断
}

这里为什么不用

HAL_UART_Transmit_DMA()

这个函数呢?

实际测试过程中发现在回调函数中使用DMA方式发送数据会有丢包现象,在main函数中使用是没有问题的,暂时没有找到解决办法。

这里主要测试了DMA接收数据是正常的,使用DMA串口收发的主要目的也是防止大量接收串口数据时产生大量中断,占用大量cpu时间,导致程序运行卡顿。

运行结果
在这里插入图片描述


版权声明:本文为qq_30658583原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。