STM32 空闲中断+DMA数据收发

实现串口空闲中断+DMA接收数据

  1. 使用STMCubeMX创建工程并设置UART和DMA,注意一点是有时候CUBE生成代码时候,UART初始化在MDA初始化之前,我之前的文章提过,这样DMA会不好使,所以要看好一定要先初始化DMA。

STM32 空闲中断+DMA数据收发_第1张图片
STM32 空闲中断+DMA数据收发_第2张图片

  1. 设置空闲中断
    STM32 空闲中断+DMA数据收发_第3张图片
  2. 初始化时候打开串口DMA接收中断
HAL_UART_Receive_DMA(&huart1, rx_buff, RX_SIZE);
  1. 编写中断处理函数,"__HAL_DMA_GET_COUNTER(huart1.hdmarx)"是获取存储空间的剩余值。所以收到的数据就是存储值减去剩余值。
#define RX_SIZE 128
uint8_t rx_len = 0;
uint8_t recv_flag = 0;
uint8_t rx_buff[RX_SIZE] = {0};

void User_Uart1_IRQ(void)
{
	static uint8_t temp = 0;
	if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE) == SET)
	{
		HAL_UART_DMAStop(&huart1);
		rx_len = RX_SIZE - __HAL_DMA_GET_COUNTER(huart1.hdmarx);
		recv_flag = 1;
		HAL_UART_Receive_DMA(&huart1, rx_buff, RX_SIZE);
	}
}

将此函数添加到stm32xx_it.h的USART1_IRQHandler()函数里面,系统自带的“HAL_UART_IRQHandler(&huart1);”不要删除,如果删除,需要在自己调用的函数清除读和空闲标志位,不删除我们可以不用管这些。

void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */
	User_Uart1_IRQ();
  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */

  /* USER CODE END USART1_IRQn 1 */
}
  1. 主函数
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		if(recv_flag == 1)
		{
			// HAL_UART_Transmit(&huart1, rx_buff, rx_len, 100);	// 正常发送	
			HAL_UART_Transmit_DMA(&huart1, rx_buff, rx_len);	// 使用DMA发送
			rx_len = 0;
			recv_flag = 0;
		}
  }
  1. 测试
    STM32 空闲中断+DMA数据收发_第4张图片

你可能感兴趣的:(STM32系类,stm32,单片机,arm)