STM32 HAL库USART串口通信详解:发送与不定长数据接收实战指南

目录

STM32 HAL库—USART:串口发送和不定长数据接收

前言:

适用场景:

实现目标:

软硬件环境:

串口通信基础知识:

1. USART(通用同步异步收发器)

2. DMA(直接存储器访问)

USART+DMA 的数据传输流程:

cudemx基础配置:

代码实现(关键部分):

1.数组(缓冲区)定义

2.启动 UART 接收 中断

3. 重定义数据接收中断回调函数

4. 处理数据后回显

测试与验证:

注意要点:

结语:


STM32 HAL库—USART:串口发送和不定长数据接收

前言:

        在嵌入式系统中,串口通信(UART) 是最常见的通信方式之一。无论是调试信息的输出,还是设备间的数据交互,UART 都是不可或缺的通信手段。然而,在传统的串口通信中,如果使用阻塞模式进行数据收发,CPU 需要不断轮询状态寄存器,导致资源浪费,并降低系统的响应能力。

        为了解决这一问题,我们可以借助 DMA(直接存储器访问) 进行串口数据传输。DMA 允许外设直接访问内存,从而在数据传输过程中释放 CPU 资源,使其能够执行其他任务,提高系统的并行处理能力。本篇博客的目标是分享如何使用 STM32 HAL库 和 CubeIDE,基于 DMA+中断 实现高效的 UART 通信。

适用场景:

