深入理解 DMA

在嵌入式开发中,数据传输效率往往是决定系统性能的关键因素。如果每一次数据搬运都需要 CPU 全程参与,不仅会占用大量处理器资源,还会导致系统响应延迟。而DMA(Direct Memory Access,直接存储器访问) 技术的出现,恰好解决了这一痛点。本文将从 DMA 的基本概念入手,详细拆解其发送与接收流程,并结合 STM32F103 系列芯片的 DMA 特性,帮助大家快速掌握这一核心技术。

一、DMA 是什么?一句话搞懂核心原理

简单来说,DMA 是一种无需 CPU 直接干预,就能实现外设与存储器、或存储器与存储器之间高速数据传输的硬件机制。

在没有 DMA 的系统中,当外设(如 UART、ADC、SPI)需要与内存交换数据时,CPU 必须全程 “盯梢”:先从外设寄存器读取数据,再写入内存;或者反过来从内存读取数据,再写入外设寄存器。这个过程中,CPU 完全被 “绑定”,无法处理其他任务,效率极低。

而 DMA 相当于在系统中开辟了一条 “专属数据通道”—— 外设和存储器可以直接通过这条通道传输数据,全程不需要 CPU 参与。只有当数据传输完成(或出现错误)时,DMA 才会通过中断的方式通知 CPU。这样一来,CPU 就能从繁琐的数据搬运工作中解放出来,专注于更重要的任务(如逻辑运算、用户交互、系统调度等),极大提升了系统整体效率。

这里需要明确几个关键对象的定义:

  • 外设:通常指外设的数据寄存器,比如 UART 的数据接收 / 发送寄存器、ADC 的转换结果寄存器、SPI 的数据缓冲区等;

  • 存储器:包括片内 SRAM(常用)、外部扩展存储器(如 SDRAM)、片内 Flash(一般用于数据读取,写入需特殊处理)。

二、DMA 的 “收发” 流程:用 UART 为例拆解每一步

DMA 的核心功能是 “数据传输”,而传输场景主要分为 “接收”(外设→存储器)和 “发送”(存储器→外设)。下面以最常用的 UART(串口)为例,结合具体流程,让大家直观理解 DMA 的工作方式。

2.1 DMA 接收流程:外设数据 “自动进内存”

当我们需要通过 UART 接收外部设备(如电脑、传感器)发送的数据时,DMA 接收的核心目标是:将 UART 接收寄存器中的数据,自动搬运到内存的指定缓冲区,无需 CPU 干预。具体步骤如下:

  1. UART 控制器先 “接活”:外部设备通过串口发送数据,UART 控制器接收到数据后,会先将数据暂存到自身的 “数据接收寄存器(DR)” 中;

  2. DMA 主动 “读数据”:DMA 控制器会实时监测 UART 接收寄存器的状态,一旦检测到有新数据(即 UART 的接收标志置位),就会通过硬件逻辑自动读取接收寄存器中的数据;

  3. DMA 自动 “写内存”:DMA 读取到数据后,会按照预先配置的 “目标内存地址”,将数据直接写入到内存的指定缓冲区(比如我们定义的uint8_t uart_rx_buf[1024]数组);

  4. 传输完成 “通知 CPU”:当 DMA 接收到指定长度的数据(或检测到 UART 停止位)后,会触发 “DMA 传输完成中断”,向 CPU 发送通知;

  5. CPU “收尾处理”:CPU 收到中断后,即可直接访问内存中的接收缓冲区(如uart_rx_buf),对数据进行解析、处理(如协议解析、数据校验等),无需再与 UART 寄存器交互。

核心结论:整个接收过程中,CPU 只需要在最后 “处理数据”,无需频繁查询 UART 寄存器状态,也不需要手动搬运数据 ——CPU 只关心内存中的最终结果

2.2 DMA 发送流程:内存数据 “自动发外设”

当我们需要通过 UART 向外发送大量数据(如日志、传感器批量数据)时,DMA 发送的核心目标是:将内存缓冲区中的数据,自动搬运到 UART 的发送寄存器,由 UART 硬件完成发送。具体步骤如下:

  1. CPU 先 “准备数据”:CPU 先将需要发送的数据(如字符串、数组)写入到内存的指定发送缓冲区(比如uint8_t uart_tx_buf[512]),这一步是 CPU 唯一需要参与的环节;

  2. DMA 主动 “读内存”:DMA 控制器按照预先配置的 “源内存地址”,从发送缓冲区中自动读取数据;

  3. DMA 自动 “写外设”:DMA 将读取到的数据,直接写入到 UART 的 “数据发送寄存器(DR)” 中;

  4. UART 硬件 “发数据”:UART 控制器检测到发送寄存器中有数据后,会自动将数据通过串口发送到外部设备,无需 DMA 干预;

  5. 传输完成 “通知 CPU”:当 DMA 将发送缓冲区中的所有数据都搬运到 UART 发送寄存器后,会触发 “DMA 传输完成中断”,通知 CPU 发送任务已完成;

  6. CPU “后续操作”:CPU 收到通知后,可以进行后续处理(如更新发送状态、准备下一批数据等)。

