0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

DMA 实战指南:零 CPU 占用玩转高速数据传输

信盈达 2026-01-04 09:15 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

嵌入式开发时,大家是不是都有过这种崩溃场景:

  • 采集一个传感器数据,本来以为只是简单的 ADC → 内存,结果发现 CPU 忙得要死;
  • 想收点串口数据,CPU 每次被中断打断,延迟累积到系统卡顿;
  • 数据传输量一上来,系统直接掉帧甚至死机。

很多初学者遇到这种情况,第一反应是“是不是代码写得不够高效”。但事实是:你再怎么优化循环,CPU 亲自搬数据就是效率低。

解决方案其实很明确——用 DMA(Direct Memory Access,直接存储器访问)。如果你会合理使用 DMA,很多“看似不可避免的性能瓶颈”都能迎刃而解。今天我们就来聊聊 DMA 的工作原理、常见应用和实战技巧。


一、DMA 究竟是什么?

DMA 的核心思路很简单:把数据搬运工作交给硬件去做。

在没有 DMA 的情况下,数据传输的流程大概是:

  1. 外设产生数据;
  2. CPU 中断响应;
  3. CPU 把数据读出来放到内存。

而有了 DMA:

  1. 外设和 DMA 控制器直接“勾搭”;
  2. 数据绕过 CPU,直接搬到内存。

这样一来,CPU 不用再做“快递员”,可以专心处理逻辑,系统响应速度和并发能力都能上一个台阶。


二、DMA 的常见应用场景

1. 串口数据接收(UART DMA)

如果你做过大数据量的串口通信,就会发现中断方式很容易丢数据。

  • DMA 可以配置成循环缓冲区,数据一来就自动写入 RAM
  • CPU 只需要在合适的时候检查缓冲区,不用每个字节都处理中断。

2. ADC 连续采样

很多传感器需要高速采样,比如电机控制中的电流检测

  • 普通方式下,CPU 每次采样要响应 ADC 中断,很快就“累趴”;
  • 用 DMA,可以把采样结果自动存到数组里,形成数据流,CPU 后续再批量处理。

3. 内存到外设数据传输

比如 SPI 发送、DAC 输出波形:

  • 传统方式要一个字节一个字节写寄存器
  • DMA 可以直接把内存中的一段缓冲区刷到外设寄存器,效率极高。

4. 内存到内存传输

一些芯片的 DMA 支持内存块搬运,可以用来快速清零数组、搬运数据结构,CPU 不用一个循环一个循环写。


三、DMA 配置的关键要点

很多同学第一次用 DMA,发现配置比想象中复杂。其实总结起来,主要是以下几个步骤:

  1. 确定通道/流
  • DMA 控制器通常有多个通道,对应不同的外设。
  • 要查手册,看你的外设挂在哪个 DMA 通道上。
  • 配置源地址和目的地址
    • 源地址可以是外设寄存器,比如 ADC_DR。
    • 目的地址一般是内存数组。
    • 有时候是反过来,比如内存 → SPI。
  • 配置传输方向
    • 外设到内存(ADC、UART RX);
    • 内存到外设(SPI TX、DAC);
    • 内存到内存。
  • 配置数据长度和传输模式
    • 单次搬运几个字节?总共搬多少?
    • 是循环模式(buffer 自动回绕)还是普通模式?
  • 启动 DMA
    • 记得在外设使能之前配置好 DMA;
    • 启动顺序有讲究,比如 UART DMA 要先开 DMA 再开 UART 接收。

四、实战技巧:避免常见坑

技巧 1:循环缓冲 vs 普通模式

  • 如果数据源是持续的(比如串口、ADC),用循环缓冲更稳。
  • 如果只是一次性发送一段数据(比如 SPI 发命令),普通模式即可。

技巧 2:善用中断回调

DMA 虽然能自动搬数据,但你还是得知道“什么时候搬完”。

  • 可以开传输完成中断,在回调函数里处理数据。
  • 对于循环模式,可以用半传输中断,做到“边采集边处理”。

技巧 3:缓存对齐问题

有些 MCU 的 DMA 对地址有对齐要求,比如 4 字节对齐,否则性能下降甚至报错。写代码前要看手册。

技巧 4:注意总线带宽

DMA 不是“无限快”,它也占用内存总线。

  • 多个 DMA 通道同时工作时,可能会互相抢占。
  • 解决方法:错峰启动,或者降低非关键任务的优先级。

技巧 5:与 CPU 配合

DMA 搬数据的同时,CPU 可能要访问同一片内存。

  • 要小心数据一致性问题,可以用“双缓冲”或者加锁机制。

五、案例分享

案例 1:ADC + DMA 实现波形采集

某项目需要 10kHz 的 ADC 采样,用中断方式 CPU 占用率高达 70%。

→ 换成 DMA 循环搬运到数组,CPU 占用率直接降到 5% 以下,系统反应流畅。

案例 2:UART 接收不丢包

串口调试工具长时间发送数据,CPU 用中断处理时经常丢字节。

→ 改用 DMA + 环形缓冲 + IDLE 中断检测帧间隔,接收稳定,再也没掉过包。

案例 3:SPI 高速传输

OLED 屏幕更新一帧图像需要传 8KB 数据,用循环写寄存器方式刷新率只有 20fps。

→ DMA 一次传输缓冲区,刷新率提高到 60fps,画面流畅无比。


六、总结

