1. 项目概述与μDMA核心价值
在嵌入式系统开发中,尤其是面对实时数据采集、高速通信或图形刷新这类任务时,CPU如果被频繁的数据搬运工作所拖累,整个系统的响应速度和效率就会大打折扣。想象一下,你正在用微控制器处理一个音频流,CPU每收到一个字节的音频数据,就要停下手中的计算任务,去执行一次内存读写操作,这无疑是巨大的资源浪费。这时,直接内存访问(DMA)技术就成为了解放CPU、提升系统性能的关键角色。而德州仪器(TI)的Tiva™系列微控制器,比如我们这次深入探讨的TM4C123GE6PM,其内置的微直接内存访问(μDMA)控制器,更是将这种能力精细化、可编程化,为开发者提供了强大的数据搬运引擎。
简单来说,μDMA允许外设(如ADC、UART、SPI)或软件直接与内存进行数据交换,整个过程无需CPU介入。CPU只需要在传输开始前告诉μDMA:“从A地址搬N个数据到B地址”,然后就可以去处理其他更重要的任务了。传输完成后,μDMA会通过中断通知CPU:“活儿干完了,数据在B地址,请查收”。这种“甩手掌柜”模式,对于需要维持高数据吞吐量的应用至关重要。
本文将以Tiva TM4C123GE6PM的μDMA模块为蓝本,为你彻底拆解其工作原理。我不会仅仅罗列寄存器手册,而是结合我多年在电机控制、传感器数据流处理中实际使用μDMA的经验,从 通道配置的底层逻辑 、 中断处理的实战流程 ,到 关键寄存器的每一个比特位如何影响传输行为 ,进行深度剖析。无论你是正在调试一个ADC多通道扫描采集,还是想优化SPI Flash的读写速度,理解并掌握μDMA,都能让你的嵌入式系统设计如虎添翼。接下来,我们就从最核心的通道控制结构开始,一步步揭开它的神秘面纱。
2. μDMA通道控制结构深度解析
如果把μDMA控制器比作一个建筑工地,那么通道控制结构(Channel Control Structure)就是发给每个施工队(DMA通道)的“施工图纸”。这张图纸详细规定了“从哪里搬砖(源地址)”、“搬到哪里去(目的地址)”、“一次搬几块(数据大小)”、“怎么搬(地址递增模式)”以及“总共要搬多少(传输数量)”等所有关键信息。在Tiva的μDMA架构中,每个通道都拥有两张这样的图纸:一张主控结构(Primary),一张备用控制结构(Alternate),这正是实现Ping-Pong、Scatter-Gather等高级传输模式的基础。
2.1 核心三寄存器:定义传输的骨架
通道控制结构主要由三个寄存器在内存中构成,它们位于由 DMACTLBASE 寄存器指定的通道控制表(Channel Control Table)中。每个通道的主控结构和备用结构在表中都有固定的偏移位置。
1. DMA通道源地址结束指针(DMASRCENDP) 这个寄存器存放的是传输 源地址区域的最后一个字节的地址 。这里有个非常关键且容易误解的点:它叫“结束指针”,但实际指向的是传输范围的末尾(包含该地址)。例如,如果你要从数组 srcBuffer[100] (起始地址0x2000.0000)传输100个字节,且地址递增,那么 DMASRCENDP 应设置为 0x2000.0000 + 100 - 1 = 0x2000.0063 。
注意 :当源地址不递增时(
SRCINC字段为0x3),此寄存器直接指向源外设的数据寄存器地址本身。此时,μDMA会反复从这个固定地址读取数据。
2. DMA通道目的地址结束指针(DMADSTENDP) 与源地址指针同理,它定义了传输 目的地址区域的最后一个字节的地址 。设置规则与 DMASRCENDP 完全一致。同样,当目的地址不递增时( DSTINC 为 0x3 ),它指向一个固定的外设数据寄存器。
3. DMA通道控制字(DMACHCTL) 这是整个控制结构的“大脑”,一个32位的寄存器包含了决定传输行为的所有控制位。我们需要逐字段理解:
-
DSTINC (位 31:30) 与 SRCINC (位 27:26) :目的和源地址增量。它决定了每次传输后,地址指针如何移动。可选值为:
0x0(字节递增)、0x1(半字递增)、0x2(字递增)、0x3(不递增)。这里有一个 硬性规则 :增量值必须大于或等于对应的数据大小(DSTSIZE/SRCSIZE)。例如,数据大小是字(4字节),那么地址增量至少要是字(0x2),不能是字节(0x0)。通常,从内存到内存的传输,两者都设为递增;从外设到内存,源(外设)不递增,目的(内存)递增;反之亦然。 -
DSTSIZE (位 29:28) 与 SRCSIZE (位 25:24) :目的和源数据项大小。定义每次传输操作的数据宽度:
0x0(8位)、0x1(16位)、0x2(32位)。另一个 关键规则 :DSTSIZE和SRCSIZE必须设置为相同的值。你不能用一次32位读取搭配一次16位写入。 -
ARBSIZE (位 17:14) :仲裁大小。这个字段决定了μDMA控制器在“抢占”总线进行传输时,一次性连续传输多少个数据项,然后再释放总线给其他主设备(如CPU)。它是以2的幂次方定义的,从1(
0x0)到1024(0xA,此时由于单次传输已达最大项数,故不仲裁)。设置更大的仲裁大小可以提高总线利用率和传输效率,尤其是在传输大块连续数据时。但如果你需要更低的传输延迟,让CPU能更频繁地介入,则可以设小一些。 -
XFERSIZE (位 13:4) :传输大小(减1)。这是你需要传输的总数据项数量减1。这是一个10位字段,最大值为1023,代表一次传输最多1024个数据项。 务必记住 :这里填写的是“项数-1”。如果你想传输200个32位字,这里应填199(0xC7)。同时,这个值指的是“数据项”的个数,而非字节数。如果数据大小是半字(16位),传输100项,实际搬运的数据量是200字节。
-
XFERMODE (位 2:0) :传输模式。这是μDMA的灵魂,决定了传输如何被触发和进行。我们将在下一章详细展开。
2.2 传输模式(XFERMODE)详解与选型策略
XFERMODE 字段定义了七种工作模式,理解它们的区别是灵活运用μDMA的关键。
-
停止(Stop, 0x0) :通道未配置或配置无效,传输停止。在初始化或重新配置前,应确保模式为此值。
-
基本模式(Basic, 0x1) :最直观的模式。 每次外设请求或软件请求触发一次,μDMA就执行
ARBSIZE所指定数量的传输 。例如,ARBSIZE=4(即8次传输),那么每来一个请求,就搬8个数据项,直到总共完成XFERSIZE+1个项。适用于需要外设频繁请求、数据流不连续的场景。 -
自动请求模式(Auto-Request, 0x2) : 只需一次初始请求(软件或外设触发),μDMA就会自动完成整个
XFERSIZE+1个数据项的传输 ,期间不再需要额外请求。这非常适合内存到内存的块搬运,或者外设能够一次性提供大量数据的情况。 -
乒乓模式(Ping-Pong, 0x3) : 高级双缓冲模式 。该模式会同时使用主控和备用两个控制结构。假设主控结构指向缓冲区A,备用结构指向缓冲区B。传输启动后,控制器先用主结构(A)传输。当A传输完成,立即产生中断,并自动切换到备用结构(B)继续传输,同时将主结构的
XFERMODE改为Stop。在中断服务程序(ISR)中,你处理完缓冲区A的数据


445

被折叠的 条评论
为什么被折叠?



