提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

串口在单片机中是使用比较频繁的一部分,一般我们人机交互就会使用到串口。串口的输出比较简单直接调用发送函数即可,接收数据就要稍微麻烦一些,因为我们接收的一般是不定长的数据。但是最近使用到了stm32的串口接收的时候,发现hal库竟然有提供串口空闲中断接收函数,无需配置和自己写中断函数。


一、串口空闲中断是什么?

一般我们串口接收的时候都是使用的RXNE,接收到一个字节数据就进入一次中断,然后把它放入缓存,但是数据量很大的时候会频繁进入中断影响单片机的时效性。这时就可以使用到IDLE空闲中断,即在接收到一段数据后在一定的时间检测到没有数据到来,就认为此时串口总线空闲便产生一个空闲中断。

二、使用步骤

1.hal库空闲中断接收函数


在stm32f1xx_hal_uart.h中

//在阻塞模式下接收一定数量的数据,直到接收到预期数量的数据或发生空闲事件。
HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint16_t *RxLen, uint32_t Timeout);
//在中断模式下接收一定数量的数据,直到接收到预期数量的数据或发生空闲事件。
HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
//在DMA模式下接收一定数量的数据,直到接收到预期数量的数据或发生空闲事件。
HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
//使用空闲中断时的接收回调函数
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size);

HAL_UARTEx_ReceiveToIdle_IT()

/**
  * @brief 在中断模式下接收一定数量的数据,直到接收到预期数量的数据或发生空闲事件。
  * @note   接收由此功能调用启动。由于RXNE和空闲事件引发的UART中断,接收的进一步进展得以实现。在接收结束时调用Callback,指示接收到的数据元素的数量。
  * @param huart UART handle.
  * @param pData	指向数据缓冲区(uint8_t或uint16_t数据元素)的指针。
  * @param Size  要接收的数据元素的大小(uint8_t或uint16_t)。
  * @retval HAL status
  * */
HAL_StatusTypeDef	HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);

2.使用方法

  1. 在主函数中调用HAL_UARTEx_ReceiveToIdle_IT()
  2. 然后在回调函数 HAL_UARTEx_RxEventCallback()中做相应处理。
int main(void)
{
  /* USER CODE BEGIN 1 */
	//__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);
  /* 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_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  //空闲中断接收
  HAL_UARTEx_ReceiveToIdle_IT(&huart1,Uart_ReadCache,410);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
//空闲中断回调函数,参数Size为串口实际接收到数据字节数
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
	if(huart->Instance==USART1)
	{
		//把收到的一包数据通过串口回传
		HAL_UART_Transmit(&huart1,Uart_ReadCache,Size,0xff);
		//再次开启空闲中断接收,不然只会接收一次数据
		HAL_UARTEx_ReceiveToIdle_IT(&huart1,Uart_ReadCache,410);
	}
}

3.最终效果

实际效果

总结

使用stm32 hal自带的空闲中断函数后我们通过串口接收不定长的数据变得十分的方便了,只需要调用两个函数即可。不像刚开始的时候使用串口空闲中断还的自己开启中断和自己编写中断回调函数,大大地提高了我我们开发的效率。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