核心优势:即使需要发送大量数据,CPU 也只需 “初始化数据” 和 “处理中断”,中间的连续数据搬运完全由 DMA 和 UART 硬件完成,避免了 CPU 被 “卡死后台”。

三、STM系列的 DMA 特性:通道、优先级与实战要点

不同芯片的 DMA 控制器设计存在差异,而 STM32F103 系列作为嵌入式开发中的 “经典款”,其 DMA 特性具有代表性,掌握它能为后续其他 STM32 型号的学习打下基础。

3.1 核心硬件配置:2 个控制器,12 个通道

STM32F103 系列芯片内置了2 个独立的 DMA 控制器,分别为 DMA1 和 DMA2,两者的通道数量和支持的外设有所区别:

  • DMA1:拥有 7 个通道,主要负责低 / 中速外设的数据传输,支持的外设包括 UART1~UART3、SPI1、I2C1、ADC1、定时器等;

  • DMA2:拥有 5 个通道,除了支持部分外设(如 UART4~UART5、SPI2)外,还支持 “存储器到存储器” 的传输(DMA1 不支持这一功能),且部分通道可配合高速外设使用。

这里的 “通道” 可以理解为 DMA 控制器为不同外设分配的 “专属接口”—— 每个通道专门管理一个或多个外设的 DMA 请求。例如,DMA1 的通道 4 可以对应 UART1 的接收请求,通道 5 对应 UART1 的发送请求,这样不同外设的 DMA 请求就不会相互干扰。

3.2 优先级管理:解决 “抢资源” 问题

当多个外设同时向同一个 DMA 控制器发起数据传输请求时(比如 UART1 和 ADC1 同时需要用 DMA1 传输数据),就会出现 “资源竞争”。STM32F103 的 DMA 通过四级优先级机制解决了这一问题:

优先级从高到低分为:很高 > 高 > 中等 > 低,可通过软件编程(配置 DMA 通道的CCR寄存器)设置每个通道的优先级。

如果两个通道的软件优先级相同,则遵循 “通道编号越小,优先级越高” 的规则。例如,DMA1 的通道 2 和通道 4 优先级相同,此时通道 2 的请求会被优先响应。

在实际项目中,优先级配置需要结合业务需求:比如 “传感器数据采集(ADC)” 的优先级应高于 “日志发送(UART)”,避免关键数据丢失。

3.3 实战注意事项

  1. 通道与外设的对应关系:STM32 的 DMA 通道与外设是 “固定映射” 的,例如 UART1 的接收只能使用 DMA1 的通道 4,不能随意选择其他通道。开发时需查阅芯片手册的 “DMA 通道映射表”,确认正确的通道配置;

  2. 数据长度匹配:DMA 传输的数据单位(字节、半字、字)需要与外设寄存器和内存缓冲区的宽度一致。例如,UART 数据寄存器是 8 位(字节),则 DMA 需配置为 “字节传输”,否则会导致数据错误;

  3. 内存地址是否递增:如果需要传输连续数据(如数组),需开启 “内存地址递增模式”,让 DMA 自动累加内存地址;若传输固定地址的数据(如单个寄存器),则需关闭递增模式;

  4. 中断使能:关键场景(如传输完成、传输错误)需开启 DMA 中断,避免 CPU “漏判” 传输状态。例如,发送数据后若未开启中断,CPU 无法知道数据是否发送完成,可能导致下一批数据覆盖未发送的数据。

四、总结:DMA 的核心价值与应用场景

通过以上内容,我们可以总结出 DMA 的核心价值:解放 CPU,提升数据传输效率。它不是 “替代 CPU”,而是 “分担 CPU 的繁琐工作”,让处理器能更高效地处理核心任务。

在实际项目中,以下场景尤其适合使用 DMA:

  • 串口大量数据收发:如日志打印、传感器批量数据上传;

  • ADC 多通道连续采样:如电压、电流、温度等多参数实时采集;

  • SPI/I2C 高速数据传输:如与显示屏、存储芯片(SD 卡、Flash)的高速通信;

  • 存储器间数据搬运:如将 Flash 中的固件数据搬运到 SRAM 中运行(STM32F103 的 DMA2 支持)。

掌握 DMA 技术,是从 “入门级嵌入式开发” 迈向 “高性能嵌入式开发” 的关键一步。后续大家可以结合 STM32CubeMX 工具(可视化配置 DMA),通过实际代码调试(如 “DMA+UART 收发数据”),进一步加深对 DMA 的理解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值