ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

【stm32】DMA

【stm32】DMA 铅笔小新z个人主页博客专栏stm32学习滴水不绝可穿石步履不休能至渊。DMA 详解 —— 让数据自动搬家的搬运工面向初学者的通俗解读配合逐行注释的代码以及每个知识点后的一句话总结。本文基于 STM32F103Cortex-M3 DMA1 实战讲解帮你彻底搞懂 DMA 的原理、通道、寄存器与中断。目录DMA 是什么为什么需要 DMADMA 的核心目标与 CPU 的职责四方关系DMA 到底在哪宏观理解 DMA 工作过程总线共享CPU 和 DMA 会打架吗DMA 通道与仲裁查文档DMA 的寄存器与地址空间通道核心配置寄存器DMA 中断TC、HT、TE区分中断类型ISR 与 IFCR配置案例1. DMA 是什么1.1 全称与定义DMADirect Memory Access直接存储器访问用来提供外设和存储器之间、或者存储器和存储器之间的高速数据传输。无需 CPU 干预数据就能通过 DMA 快速移动从而节省 CPU 资源去做其他操作。通俗地说DMA 就是单片机内部的一个外设控制器它拥有独立的地址总线和控制逻辑。在 CPU 授权之后它可以接管总线控制权在不占用 CPU 资源的情况下自动把数据从一个地址源搬到另一个地址目的。1.2 一个搬运货物的比喻为了快速理解 DMA先看一个搬运货物的例子角色对应CPU老板DMA专业搬运工数据需要搬运的货物外设串口、I2C、SPI、ADC 等货物的来源或目的地之一存储器内存货物的来源或目的地之一老板CPU不用亲自搬货他把从哪搬、搬到哪、搬多少交代给搬运工DMA搬运工自己完成老板去做更重要的决策工作。 本知识点一句话总结DMA直接存储器访问是单片机内部的一个独立硬件控制器拥有自己的地址总线和控制逻辑。它的作用是在 CPU 授权后接管总线不占用 CPU 就自动把数据从源地址搬到目的地址实现外设↔存储器、存储器↔存储器之间的高速传输。可以把 CPU 比作老板DMA 比作专业搬运工——老板只下指令搬运工干体力活从而把宝贵的 CPU 资源留给逻辑运算等更重要的工作。2. 为什么需要 DMA2.1 没有 DMA 时CPU 亲自搬货如果没有 DMA把数据从外设搬到内存、从内存搬到外设都是 CPU 自己做的外设 →(CPU 读取)→ CPU →(CPU 写入)→ 内存CPU 不仅要执行用户代码、响应中断还要亲自干数据搬迁这种体力活。结果是CPU 被拖慢同时数据搬迁的响应速度也被拖慢。2.2 引入 DMA 后CPU 只发指令引入 DMA 模块后相当于请了搬运工DMA。CPU 只需要告诉 DMA 三件事搬多少数据数量从哪搬源地址搬到哪目的地址。CPU 不需要亲自参与搬运过程只需发布搬运命令最后处理搬运完的货物即可。2.3 为什么这么设计CPU 资源非常宝贵应该专注于逻辑运算、业务处理这类重要工作而大批量数据的重复搬运这类简单、重复的工作应该交给 DMA 完成。没有 DMACPU 既当老板又当搬运工 → 累死且低效 有 DMA CPU 当老板DMA 当搬运工 → 各司其职高效 本知识点一句话总结引入 DMA 的根本原因是解放 CPU没有 DMA 时外设与内存之间的数据拷贝都要 CPU 亲自执行既拖慢 CPU 又拖慢数据响应。引入 DMA 后CPU 只需下发源地址、目的地址、数据量三个参数即可搬运过程由 DMA 硬件完成。这样 CPU 专注于逻辑运算和业务处理简单重复的搬运工作交给 DMA实现各司其职整体效率大幅提升。3. DMA 的核心目标与 CPU 的职责3.1 核心目标数据传输搬运过程需要一个主体来控制。在 CPU 不参与的情况下就需要另一个主体来控制传输过程这就是DMA 控制器。不同架构 CPU 的 DMA 控制器实现细节不同但目标一致代替 CPU 控制数据传输过程。3.2 CPU 到底做什么一个容易误解的点说DMA 不占用 CPU不等于CPU 什么都不用干。CPU 需要做两件事启动 DMA 传输过程初始化配置 使能在 DMA 传输结束时执行下一个业务逻辑如启动新的传输、或处理已收到的数据例如格式化打印。记住CPU 不参与的是搬运过程而不是启动和收尾。启动和收尾这两头还得 CPU 亲自来。 本知识点一句话总结DMA 的核心目标是代替 CPU 控制数据传输过程但 CPU 并非完全不参与它要负责两件事——① 在传输前配置并启动 DMA② 在传输结束后收到中断执行后续业务逻辑如启动下一次传输、处理数据。所谓不占用 CPU仅指搬运过程本身由 DMA 硬件完成CPU 不介入但启动和收尾仍需 CPU 参与。4. 四方关系DMA 到底在哪明确 DMA 的定位——它和 Cortex-M3(CPU)、MCU、开发板灵犀板之间的四方关系DMA 在 MCU 内部是 MCU 内部的一个独立硬件控制单元属于一个独立的片上外设。但从更本质的角度看DMA 是一个总线主设备Bus Master这一点和普通片上外设如串口是被动的从设备有区分度。关键词DMA 是总线主设备——它能主动发起总线操作读/写而普通外设只是被动响应。这是 DMA 能自主搬数据的根本原因。在 STM32F103 系列芯片内部一般包含两个 DMA 控制器模块DMA1有 7 个通道DMA2有 5 个通道只有大容量和互联型产品才有。后续研究时把注意力放在DMA1上即可DMA2 原理完全一样。 本知识点一句话总结DMA 位于 MCU 内部是一个独立的硬件控制单元片上外设但本质上是总线主设备Bus Master——它能主动发起总线读写操作这正是它能自主搬运数据的根本原因普通外设只是被动的从设备。STM32F103 有两个 DMA 控制器DMA17 通道和 DMA25 通道仅大容量/互联型有两者原理相同学习时以 DMA1 为例即可。5. 宏观理解 DMA 工作过程DMA 传输主要发生在外设和内存之间存储器到存储器虽然也支持但应用很少。一个 DMA 数据传输过程有4 个核心参与主体CPUCortex-M3 内核负责启动 DMA 数据传输。外设负责向 DMA 控制器发起 DMA 请求。DMA 控制器负责响应 DMA 请求并控制数据传输过程。内存SRAM作为数据的源或目的缓冲区。下面以串口USART1为例分 4 步建立宏观认知5.1 第一步CPU 启动 DMACPU 让 DMA 帮它搬迁数据这个工作需要用户提前设置好源地址、目的地址、数量等并最终使能通道。5.2 第二步外设发起 DMA 请求当外设收到数据时如串口收到一个字节USART1 会向 DMA 发起DMA 数据搬迁请求。当外设要发数据时如串口要往外发一个字节USART1 也会向 DMA 发起请求。5.3 关于 DMA 应答硬件握手外设在发生特定事件后向 DMA 控制器发送一个请求信号当 DMA 控制器开始访问该外设时会先回一个应答信号。这个过程叫 DMA 的硬件握手。从电气角度握手就是电脉冲或高低电平。这个握手过程不需要工程师配置是 DMA 和对应片上外设自主完成的。5.4 第三步DMA 响应请求并控制传输外设 → 内存DMA 把外设数据寄存器里的数据搬到内存缓冲区。内存 → 外设DMA 把内存缓冲区的数据搬到外设数据寄存器。5.5 第四步通知 CPU传输完成数据全部搬完后DMA 通过中断通知 CPUCPU 收到后介入处理后续数据。完整流程一句话CPU 启动 → 外设请求 → DMA 握手并搬运 → DMA 中断通知 CPU 收尾。 本知识点一句话总结一个完整的 DMA 传输包含四个主体和四步流程四个主体是 CPU、外设、DMA 控制器、内存。四步流程是① CPU 配置并启动 DMA② 外设因收到数据/要发数据向 DMA 发请求③ DMA 与外设硬件握手后响应请求把数据从外设寄存器搬到内存或反向④ 搬完产生中断通知 CPU 收尾。其中握手请求/应答是 DMA 与外设硬件自动完成的无需软件配置。6. 总线共享CPU 和 DMA 会打架吗6.1 提出问题CPU 本来也要访问外设和内存读 Flash 代码、访问 USART、写内存等DMA 也要访问。两者都要通过AHB 总线和总线矩阵进行那岂不是会冲突6.2 官方说明意法官方文档参考手册给出的结论是DMA 控制器和 Cortex-M3 核心共享系统数据总线。当 CPU 和 DMA 同时访问相同目标RAM 或外设时DMA 请求会暂停 CPU 访问系统总线达若干个周期以保证 CPU 至少可以得到一半的系统总线存储器或外设带宽。总线仲裁器执行循环调度。6.3 结论官方没有披露 DMA 和总线的详细内部细节但对应用层来说足够了。最终结论逻辑上 CPU 和 DMA 互不影响。总线仲裁器通过循环调度保证两边都能获得至少一半带宽不会死锁或互相饿死。 本知识点一句话总结CPU 和 DMA 都通过 AHB 总线和总线矩阵访问外设/内存存在潜在的资源竞争。解决方式是总线仲裁器的循环调度当 CPU 和 DMA 同时访问相同目标时DMA 请求会暂停 CPU 访问总线若干周期从而保证 CPU 至少能获得一半总线带宽。因此逻辑上 CPU 和 DMA 互不影响能安全地共享系统数据总线。7. DMA 通道与仲裁7.1 通道初识为什么要多个通道MCU 里的片上外设非常多USART、SPI、I2C、ADC、TIM……。如果 DMA 控制器只有一个通道一次只能处理一个外设的请求效率太低。为了支持多个外设的数据搬迁并发进行DMA 提供了多个通道每个通道独立工作每一个通道其实就是一个子 DMA主要负责进行数据搬迁。7.2 一个疑问总线不是共享的吗怎么能并发多通道用的是同一套总线所以严格说同一时刻只能有一个通道真正占有总线。但要注意外设数据需要搬迁 ≠ “一直在搬迁”。多个外设往往在不同时刻才需要搬数据空闲时总线就空着。DMA 的并发本质是分时复用总线——多个通道交替使用总线空闲时间完成各自搬迁。多通道的终极目标是不让总线闲着充分复用总线资源。打个比方一条单车道马路不同的车通道轮流过虽然同一时刻只能过一辆但整体看起来是并发运行的。7.3 仲裁器与通道优先级既然同一时刻只能让一个通道拥有总线那到底让谁先这就需要优先级和仲裁器。关键认知两个细节优先级高 ≠ 一直霸占总线因为外设不一定满足搬迁条件还没收到数据、还没发完等高优先级通道暂时不工作时低优先级通道照样能干活。仲裁器用来判断优先级、决定谁拥有总线资源的模块。比喻你是航空公司 VIP 乘客优先级高但你不是每天坐飞机、也不是时刻在排队。当你排队时需要工作人员仲裁器确认你的 VIP 身份让你先走你不排队时普通乘客照常通行。仲裁器根据通道请求的优先级来启动外设/存储器的访问优先级管理分2 个阶段阶段一软件优先级4 个等级在DMA_CCRx寄存器中设置DMA_PRIORITY_LOW// 低DMA_PRIORITY_MEDIUM// 中DMA_PRIORITY_HIGH// 高DMA_PRIORITY_VERY_HIGH// 最高阶段二硬件优先级如果两个请求的软件优先级相同则编号较小的通道优先级更高。例如通道 2 优先于通道 4。这个硬件优先级由芯片内部走线决定通道编号固定用户无需也无法设置。7.4 细节 1外设请求信号硬映射哪种片上外设用哪个 DMA 通道在芯片设计走线时就已经固定了。这种外设↔通道的固定对应关系叫硬映射Hard Mapping。以 USART1 为例DMA1USART1_TX → 通道 4USART1_RX → 通道 5收发映射到不同通道是为了让收发几乎同时用 DMA 搬迁从而在 DMA 场景下支持 USART1 的全双工。同时任意一个通道只能被一种外设使用排他性。虽然一个通道理论上能接到多个外设的请求但用户必须提前配置好让哪个外设用这个通道不能同时让两个以上外设使用同一个通道。外设要使用 DMA对应外设控制寄存器里必然有开启 DMA的配置位。以 USART1 为例它的CR3 寄存器里的DMAT发送 DMA 使能和DMAR接收 DMA 使能就是开关。任何要用 DMA 的外设都必然存在类似配置位。7.5 细节 2优先级聚合与仲裁过程把打开一个通道想象成选中一个开关。多个通道的请求信号汇聚到仲裁器仲裁器根据软件优先级 → 硬件优先级的顺序选出当前应该占有总线的通道执行该通道的数据搬迁。7.6 核心结论通道的内部构成逻辑上一个通道内部一定包含一套核心配置寄存器n 个通道就包含 n 份核心寄存器。每个通道都要独立配置优先级、传输方向、数据量、地址自增等所以这些配置寄存器每个通道都有一份。 本知识点一句话总结DMA 通过多通道实现多外设的并发搬迁每个通道是一个独立的子 DMA。多通道本质是分时复用总线同一时刻只有一个通道真正占有总线终极目标是不让总线闲着。当多通道同时请求时由仲裁器决定谁先优先级分两级先看软件优先级CCR 寄存器的 PL 位4 级相同再看硬件优先级通道编号小的优先。外设与通道的对应关系是芯片设计时固定好的硬映射如 USART1_TX→通道4、RX→通道5且一个通道具有排他性同一时刻只能服务一个外设。8. 查文档DMA 的寄存器与地址空间8.1 寄存器被映射到地址空间STM32 的片上外设寄存器是统一编址、直接映射到 CPU 地址空间的所以可以直接用 C 语言指针访问 DMA 模块。8.2 DMA1 的地址范围DMA1 地址范围0x4002 0000~0x4002 03FF大小计算0x400203FF - 0x40020000 1 0x400 1024 字节 1KB注意CPU 虽为 DMA1 分配了 1KB但实际只用到开头很少一部分后续地址是保留的访问可能产生不可预知行为。8.3 DMA1 的寄存器数量DMA1 共有2 4 × 7 30个寄存器“2”DMA1 整体关于通道中断管理的两个寄存器即 ISR 和 IFCR稍后讲。“4”每个通道都有 4 个管理/配置类寄存器。“7”DMA1 有 7 个通道。访问方式0x40020000 寄存器偏移。DMA2 结构几乎完全一样只是起始地址0x40020400只有 5 个通道所以是2 4 × 5 22个寄存器。核心结论用 C 指针通过基地址 偏移量就能直接访问 DMA 内部寄存器从而配置通道、控制 DMA 行为。 本知识点一句话总结STM32 的 DMA 寄存器是统一编址、可直接用 C 指针访问的。DMA1 基地址为0x40020000地址空间 1KB共 30 个寄存器 2 个中断管理寄存器 每通道 4 个配置寄存器 × 7 个通道。DMA2 基地址0x400204005 个通道共 22 个寄存器。访问任意寄存器都是基地址 偏移量配置 DMA 的本质就是 CPU 写这些寄存器。9. 通道核心配置寄存器9.1 概览每个通道 4 个寄存器每个 DMA 通道有 4 个独立寄存器寄存器缩写展开命名英文全称核心功能DMA_CCRxDMA1_CCR1 ~ CCR7DMA Channel x Configuration Register配置与优先级软件优先级、传输方向、模式、数据宽度、自增等DMA_CNDTRxDMA1_CNDTR1 ~ CNDTR7DMA Channel x Number of Data to Transfer Register传输数量设定并记录剩余待搬运数据总量DMA_CPARxDMA1_CPAR1 ~ CPAR7DMA Channel x Peripheral Address Register外设地址存储外设端起始物理地址DMA_CMARxDMA1_CMAR1 ~ CMAR7DMA Channel x Memory Address Register存储器地址存储内存端起始物理地址每个通道都对应一套这 4 个寄存器n 个通道就有 n 份。配置 DMA 的本质就是 CPU 设置这些寄存器。9.2 CCR 寄存器详解DMA_CCRx是特定通道的核心寄存器。下面逐个解释其中的关键位。9.2.1 通道使能 EN 与优先级 PLEN通道使能位决定是否开启对应通道。因为外设和通道是固定关联的使能通道就允许对应外设使用该通道搬运数据。⚠️细节使能了 ≠ 仲裁成功。使能只表示这个通道可以工作、可以参与申请仲裁但当前是否真正搬运取决于仲裁结果。PL通道优先级设置该通道的软件优先级低/中/高/最高。当多个通道同时申请时仲裁器比较各通道 PL 值决定谁先。9.2.2 传输方向 DIR外设和存储器的 DMA 传输方向有两种DIR0外设 → 内存从外设读。例如从串口、I2C、SPI 接收数据。DIR1内存 → 外设从内存读即写外设。例如向串口、I2C、SPI 发送数据。记忆技巧永远站在内存角度。1像一支笔用来写字DIR1 表示从内存写数据到外设。0像一张嘴读书用嘴读DIR0 表示把数据从外设读到内存。9.2.3 数据宽度 PSIZE 和 MSIZE数据宽度指定每次传输的数据大小可配置 8/16/32 位。外设和内存是独立设备可分别设置宽度。例如外设 16 位、内存 16 位则每次传输 2 字节。⚠️注意外设和内存宽度可以不同但需匹配以避免数据错误源窄目的宽 → 数据扩展类似int b a;里a是 char 会扩展源宽目的窄 → 数据截断丢失类似char a b;里b是 int 会截断。多数情况把源端和目的端宽度配置相同即可避免截断错误。9.2.4 地址自增 PINC 和 MINCDMA 需要设置参与传输的双方是否会地址自增。模式PINC/MINC步长逻辑典型应用说明单增模式常用PINC0, MINC1外设固定内存 MSIZE串口收发外设守着固定数据寄存器如 USART_DR内存按顺序存储双增模式PINC1, MINC1外设 PSIZE内存 MSIZE数据拷贝源地址和目的地址同步移动整块迁移双不增模式不常用PINC0, MINC0外设固定内存固定引脚镜像两个地址原地踏步硬件寄存器↔内存变量实时映射地址自增时按对应设备自己设置的数据宽度自增宽度设置数据类型物理步长008 位uint8_t1 字节0116 位uint16_t2 字节1032 位uint32_t4 字节9.2.5 循环模式 CIRCDMA 有时只需做一次有时需要重复执行单次模式Normal循环模式Circular核心逻辑搬完预设数量即停止进入空闲搬完立即重头开始无限循环CNDTR 归零后保持为 0自动重装为初始总数地址指针停留在末尾地址自动跳回起始地址EN 使能位硬件自动清零通道关闭始终保持 1持续开启再次触发需软件重新配置并开启 EN只需启动一次硬件自动触发典型应用串口发字符串、内存拷贝ADC 连续采样、音频播放、引脚镜像数据覆盖风险无搬完即停高CPU 处理慢时第二圈覆盖第一圈9.3 传输数量寄存器 CNDTR数据传输数量 NDT 表示传输数据项的个数最大可配置65535。几点含义NDT不是字节数实际总字节数 NDT × 数据宽度。示例NDT32宽度 32bit4 字节总字节 32 × 4 128 字节。数据宽度是基本大小传输数量是多少个基本大小。从外设到内存表示从外设读取的数据项个数从内存到外设表示向外设发送的数据项个数。NDT 决定了单次 DMA 传输何时结束传输完成。9.4 外设地址 CPAR 与内存地址 CMAR严格说搬迁数据不是从外设到内存而是从外设数据寄存器DR到内存地址指向的空间或从内存地址指向的空间到外设数据寄存器。所以通道配置里必然要有描述源/目的的寄存器DMA_CPARx保存外设数据寄存器地址DMA_CMARx保存内存地址再由DMA_CCRx的 DIR 位表示传输方向。对齐了解即可半字对齐地址能被 2 整除bit0 0字对齐地址能被 4 整除bit0、bit1 0。现代 CPU 按块读内存如一次 4/8 字节若数据跨越两个读取周期则需读两次拼接耗时翻倍。设置 2/4 字节读写单位时DMA 会自动处理对齐。9.5 通道配置小结对单个 DMA 通道的配置参数逻辑上分3 类外设端外设地址CPAR、外设数据宽度PSIZE、外设自增PINC存储器端内存地址CMAR、内存数据宽度MSIZE、内存自增MINC传输过程参数传输方向DIR、传输数量CNDTR/NDT、优先级PL、循环模式CIRC、中断使能TCIE/HTIE/TEIE等。此时还有个未解决的问题搬完了CPU 怎么知道——答案是中断下一节讲。 本知识点一句话总结每个 DMA 通道由 4 个寄存器构成CCR配置方向/宽度/自增/循环/优先级/中断使能、CNDTR传输数据项个数 NDT最大 65535总字节 NDT×宽度、CPAR外设数据寄存器地址、CMAR内存地址。核心配置可归纳为三类外设端、存储器端、传输过程参数。关键点DIR 决定方向0 外设→内存1 内存→外设宽度建议源/目相同避免截断PINC/MINC 控制地址自增CIRC 决定单次还是循环NDT 决定何时结束。10. DMA 中断TC、HT、TE10.1 直接回答问题Q数据搬迁完毕后CPU 怎么知道DMA 怎么告诉 CPUADMA核心是通道本质也是一个 MCU 片上外设和串口、SPI、I2C 一样也能通过中断通知 CPU。当 DMA 搬迁完数据会通过中断通知 CPUCPU 在中断处理函数里做后续处理。10.2 三种中断在 CCR 里配置DMA_CCRx 里与中断有关的配置位每个通道都有TCIE传输完成中断使能所有数据传输完成时触发最常用。作用就是通知 CPU我搬完了你可以处理了。HTIE半传输中断使能数据传输量达到预设总额一半时触发。TEIE传输错误中断使能传输中发生总线错误或配置冲突时触发用于异常捕获和处理避免程序卡死。10.3 为什么要有半传输中断原因实现数据传输与数据处理的并行消除等待时间。若只有 TC 中断CPU 必须等整块数据搬完才能开始处理。有了 HT 中断可以先搬一半 → 触发 HT 中断 → CPU 处理前半段同时 DMA 继续搬后半段逻辑上数据搬运和数据处理并行进行。双缓冲Ping-Pong Buffering是 HT 的经典应用。假设 1024 字节缓冲区前半 512 字节填满 → 触发 HT 中断 → CPU 处理前半段DMA 继续搬后半段后半 512 字节填满 → 触发 TC 中断 → 循环往复像接力赛。典型场景音频播放。如果读完再播放、再读再放会卡顿用 HT 中断让播放音频和拷贝音频同时进行就能解决卡顿。 本知识点一句话总结DMA 通过中断通知 CPU 传输状态在 CCR 寄存器里有三个中断使能位TCIE传输完成最常用通知 CPU 搬完可处理、HTIE半传输搬满一半时触发、TEIE传输错误捕获异常防卡死。半传输中断的核心价值是实现搬运与处理的并行先搬一半触发 HTCPU 处理前半段时 DMA 继续搬后半段即双缓冲Ping-Pong机制典型用于音频播放等对实时性要求高的场景消除等全部搬完再处理的等待时间。11. 区分中断类型ISR 与 IFCR11.1 问题一个通道就一根中断线怎么区分是哪类中断一个通道只有一根中断线连到 NVIC最多传递有中断了这个信号无法传递是传输完成、传输一半、还是出错这么多信息。11.2 解决方案DMA_ISR 与 DMA_IFCR为了区分 DMA1 中 7 个通道、每个通道的不同中断类型DMA 内部提供了两个中断管理寄存器就是前面说的那2个寄存器。每个通道的中断情况由4 个标志位表示GIFx是否产生了上述任意事件全局中断标志TCIFx是否发生了传输完成HTIFx是否发生了半传输完成TEIFx是否发生了传输错误。x 表示通道号1~7关键机制一旦特定通道产生中断DMA 硬件除了向 CPU 发中断还会自动设置DMA_ISR寄存器中对应的位。例如通道 5 发生 TCTCIF51, HTIF50, TEIF50, GIF51。CPU 收到中断后回头读DMA_ISR寄存器就能明确是哪个通道、发生了什么中断再做相应处理。至此 DMA 逻辑闭环。标志位清除这些中断标志位是只读的不能直接写 0 清除。要清除必须写DMA_IFCR寄存器的对应位写 1 清零。比喻你把村里的小朋友打了小朋友不直接找你打不过而是去找你妈让你妈收拾你。这里的ISR 只读、IFCR 负责清除就是类似的间接操作逻辑。这些寄存器的设置和清除后续有 HAL 库自动完成我们读源码时再回来看文档即可。 本知识点一句话总结因为一个通道只有一根中断线无法区分中断类型DMA 用DMA_ISR中断状态寄存器和DMA_IFCR中断标志清除寄存器来解决。每个通道有 4 个标志GIF任意事件、TCIF传输完成、HTIF半传输、TEIF传输错误。硬件触发中断时会自动置位 ISR 对应位CPU 在中断里读 ISR 即可判断是哪个通道、哪类中断。ISR 只读清除标志要通过写 IFCR 的对应位完成。这两个寄存器就是 DMA1 那2 个中断管理寄存器。12. 配置案例12.1 案例 1USART1 用 DMA 接收数据的配置一个使用 USART1 的 DMA 模式进行接收的配置示例寄存器地址0x40013804就是 USART1 的数据寄存器DR地址。数据宽度 8 位因为串口有效数据是 8 位收发端宽度都配 8 位。外设端不自增因为只有一个数据寄存器外设地址固定。存储器端自增因为要连续保存串口数据内存地址要自增。12.2 案例 2按图说话需求传输方向外设 → 存储器DIR0。外设只有一个 8 位数据寄存器地址0x40013804记作REG(0x40013804)。内存缓冲区 256 字节起始地址0x200000e0记作BUF(0x200000e0)。数据宽度 8 位外设地址不自增一次 DMA 传输读 256 字节内存地址自增。一次 DMA 传输过程CPU 启动 DMA 数据传输。外设寄存器数据非空外设向 DMA 发出请求。DMA 应答启动传输REG(0x40013804) → BUF(0x200000e0)。传输完成寄存器数据非空事件自动清除。外设又来数据非空再次请求。DMA 应答传输REG(0x40013804) → BUF(0x200000e01)。传输完成事件自动清除。……以此类推外设再来数据请求。DMA 应答传输REG(0x40013804) → BUF(0x200000e0255)。传输完成事件自动清除。256 字节搬完产生传输完成TC中断。这个案例完整串起了前面所有知识点外设地址固定PINC0、内存地址自增MINC1、每搬一个字节外设请求一次、最后产生 TC 中断。 本知识点一句话总结配置一个串口 DMA 接收核心是外设地址填数据寄存器地址如 USART1 的0x40013804且不自增内存地址填缓冲区首地址如0x200000e0且自增方向 DIR0外设→内存宽度按外设数据位宽串口 8 位。工作过程是外设每来一个数据就请求一次DMA 搬一个字节并让内存地址 1搬满预设数量如 256 字节后产生 TC 中断。整个过程 CPU 不参与搬运只在最后的中断里介入处理。全文总结速记卡DMA 是什么直接存储器访问独立硬件控制器 总线主设备代替 CPU 自动搬运数据。为什么用解放 CPU把重复的搬运工作交给 DMACPU 专注业务逻辑。四方关系CPU启动收尾、外设发请求、DMA控制搬运、内存源/目的。工作流程CPU 启动 → 外设请求 → DMA 握手搬运 → 中断通知 CPU。总线共享CPU 和 DMA 共享 AHB 总线靠总线仲裁器循环调度各占一半带宽逻辑上互不影响。通道与仲裁多通道分时复用总线仲裁器按软件优先级4 级→硬件优先级编号小优先仲裁外设↔通道是硬映射USART1_TX→通道4、RX→通道5且排他。寄存器DMA1 基地址0x4002000030 个寄存器每通道 4 个CCR/CNDTR/CPAR/CMAR。CCR 关键位EN使能、PL优先级、DIR方向、PSIZE/MSIZE宽度、PINC/MINC自增、CIRC循环、TCIE/HTIE/TEIE中断。中断TC完成、HT半传输双缓冲并行、TE错误用 ISR 读状态、IFCR 清标志。使用流程配置外设 DMA 使能位 → 配置通道 4 寄存器 → 使能通道 → 中断收尾。
返回列表