STM32使用串口(空闲中断IDLE+DMA)接收ESP8266数据

串口空闲中断

ESP8266收发数据

一、在使用ESP8266模块时遇到的一些问题,首先是对模块数据的收发,我们在发送AT指令时会收到模块发送的反馈数据。在我们没有使用实时操作系统的情况下,通过HAL库的串口收发函数是比较难以完成工作的。我在参考了众多博客后总结了两种方法:
1、串口接收+50ms定时器
2、串口空闲中断
本文主要是介绍串口空闲中断

空闲中断的定义

空闲的定义是总线上在一个字节的时间内没有再接收到数据,USART_IT_IDLE空闲中断是检测到数据被接收后,总线上在一个字节的时间内没有再接收到数据的时候发生的。
而空闲中断又分为两种:
1、当接收到1个字节,会产生USART_IT_RXNE中断

2、当接收到一帧数据,就会产生USART_IT_IDLE中断

串口空闲中断(UART_IT_IDLE):STM32的IDLE的中断在串口无数据接收的情况下,是不会一直产生的,当清除IDLE标志位后,必须有接收到第一个数据后,才开始触发,一但接收的数据断流,没有接收到数据,即产生IDLE中断。IDLE位不会再次被置高直到RXNE位被置起(即又检测到一次空闲总线)。
IDLE置1之后它不会自动清0,也不会因为状态位是1而一直产生中断,它只有0跳变到1时才会产生,也可以理解为上升沿触发。所以,为确保下次空闲中断正常进行,需要在中断服务函数发送任意数据来清除标志位。

USART_IT_RXNE也是同理,只是判断空闲的标准不一样

在这里插入图片描述

void MX_USART2_UART_Init(void)
{

  /* USER CODE BEGIN USART2_Init 0 */

  /* USER CODE END USART2_Init 0 */

  /* USER CODE BEGIN USART2_Init 1 */

  /* USER CODE END USART2_Init 1 */
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 115200;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART2_Init 2 */
	__HAL_UART_CLEAR_IDLEFLAG(&huart2);//清除空闲中断标志位
	__HAL_UART_ENABLE_IT(&huart2,UART_IT_IDLE);//开启串口2的空闲中断
	
	memset(WiFi_RX_BUF,0,WiFi_RXBUFF_SIZE);     //清空WiFi接收缓冲区
	HAL_UART_DMAStop(&huart2);//停止DMA
	HAL_UART_Receive_DMA(&huart2,Usart2_RxBuff,USART2_RXBUFF_SIZE);
  /* USER CODE END USART2_Init 2 */

}

在串口初始化函数中开启空闲中断,首先是清楚空闲中断标志位,然后是使能UART_IT_IDLE中断。

void USART2_IRQHandler(void)
{
  /* USER CODE BEGIN USART2_IRQn 0 */
	if(__HAL_UART_GET_FLAG(&huart2,UART_FLAG_IDLE)!=RESET)
	{
		Usart2_RxCounter=0;
		__HAL_UART_CLEAR_IDLEFLAG(&huart2);//清楚空闲中断标志位
		HAL_UART_DMAStop(&huart2);//停止DMA接收以防止新的数据覆盖
		/*预计要接受的数据量-剩余待接收的数量=接收的数据数量*/
		Usart2_RxCounter+=(USART2_RXBUFF_SIZE-__HAL_DMA_GET_COUNTER(&hdma_usart2_rx));
		HAL_UART_Receive_DMA(&huart2,Usart2_RxBuff,USART2_RXBUFF_SIZE);
		Usart2_RxCompleted=1;//接收标志位置位1,代表数据已经接收
	}
  /* USER CODE END USART2_IRQn 0 */
  HAL_UART_IRQHandler(&huart2);
  /* USER CODE BEGIN USART2_IRQn 1 */

  /* USER CODE END USART2_IRQn 1 */
}

在中断函数中我们首先判断空闲中断标志位是否置位,如果if成立则清楚标志位,然后再停止DMA接收,以防止后来的数据覆盖缓存,然后再接收数据。

本人能力有限,若有错误的地方情多多包涵

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值