蓝桥杯HAL库-串口接收不定长数据(空闲中断+DMA)

本文介绍了如何在STM32中利用串口空闲中断和DMA实现接收不定长数据,包括设置接收缓冲区、启用空闲中断和DMA、编写中断函数以及处理数据长度和溢出问题。
摘要由CSDN通过智能技术生成

 串口接收中断函数原型:

HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)

单纯的DMA(或中断)必须要接收到指定数量的数据才能完全读走数据,否则数据会一直被缓存无法读取。适合定长数据帧。

对于串口接收不定长数据有

   方式:《  串口空闲中断+DMA  》 。

        想让串口接收不定长数据,需要我们开启串口的空闲中断(IDLE)。空闲中断指:stm32的数据总线在接受数据过程中,如果在接收一个字节所需要的时间内没有在接收到新数据,单片机就会进入串口空闲中断,表面此时不定长数据已经接收完成了。即会自动触发单片机的空闲中断IDLE标志位,引发空闲中断。

空闲中断的优点在于省去了帧头帧尾的检测,进入中断程序即意味着已经接收到一组完整数据,及时对数据处理或将数据转移出缓冲区即可。

注:串口空闲中断在串口无数据接收的情况下,是不会产生的。产生的条件是当清除空闲标志位后,必须有接收到第一个数据后,才开始触发,一旦接收的数据断流,没有接收到数据,即产生空闲中断

    当我们要接收不定长数据时,常常将串口接收空闲中断结合DMA使用。有了DMA,数据的一个个接收不会经过再叨扰触发串口中断,而是每当数据接收完毕后才会触发串口空闲中断。

代码思路:

//定义:
uint8_t Rx_buf[50];   //接收缓冲区
uint16_t Rx_long=0;    //接受数据的长度
uint8_t Buf_long =50;   //接收缓冲区大小

①首先要在主函数里定义一个接收数据的缓冲区,一般用数组。在串口初始化时要开启串口的空闲中断。

 __HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);//使能空闲中断

②然后在主函数里使能串口DMA接收

HAL_UART_Receive_DMA(&huart1,(uint8_t *)buf,buf_long); //使能串口DMA接收

--------------------此时只要接收数据停止时,就会触发空闲中断。

③在中断函数中写入要进行的内容

void USART2_IRQHandler(void)
{
  /* USER CODE BEGIN USART2_IRQn 0 */

  /* USER CODE END USART2_IRQn 0 */
  HAL_UART_IRQHandler(&huart2);
  /* USER CODE BEGIN USART2_IRQn 1 */
if(__HAL_UART_GET_FLAG(&huart2,UART_FLAG_IDLE)==SET)//判断是否为空闲中断 SET表示发送了空闲中断
		{
			__HAL_UART_CLEAR_IDLEFLAG(&huart2);//清除空闲中断标志位
			HAL_UART_DMAStop(&huart2); //停止DMA
			//Rx_long = Buf_long- __HAL_DMA_GET_COUNTER(huart->hdmarx);
			Rx_long = Buf_long-__HAL_DMA_GET_COUNTER(&hdma_usart2_rx);//计算接收数据的长度
			HAL_UART_Transmit(&huart2,Rx_buf,Rx_long,10); //将接收的数据发送显示在电脑上
			HAL_UART_Receive_DMA(&huart2,Rx_buf,Buf_long); //重新开启DMA转运
		}
  /* USER CODE END USART2_IRQn 1 */
}

④下载程序,实验现象

注:我们设置的缓冲区长度大小为50字节。如果待接收的数据大于缓冲区长度,这时串口接收就会无法接收该数据。若出现此问题,把缓冲区的长度改大即可。

  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值