问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

STM32串口DMA收发数据详解 | 高效传输与实战代码

创作时间:
作者:
@小白创作中心

STM32串口DMA收发数据详解 | 高效传输与实战代码

引用
CSDN
1.
https://blog.csdn.net/weixin_46716828/article/details/145592824

串口通信是STM32开发中最常用的功能之一,而DMA(直接存储器访问)技术能显著提升数据传输效率,减少CPU占用。本文从原理到实战,详细讲解如何配置STM32的串口DMA收发功能,并提供可直接复用的代码和避坑指南。

为什么需要DMA?

在传统的串口中断收发模式下,每个字节的传输都需要CPU介入,导致资源浪费和响应延迟。例如:

  • 发送1KB数据需触发1024次发送中断,占用大量CPU时间。
  • 高频率传感器数据采集时,可能因中断堆积导致数据丢失。

DMA的核心优势:

  • 零CPU干预:数据直接在内存与外设间传输,释放CPU处理其他任务。
  • 支持连续传输:单次配置即可完成多字节收发,适合大数据量场景(如图像传输、高速通信)。

硬件与开发环境

  • 硬件平台:STM32系列(以STM32H750为例)。
  • 开发工具:STM32CubeMX + STM32CubeIDE。
  • 外设配置:USART1(PA9-TX, PA10-RX),DMA1 Stream3(发送),DMA1 Stream2(接收)。

CubeMX配置步骤

  1. 开启串口USART1
  • 模式:Asynchronous(异步通信)。
  • 参数:波特率115200,8位数据,无校验,1停止位。
  1. 配置DMA接收通道
  • Direction: Peripheral To Memory(外设到内存)。
  • Priority: low(低优先级)。
  • Mode: Normal(单次传输)或Circular(循环传输,适合持续接收)。
  1. 配置DMA发送通道
  • Direction: Memory To Peripheral(内存到外设)。
  1. 生成代码:生成STM32CubeIDE工程并打开。

代码实现与解析

  1. DMA接收数据

    //主函数初始化代码
    HAL_UART_Receive_DMA(&huart1, Receive_data, sizeof(Receive_data));
    __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); //使能空闲中断
    
    //串口中断函数代码
    void USART1_IRQHandler(void)
    {
        if (__HAL_UART_GET_IT( &huart1, UART_IT_IDLE ) != RESET)         //判断是否是空闲中断
        {
            __HAL_UART_CLEAR_IDLEFLAG(&huart1);                         //清除空闲中断标志
            HAL_UART_AbortReceive(&huart1);                             //停止DMA
            Data_len = sizeof(Receive_data) - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);	            
            //接收了多长的数据
            Data_flag = 1;                                               //接收中断标志位
            HAL_UART_Receive_DMA(&huart1,Receive_data,sizeof(Receive_data));    //使能接收
        }
        HAL_UART_IRQHandler(&huart1);
    }
    
  2. DMA发送数据

    //主函数循环中
    if (Data_flag) {                                                //判断DMA是否接收完成
        HAL_UART_Transmit_DMA(&huart1, Receive_data, Data_len);    //DMA发送数据
        Data_flag = 0;                                      //标志位置0
    }
    
  3. 测试结果

关键问题与解决方案

  1. DMA传输不触发
  • 检查点
  • DMA通道与流是否与CubeMX配置一致(如USART1_TX对应DMA1 Stream5)。
  • 是否调用HAL_UART_Transmit_DMA()前启用DMA时钟。
  1. 数据接收不完整
  • 优化方案
  • 启用双缓冲区机制:交替切换接收缓冲区,防止数据覆盖。
  1. DMA与中断冲突
  • 优先级设置
  • 在NVIC中为DMA和串口中断分配合理优先级(推荐DMA > 串口)。

应用场景

  1. 高速数据采集:通过DMA接收多通道ADC数据(如振动传感器波形)。
  2. 无线通信模块:ESP8266/蓝牙模组的长数据包透传。
  3. 工业协议解析:Modbus-RTU协议中高效处理多寄存器读写。

总结

DMA是STM32高性能开发的必备技能,合理使用可大幅提升系统效率。本文代码已通过实测,可直接使用。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号