本次实验适用于以下应用场景:

  • 需要实时通信的嵌入式系统(如物联网设备、工业控制)

  • 需要高速数据传输,且 CPU 负担较重的应用

  • 需要非阻塞式通信,保证系统主任务流畅运行

  • 实现目标:

    1. 配置 UART 进行串口通信,实现数据的发送与接收。

    2. 采用 DMA 进行数据传输,提高系统效率,减少 CPU 负担。

    3. 结合 中断机制 处理不定长数据,提高数据接收的灵活性。

    4. 通过 STM32CubeIDE 实现代码编写、下载与调试。

    软硬件环境:

  • 开发板:STM32F407 开发板

  • 开发环境:STM32CubeIDE + STM32CubeMX

  • 调试工具:ST-LINK V2

  • 串口工具:USB 转串口模块(CH340G)、串口调试助手(如XCOM)

  • 串口通信基础知识:

    在进入实际配置和代码编写之前,我们先回顾一下 UART 和 DMA 的基本概念。

    1. USART(通用同步异步收发器)

          UART(Universal Asynchronous Receiver/Transmitter)是一种 异步 串行通信协议,它无需同步时钟信号,仅通过起始位、数据位、校验位和停止位进行数据传输。基本参数包括:

  • 波特率(Baud Rate):表示每秒传输的位数,例如 115200 bps。

  • 数据位(Data Bits):一般为 8 位。

  • 校验位(Parity Bit):可选,用于错误检测(本次实验不使用)。

  • 停止位(Stop Bit):表示数据帧结束,一般为 1 位。

  • STM32 的 UART 采用 串行数据寄存器(DR)、状态寄存器(SR)和控制寄存器(CR) 进行数据收发和控制。

    2. DMA(直接存储器访问)

    DMA(Direct Memory Access)是一种允许外设直接访问内存的机制,它能够在不经过 CPU 参与的情况下完成数据传输。DMA 的主要特点包括:

  • 降低 CPU 负担,提高系统响应速度。

  • 提高数据传输效率,特别适用于大数据量传输。

  • 支持多通道,可以同时处理多个数据流。

  • 在 STM32 中,DMA 传输方式一般有 外设到内存(接收)、内存到外设(发送)、内存到内存 三种模式。

    USART+DMA 的数据传输流程:

    为了让数据传输更加高效,我们采用 DMA+中断 结合的方式:

    1. 发送数据(USART_TX + DMA)

    2. 在程序中调用 HAL_UART_Transmit_DMA() 函数,将数据从内存传输到 UART 发送缓冲区。

    3. DMA 自动完成数据传输,无需 CPU 轮询。

    4. 接收数据(USART_RX + NVIC)

    5. 开启USART接收中断。

    6. 结合 HAL_UARTEx_ReceiveToIdle_IT() 使系统在数据接收完毕(或检测到空闲信号)时触发中断

    cudemx基础配置:

    (1)配置系统时钟(选择HSE外部晶振,主频设置为168MHz)。

    (2)USART通信配置:

         使能RX和TX引脚GPIO时钟和USART时钟;选择异步通信模式,基础配置为波特率115200,8比特(包含校验位),无校验位,一位停止位,接收发送模式。

    (3)DMA配置:

         打开USART1_TX的DMA通道(系统自动选择对应映射的通道),传输方向为内存到外设。

    (4)中断配置:串口一全局中断使能和DMA中断使能。

    代码实现(关键部分):

    以下是本实验的核心代码逻辑:、

    1.数组(缓冲区)定义
    #define max_buf 50
     uint8_t tx_buf[max_buf]; //待发送的数据数组
     uint8_t rx_buf[max_buf]; //存放接收到的数据
     uint8_t flag=0;          //标志位,是否收到数据
     uint8_t length=0;        //数据长度
    
    2.启动 UART 接收 中断
      /* USER CODE BEGIN 2 */
    
      HAL_UARTEx_ReceiveToIdle_IT(&huart1, rx_buf, max_buf);
    
      /* USER CODE END 2 */
    
      /* Infinite loop */
      /* USER CODE BEGIN WHILE */
      while (1)
      {
    3. 重定义数据接收中断回调函数

           这里把函数写到了main.c的code4可修改代码块中。先判断中断触发源,并置位标志位,同时获取接受数组长度。(长度是由HAL_UARTEx_RxEventCallback自动计算返回的)

    /* USER CODE BEGIN 4 */
    void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
    {
    	if(huart->Instance==USART1)
    	{
    		flag=1;
    		length=Size;
    	}
    }
    /* USER CODE END 4 */
    4. 处理数据后回显

    本博客中是将数据反转后发出。再次调用HAL_UARTEx_ReceiveToIdle_IT函数接收数据,同时清零标志位。

      /* Infinite loop */
      /* USER CODE BEGIN WHILE */
      while (1)
      {
    	  if(flag==1)
    	  {
    		for(int i =0;i<length;i++)
    		{
    			tx_buf[i] = rx_buf[length -1 - i];    //将数据颠倒
    		}
    		tx_buf[length]='\0';
    
    		HAL_UART_Transmit_DMA(&huart1,tx_buf, length);         //使用DMA发送数据
    		HAL_UARTEx_ReceiveToIdle_IT(&huart1, rx_buf, max_buf); //接收不定长数据
    		flag=0;
    	  }
        /* USER CODE END WHILE */
        /* USER CODE BEGIN 3 */
      }
      /* USER CODE END 3 */
    }

    测试与验证:

    1. 打开串口调试助手,设置波特率为 115200,数据格式为 8N1

    2. 向 STM32 发送数据,STM32 在收到数据后将数据反转后会回显。

    3. 观察 STM32 输出信息,如果能够正确回显,则表示 DMA+中断结合的串口通信正常工作。

    注意要点:

    1. DMA 配置要匹配外设

    2. 方向要设置正确(内存到外设、外设到内存)。

    3. 数据宽度需匹配 UART(通常是字节单位)。

    4. 使用 HAL_UARTEx_ReceiveToIdle_IT() 处理不定长数据

      该函数能够在数据接收完成或者检测到空闲帧时,触发中断,适合接受不定长数据,避免固定长度数据带来的问题。

    5. 避免在中断回调中执行耗时操作

      如果数据量较大,建议将处理逻辑放在主循环中,避免阻塞其他中断。

    结语:

          本篇博客介绍了 UART 串口通信,并结合 DMA 和中断机制,实现了高效的数据传输方式。通过 DMA,可以让 CPU 专注于其他任务,而中断机制确保了不定长数据的正确接收。这种方法在 物联网、工业自动化 等领域有着广泛的应用。

    希望这篇博客能帮到你,如果你在实践中遇到问题,欢迎留言交流!🚀

    作者:Open-car

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32 HAL库USART串口通信详解:发送与不定长数据接收实战指南

    发表回复