DMA 对嵌入式开发来说,是“必学技能”之一。很多人初学时嫌它复杂,继续让 CPU 自己“跑腿”,结果系统卡顿、性能不达标。其实只要掌握几个要点:

  1. 了解外设和 DMA 通道的映射关系;
  2. 正确配置源地址、目的地址和传输模式;
  3. 结合中断回调实现数据处理;
  4. 注意带宽和缓存一致性问题。

你就能真正实现“零 CPU 占用的高速传输”,让系统既高效又稳定。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • cpu
    cpu
    +关注

    关注

    68

    文章

    11370

    浏览量

    226396
  • 数据传输
    +关注

    关注

    9

    文章

    2251

    浏览量

    67803
  • dma
    dma
    +关注

    关注

    3

    文章

    584

    浏览量

    106381
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    CW32L052单片机支持DMA实现高速数据传输

    CW32L052支持DMA(Direct Memory Access),即直接内存访问,无需CPU干预,实现高速数据传输
    的头像 发表于 02-27 11:36 2375次阅读

    ADXRS453Z的芯片支持使用STM32单片机的DMA数据传输功能吗?

    ADXRS453Z的芯片支持使用STM32单片机的DMA数据传输功能吗?如果,不能,考虑到我们的数据传输还是挺多的,那么常规的SPI通信方式占用大量的
    发表于 12-29 07:47

    基于FPGA的高速LVDS数据传输

    高速LVDS数据传输方案和协议基于FPGA的高速LVDS数据传输本人在北京工作6年,从事FPGA外围接口设计,非常熟悉高速LVDS
    发表于 03-01 18:47

    Serial RapidIO接口DMA数据传输

    数据传输本人已经在多个基于DSP和PowerPC信号处理板上调试验证了Serial RapidIO Endpoint Master DMA功能.1. Master DMA Write数据传输
    发表于 08-23 13:27

    请问ADXRS453Z的芯片支持使用STM32单片机的DMA数据传输功能吗?

    ADXRS453Z的芯片支持使用STM32单片机的DMA数据传输功能吗?如果,不能,考虑到我们的数据传输还是挺多的,那么常规的SPI通信方式占用大量的
    发表于 08-10 08:13

    DMA数据传输速率是多少?

    DMA数据传输速率是多少?由于DMACPU无关,所以CPU的速率可能不高。你知道DMAC的时钟是什么吗? 以上来自于百度翻译 以下为原
    发表于 05-14 11:13

    怎么实现基于FPGA的具有流量控制机制的高速串行数据传输系统设计?

    本文介绍了基于Xilinx Virtex-6 FPGA的高速串行数据传输系统的设计与实现,系统包含AXI DMA和GTX串行收发器,系统增加了流量控制机制来保证高速
    发表于 05-25 06:45

    stm32数据传输的相关资料分享

    简介DMA,全称Direct Memory Access,即直接存储器访问。DMA传输数据从一个地址空间复制到另一个地址空间,提供在外设和存储器之间或者存储器和存储器之间的
    发表于 02-22 06:58

    DMA进行数据传输CPU进行数据传输的疑问

    原先的总线矩阵+仲裁器结构中的数据总线进行数据传输的? 接上一个问题,如果是的话,那么当进行DMA数据传输时,必定是需要占用
    发表于 05-25 17:18

    基于FPDP的高速数据传输系统设计

    基于FPDP的高速数据传输系统设计 随着电子技术的高速发展,越来越多的信号处理系统,需要高速数据采集和大吞吐量的
    发表于 12-01 09:41 2502次阅读
    基于FPDP的<b class='flag-5'>高速</b><b class='flag-5'>数据传输</b>系统设计

    基于Zynq-7000的SRIO高速数据传输设计与实现

    用来控制DMA数据传输和SRIO事务处理,ARM只进行简单的参数设置,能够完成SRIO各种事务类型的传输.,实际应用表明,该系统具有操作简便、高效的特点,同时减轻了CPU的负担,达到
    发表于 12-21 11:37 31次下载
    基于Zynq-7000的SRIO<b class='flag-5'>高速</b><b class='flag-5'>数据传输</b>设计与实现

    DMA数据传输(源代码分享)

    手头项目也需要加入DMA数据传输,以最大限度地提升CPU效率,于是测试了一下XMEGA的DMA模块,把一块内存中的数据
    的头像 发表于 04-27 09:22 1w次阅读

    DMA数据传输在SPEAR300实现高速串口驱动设计

    DMA数据传输无需CPU的参与,是一种更加高效的数据传输方式。现有的DMA数据传输方案都是基于
    发表于 04-04 12:23 2080次阅读
    <b class='flag-5'>DMA</b><b class='flag-5'>数据传输</b>在SPEAR300实现<b class='flag-5'>高速</b>串口驱动设计

    STM32CubeMX-串口开启DMA进行数据传输

    STM32CubeMX笔记-串口开启DMA进行数据传输
    发表于 12-27 18:40 7次下载
    STM32CubeMX-串口开启<b class='flag-5'>DMA</b>进行<b class='flag-5'>数据传输</b>

    stm32数据传输

    简介DMA,全称Direct Memory Access,即直接存储器访问。DMA传输数据从一个地址空间复制到另一个地址空间,提供在外设和存储器之间或者存储器和存储器之间的
    发表于 12-28 19:08 8次下载
    stm32<b class='flag-5'>数据传输</b>