STM32HAL库DMA和串口接收不定长字符串

Posted QWQ_DIODA

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32HAL库DMA和串口接收不定长字符串相关的知识,希望对你有一定的参考价值。

前言

前一阵子瞎搞,想整VS2019开发stm32,毕竟优雅的IDE界面谁能拒绝呐?
可是最后bug一堆。。。就先放弃了,于是就改回MDK5了。
瞎搞的时候就是搞得DMA串口接收不定长信息,既然搞了,总得有点收获吧


DMA部分

DMA就是一个有特权的搬运工,能在CPU管不着的情况下,自己吧数据从一个地址搬到另一个地址。

我们只需要知道告诉DMA:
要把数据从哪儿搬到哪儿,一次搬多少,不停的搬还是搬一次就行了

我们只需要设置DMA有货就搬,USART有多少搬多少就行了

即:循环模式,外设到内存,一次一字节,每次搬运数量必须大于自己定义的数组大小

USART部分

STM32的USART有很多个中断
平常我们接收数据一般所用为RXNE(读数据寄存器非空)中断
这种使用方式的缺点是只能接收定长的数据

但是,32的串口还有一个总线空闲中断IDLE!
在这里插入图片描述
也就是说,当你的接收缓冲寄存器里面完了没数据了就会产生一个中断

并且,他只会在RXNE被再次置高的时候,才能被置高,也就是说,你啥也不干导致总线空闲的时候,他也会很聪明的不打开中断。

步骤

  • 定义一个接收缓冲的数组,不能低于你的最大传输数据量
  • 初始化串口
  • 初始化串口DMA(循环)
  • 打开IDLE中断
  • 开启DMA传输
  • 在中断函数中判断IDLE中断是否执行
  • 清空IDLE标志位
  • 停止DMA传输(处理数据防止干扰)
  • 获取数据长度
  • 接收缓冲数组数据末尾加上 ‘\\0’
  • 发送接收缓冲区数据,验证接收
  • 重新打开DMA

代码

初始化

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

/*初始化全局变量*/
uint8_t Rx_buff[100];
uint32_t Rx_Length = 0;
usart.c
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
	cubeMX自生成部分省略
  /* USER CODE BEGIN USART1_MspInit 1 */
  
 	/* 打开DMA传输,地址为从USART_DR到Rx_Buff */
	HAL_UART_Receive_DMA(&huart1,(uint8_t*)Rx_buff,100);
	/* 打开串口IDLE中断 */
	__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);
	
  /* USER CODE END USART1_MspInit 1 */
  }
}
中断部分

void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */

  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */
	if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE)!=RESET)
	{
		/* 清空IDLE标志位 */
		__HAL_UART_CLEAR_FLAG(&huart1,UART_FLAG_IDLE);
		/* DMA传输停止 */
		HAL_UART_DMAStop(&huart1);
		
		/* 获取接收数据长度 */
		Rx_Length = 100 - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
		/* 在数据末尾添加 '\\0' 表示接收结束 */
		Rx_buff[Rx_Length] = '\\0';
		
		/* 像串口发送输出结果 */
		printf("接受内容:%s\\n",Rx_buff);
		printf("长度:%d\\n\\r",Rx_Length);
		
		/* 重新打开DMA传输 */
		HAL_UART_Receive_DMA(&huart1,(uint8_t*)Rx_buff,100);
	}
  /* USER CODE END USART1_IRQn 1 */
}

效果

在这里插入图片描述
接收的第一个数据无法接收,看了半天也不知道为啥,有懂的大佬可以说一下(真的感谢!!)在这里插入图片描述

以上是关于STM32HAL库DMA和串口接收不定长字符串的主要内容,如果未能解决你的问题,请参考以下文章

STM32怎么接收不定长串口数据

STM32F103VET6基于STM32CubeMX创建串口中断+ DMA 不定长数据接收

STM32CubeMX HAL库串口+DMA数据发送不定长度数据接收

STM32怎么接收不定长串口数据

STM32G431 CubeMx HAL库——使用IDLE+RXNE实现串口不定长数据接收

STM32一种使用HAL,DMA,IDLE,POLLING的方式来处理UART的不定长接收机制