1. DMA技术核心价值与PXD10实现概览在嵌入式系统开发中CPU资源是宝贵的。想象一下你正在处理一个实时音频流每秒有数万个采样点需要从ADC模数转换器搬到内存缓冲区同时还要响应网络数据包、刷新显示屏。如果所有这些字节的搬运工作都由CPU通过memcpy或循环读写外设寄存器来完成CPU将深陷于简单重复的“搬运工”角色无暇处理真正的算法和逻辑系统实时性会大打折扣。这就是直接内存访问DMA技术存在的根本意义它像一个专职的、高效的“数据搬运工”接管了外设与内存、内存与内存之间的大块数据搬运工作让CPU得以解放专注于核心计算任务。在飞思卡尔现恩智浦的PXD10这类高性能微控制器上DMA的实现尤为精妙和强大。它不仅仅是一个简单的“搬运工”更是一个高度可编程、智能化的数据传输引擎。其核心由两大关键组件构成DMA多路复用器DMA Mux和增强型直接内存访问控制器eDMA。DMA Mux扮演着“交通调度员”的角色它管理着众多外设如SPI、UART、ADC、GPIO等发出的数据传输请求并将这些请求有序地路由到有限的eDMA通道上。而eDMA则是真正的“搬运引擎”它拥有复杂的传输控制描述符TCD和双循环主/次循环机制能够执行从简单内存拷贝到复杂散点/收集Scatter/Gather等各种高级数据传输模式。理解并熟练配置这两者是解锁PXD10这类微控制器全部数据处理潜力的关键。它能让你实现诸如“每100微秒自动读取一次传感器数据并存入环形缓冲区”、“将内存中的波形表不间断地输出到GPIO以生成精密信号”、“在后台完成大块图像数据的搬移和格式转换”等高阶功能而CPU只需在传输完成时得到通知甚至完全无需干预。接下来我们将深入这两个核心模块的机理与配置实战。2. DMA多路复用器DMA Mux智能请求路由与触发机制DMA Mux是连接外设请求与eDMA通道的桥梁。在PXD10中并非每个外设都独占一个DMA通道那样会消耗过多的硬件资源。DMA Mux允许多个外设源DMA Source复用到数量更少的DMA通道上。它的核心功能是路由与触发。2.1 通道路由与请求门控每个DMA Mux通道都有一个配置寄存器如CHCONFIG2。你可以将某个外设的请求源编号例如SPI0发送请求可能是源#5写入该寄存器从而将该外设绑定到特定的DMA通道。当外设需要传输数据时比如SPI发送缓冲区空它会拉高自己的DMA请求线。DMA Mux检测到该请求并且如果对应通道已启用就会将请求转发给eDMA控制器。这里有一个关键的门控逻辑外设请求是传输的必要条件而非充分条件。手册中图13-5的示意图及其说明揭示了一个重要细节即使DMA Mux通道配置了触发Trigger如果触发事件到来时绑定的外设并没有主动发出DMA请求那么这个触发事件会被忽略。这确保了DMA传输只在“数据就绪”且“时机合适”时发生避免了无效或错误的数据搬运。2.2 周期性触发Periodic Triggering机制详解这是DMA Mux最强大的功能之一尤其适用于需要定时、周期性数据交换的场景。只有前4个DMA通道Channel 0-3支持此功能。原理你可以将一个硬件定时器如周期中断定时器PIT的输出作为某个DMA通道的触发源。当定时器周期性地产生触发脉冲时如果此时该通道绑定的外设正在请求DMA例如SPI发送缓冲区为空等待新数据则DMA传输立即启动。配置步骤以通道2源#5启用触发为例确定通道与源选定支持触发的通道0-3例如通道2。确定外设源编号例如SPI发送为源#5。清零通道配置向CHCONFIG2寄存器写入0x00。这一步清除了通道使能ENBL和触发使能TRIG位是安全的配置起点。配置eDMA通道在eDMA控制器中配置通道2的传输控制描述符TCD包括源/目标地址、传输大小等并使能该eDMA通道。这一步是独立的但必须在Mux配置前完成。配置定时器配置PIT等定时器模块设定你所需的触发间隔例如5μs。使能Mux通道并绑定触发向CHCONFIG2寄存器写入最终值。对于源#5并使能触发该值通常为0xC5。这里的0xC5如何得来C5十六进制 1100 0101二进制最高位bit 7通常为1表示通道使能ENBL。次高位bit 6为1表示触发使能TRIG。低6位bit 5-0是源编号000101二进制即5十进制。因此0xC5这个值同时完成了“使能通道”、“使能触发”、“选择源#5”三个操作。// 寄存器地址定义示例具体地址需查数据手册 #define DMAMUX_BASE_ADDR 0xFC084000 volatile unsigned char *CHCONFIG2 (volatile unsigned char *)(DMAMUX_BASE_ADDR 0x02); // 配置步骤 *CHCONFIG2 0x00; // 1. 清零配置 // 2. 此处省略配置eDMA通道2的TCD并使其能 // 3. 此处省略配置PIT定时器产生5us周期触发 *CHCONFIG2 0xC5; // 4. 使能通道启用触发绑定源#5应用场景周期性数据采集配置ADC的DMA请求到某个通道并用定时器触发。这样无需CPU干预系统就能以固定频率如10kHz采集模拟信号并存入内存。波形生成将存储波形数据如正弦波表的内存区域作为源GPIO端口作为目标配置DMA。用定时器触发DMA即可自动、精准地将波形数据输出到GPIO引脚生成模拟信号需配合外部DAC或滤波电路。2.3 “始终启用”Always Enabled源解析除了外设请求源DMA Mux还提供了几个特殊的“始终启用”源。它们不像外设源那样受外设请求信号“节制”。一旦将DMA通道配置为使用“始终启用”源该通道就会像打开了水龙头一样只要eDMA控制器准备好就会持续不断地进行传输除非被带宽控制或优先级更高的通道打断。核心价值与典型用例软件启动的传输当你需要CPU主动发起一次DMA传输时例如命令驱动型数据搬移可以使用“始终启用”源。CPU只需设置好TCD然后通过软件触发设置TCD中的START位或直接使能该通道传输便会立即开始。内存到内存的高速搬移这是最直接的用途。配置源地址和目标地址均为内存地址选择“始终启用”源启动后DMA会以最大带宽在后台搬移数据效率远高于CPU。GPIO的高速、无节制读写当需要以最高速率向GPIO端口写入或读取数据流时例如驱动LED矩阵或高速采样数字信号使用“始终启用”源可以避免因等待外设“准备就绪”信号而产生的延迟。构建链式或复杂传输结合通道链接Channel Linking功能“始终启用”源可以用于在多个传输任务间自动切换实现复杂的传输序列。配置注意事项 使用“始终启用”源时你需要格外小心数据传输的“节奏”。因为没有外设请求来自然限流你必须通过其他方式控制传输速率例如eDMA带宽控制BWC字段在TCD中设置带宽控制强制DMA引擎在每次读-写操作后插入空闲周期从而降低均带宽。与周期性触发结合即使使用“始终启用”源你仍然可以启用DMA Mux的触发功能。这样传输只会在定时器触发事件发生时进行从而将“无节制”的传输转变为“周期性”的传输实现了流控。3. 增强型DMAeDMA控制器架构与传输控制描述符TCD深度剖析eDMA是飞思卡尔/恩智浦第二代DMA控制器的核心其设计理念是“高度可编程”和“最小化CPU干预”。它通过一个存储在本地SRAM中的传输控制描述符TCD来完全定义一次复杂的传输任务。理解TCD的每个字段是驾驭eDMA的关键。3.1 TCD数据结构与双循环模型eDMA的传输模型基于“主循环Major Loop”和“次循环Minor Loop”的双重嵌套结构这是其强大灵活性的根源。次循环Minor Loop一次“服务请求”由软件、外设或链接触发所执行的全部数据传输。它由TCD中的NBYTES字段定义要传输的总字节数。eDMA引擎会根据源传输大小SSIZE和目的传输大小DSIZE自动计算出需要多少次“读-写”操作来完成这NBYTES个字节的搬运。一次Minor Loop的完成消耗一次服务请求并完成主循环的一次迭代。主循环Major Loop由BITER起始迭代计数和CITER当前迭代计数字段控制。BITER定义了主循环的总迭代次数即Minor Loop需要被执行多少次。CITER在每次Minor Loop完成后递减当减到0时表示整个主循环即整个DMA传输任务完成。这种模型非常适合处理二维数据。例如将一个图像数据块从摄像头接口搬运到显示缓冲区。假设图像是320x240像素每个像素2字节。你可以设置SSIZE和DSIZE为16位半字。设置NBYTES 320*2 640字节。这意味着一次Minor Loop搬运一行图像数据。设置BITER 240。这意味着主循环需要执行240次即搬运240行。设置SOFF 2每读一个像素源地址2字节。设置DOFF 2每写一个像素目标地址2字节。设置SLAST -640当一行搬完Minor Loop结束时将源地址调整回行首假设源数据是连续存放的。设置DLAST_SGA 640当一行搬完Minor Loop结束时将目标地址指向下一行的行首。这样只需启动一次DMA它就能自动完成整个图像帧的搬运并在完成后产生中断通知CPU。3.2 关键TCD字段精讲与配置策略SADDR与DADDR源/目标地址这是传输的起点和终点。可以是内存地址如数组首地址也可以是外设数据寄存器地址如SPI0-DR。注意在传输过程中这两个地址会被引擎自动更新根据SOFF/DOFF和SLAST/DLAST_SGA。SOFF与DOFF源/目标地址偏移有符号整数。在每次传输完SSIZE/DSIZE指定的数据单元后引擎会将当前地址加上这个偏移量以指向下一个数据单元。典型配置对于线性递增的内存缓冲区通常设置为传输数据本身的大小如SSIZE字(4字节)则SOFF4。如果是从一个固定的外设寄存器读取数据如ADC结果寄存器则SOFF应设为0。对于乒乓缓冲区或环形缓冲区需要结合SMOD/DMOD使用。SSIZE与DSIZE源/目标传输大小定义每次访问的粒度。可选8位、16位、32位、64位甚至16字节、32字节的突发Burst传输。大小不匹配的处理这是eDMA的一个智能特性。如果SSIZEDSIZE例如从8位UART读向32位内存写eDMA会执行多次读操作凑足一次写操作的数据量。反之亦然。这简化了不同位宽设备间的数据搬运。SMOD与DMOD源/目标地址模数这是实现环形缓冲区或滑动窗口访问的关键。模数N定义了一个2^N字节的地址区域。当地址加上偏移后超出这个区域时地址会自动回绕到区域的起始点。示例设置DMOD 52^5 32字节。目标地址在0x2000_0100到0x2000_011F之间循环。当一次写操作后地址达到0x2000_0120时它会自动回绕到0x2000_0100。这非常适合实现一个固定大小的FIFO或数据缓冲区无需软件检查边界和重置指针。NBYTES次循环字节数定义每次服务请求要传输的总字节数。eDMA引擎内部会根据SSIZE和DSIZE计算出需要多少次读/写操作。NBYTES必须是源/目标传输大小中较大者的整数倍。SLAST与DLAST_SGA最后源/目标地址调整在每次主循环即CITER递减完成后应用的地址调整值。SLAST通常用于在一次二维传输完成后将源地址重置到下一“行”或某个特定位置。DLAST_SGA功能更强大当E_SG散点/收集使能为0时它作为普通的最后目标地址调整值。当E_SG为1时DLAST_SGA被解释为一个内存地址该地址处存放着下一个TCD。这意味着在主循环完成后eDMA会自动从该地址加载一个新的TCD来重新配置本通道从而实现复杂的传输链或动态任务切换这是实现高级DMA调度的基础。BITER/CITER起始/当前主循环迭代计数与链接LinkingBITER是初始值CITER是运行值。CITER从BITER开始每完成一次Minor Loop减1减到0则主循环完成。CITER.E_LINK和BITER.E_LINK位控制“次循环链接”。若使能则在每次Minor Loop完成后即CITER减1但未到0时会自动启动CITER.LINKCH指定的另一个通道。这可以用于实现两个传输任务的交替执行Ping-Pong Buffer。MAJOR.E_LINK位控制“主循环链接”。若使能则在主循环完成CITER减到0时会自动启动MAJOR.LINKCH指定的另一个通道。这用于构建传输任务序列。INT_MAJ与INT_HALF中断控制INT_MAJ主循环完成时产生中断。INT_HALF当CITER减到BITER的一半时产生中断。这在处理双缓冲区时非常有用当DMA填满半个缓冲区时产生中断CPU可以安全处理这半部分数据而DMA同时向另一半缓冲区写入数据。3.3 eDMA通道配置与启动流程配置一个eDMA通道是一个精细的过程以下是一个标准流程以内存到外设如SPI发送的传输为例关闭通道在修改TCD前先通过eDMA的通道控制寄存器禁用目标通道防止配置过程中发生意外传输。填充TCD结构体在内存中定义一个与TCD对应的数据结构并填充各个字段。务必注意字节序和对齐通常需要32位对齐。typedef struct { uint32_t SADDR; // 源地址如数据数组地址 uint16_t ATTR; // 属性SMOD, SSIZE, DMOD, DSIZE (需按位组合) int16_t SOFF; // 源地址偏移如每次传输后4 uint32_t NBYTES; // 次循环字节数如一次传输16字节 uint32_t SLAST; // 主循环后源地址调整如0不调整 uint32_t DADDR; // 标地址如 (SPI0-DR) uint16_t CITER; // 当前迭代计数初始化时等于BITER int16_t DOFF; // 目标地址偏移如0固定寄存器 uint32_t DLAST_SGA; // 主循环后目标地址调整或SG地址 uint16_t BITER; // 起始迭代计数如100次 uint16_t CSR; // 控制状态INT_MAJ, INT_HALF, START等位 } tcd_t; tcd_t myTcd __attribute__((aligned(32))); // 确保32字节对齐 myTcd.SADDR (uint32_t)source_buffer; myTcd.ATTR (0 5) | (2 2) | (0 0); // SMOD0, SSIZE2(32位), DMOD0, DSIZE2(32位) myTcd.SOFF 4; // 每次读后源地址4字节 myTcd.NBYTES 64; // 每次服务请求传输64字节 myTcd.SLAST 0; myTcd.DADDR (uint32_t)(SPI0-DR); myTcd.CITER 100; myTcd.DOFF 0; // 目标地址固定 myTcd.DLAST_SGA 0; myTcd.BITER 100; myTcd.CSR (1 7); // 使能主循环完成中断(INT_MAJ)其他位默认0写入TCD内存将准备好的TCD结构体拷贝到eDMA控制器为该通道分配的专用TCD内存区域。这个地址是映射到IPS总线上的固定偏移。通常有专门的库函数或寄存器来完成此操作。配置DMA Mux如前所述将对应的外设请求源或“始终启用”源路由到该eDMA通道并根据需要配置触发。使能eDMA通道中断可选在NVIC嵌套向量中断控制器中使能该eDMA通道的中断。启动传输软件启动如果使用“始终启用”源可以直接设置TCD中的START位或写eDMA的软件触发寄存器。硬件启动如果配置了外设请求和/或触发当外设就绪且触发条件满足时传输自动开始。重要提示在传输过程中切勿修改正在被eDMA引擎使用的TCD字段特别是CITER,SADDR,DADDR。安全的做法是在修改TCD前先禁用通道或使用双缓冲TCD通过E_SG功能实现。对于BITER、NBYTES等描述传输规模的字段如果在传输中修改可能导致不可预知的行为。4. 实战应用构建无需CPU干预的数据处理系统理论需要结合实践。我们设计两个综合性的案例展示如何将DMA Mux和eDMA结合起来构建高效的数据流。4.1 案例一基于SPI与定时触发的全自动数据采集与转发系统场景系统需要以100kHz的固定频率通过SPI从外部传感器读取16位数据并实时存入一个大小为1000个样本的环形缓冲区。当缓冲区半满500个样本和全满时需要通知CPU进行处理。系统设计SPI配置将SPI配置为主机模式时钟频率满足100kHz采样率。使能SPI接收的DMA请求。缓冲区设计在内存中定义两个uint16_t数组adc_buffer[1000]。这作为一个环形缓冲区。eDMA通道配置通道0用于SPI接收SADDR:(SPI0-DR)(SPI数据寄存器地址)SOFF: 0 (源地址固定)SSIZE: 16位DADDR:adc_buffer(目标数组首地址)DOFF: 2 (每次写入后目标地址2字节)DMOD: 计算值。缓冲区总字节数为2000字节。找到大于等于2000的2的幂是2048 (2^11)。因此DMOD 11实现地址在0~2047字节范围内回绕完美匹配环形缓冲区。NBYTES: 2 (每次请求传输一个16位样本)BITER: 1000 (主循环计数对应缓冲区深度)CITER: 1000DLAST_SGA: 0 (E_SG0)INT_MAJ: 0 (我们不希望缓冲区全满才通知那样会丢失数据)INT_HALF: 1(关键)使能半满中断。CSR: 相应配置。DMA Mux配置将SPI接收请求源路由到eDMA通道0。不启用定时触发因为采样率由SPI时钟本身控制。DMA传输的节奏由SPI接收数据的速度即外设请求决定。CPU角色初始化所有配置后启动SPI通信。CPU无需干预数据传输。当DMA的INT_HALF中断触发时意味着adc_buffer的前500个样本已就绪。CPU可以在中断服务程序ISR中安全地读取和处理这500个样本例如进行滤波、计算。与此同时DMA正在向后500个样本位置继续写入数据实现了“乒乓”操作数据流永不间断。4.2 案例二利用“始终启用”源与通道链接实现内存到GPIO的复杂波形生成场景需要生成一个由多个不同频率和幅度的正弦波片段拼接而成的复杂波形并通过GPIO端口配合R-2R电阻网络或专用DAC芯片输出模拟信号。系统设计波形数据准备在内存中预先计算好多个正弦波片段的采样值数组例如sin_wave1[100],sin_wave2[200],dc_wave[50]直流电平。eDMA通道配置多个通道协作通道1负责输出sin_wave1。SADDR:sin_wave1DADDR:(GPIOA-ODR)(数据输出寄存器)SOFF: 2 (假设16位数据)DOFF: 0NBYTES: 200 (100个样本 * 2字节)BITER: 1 (只播放一次这个片段)MAJOR.E_LINK: 1(关键)MAJOR.LINKCH: 2 (主循环完成后链接到通道2)通道2负责输出sin_wave2。配置类似BITER可能为1并链接到通道3。通道3负责输出dc_wave。配置类似BITER可能为10输出10次该直流电平并链接回通道1或设置为停止。所有通道使用“始终启用”源。INT_MAJ使能用于在每段波形输出完成后可选的CPU通知例如更新状态标志。DMA Mux配置将通道1、2、3都配置为使用同一个“始终启用”源例如源#63。同时为通道1启用周期性触发触发间隔根据输出采样率设定例如欲产生1kHz正弦波每周期100点则触发间隔为10us。运行流程CPU启动通道1并配置好定时器触发。定时器第一次触发通道1开始将sin_wave1的数据搬移到GPIO。由于是“始终启用”源只要eDMA空闲数据会以最快速度输出受带宽控制限制。NBYTES200所以这次触发会搬完整个sin_wave1数组。通道1的主循环BITER1完成。由于其MAJOR.E_LINK1硬件自动将通道2的START位置1。此时定时器第二次触发到来。DMA Mux看到通道2有服务请求被链接启动且触发条件满足于是开始执行通道2的传输输出sin_wave2。如此循环通道2完成后链接到通道3输出直流电平。通道3完成后可以链接回通道1形成循环或产生中断让CPU介入动态加载下一组波形片段TCD利用E_SG功能实现任意复杂序列的波形播放。这个系统的精妙之处在于CPU仅在初始配置和可能的序列切换时介入。整个复杂波形的生成、片段切换、定时输出全部由DMA硬件自动完成CPU负载几乎为零且输出时序由硬件定时器保证极其精准。5. 调试技巧、常见问题与避坑指南在实际开发中DMA配置复杂出错时现象往往难以直接定位。以下是一些宝贵的实战经验。5.1 调试方法与工具寄存器检查法首先务必逐字核对写入的TCD内存内容。许多IDE的Memory窗口可以查看。将你的tcd_t结构体内容与计算出的期望值进行对比特别是NBYTES、BITER/CITER、地址和偏移量。状态标志监控eDMA有错误状态寄存器ES和通道完成中断标志寄存器INT。在调试时使能所有错误中断并在ISR中读取ES寄存器确定错误类型如配置错误、总线错误。通道的DONE和ACTIVE位也反映了其状态。逻辑分析仪/示波器这是最直观的工具。探测GPIO输出可以验证DMA是否按预期工作以及时序是否正确。对于SPI等通信可以捕捉时钟和数据线确认DMA传输的数据内容。“分步仿真”法在复杂传输中先将BITER设1NBYTES设小只让DMA执行一次极小的传输。用调试器单步跟踪检查源和目标内存的变化是否符合预期。逐步增加复杂度和数据量。5.2 常见问题排查表现象可能原因排查步骤与解决方案DMA根本不启动1. eDMA通道未使能。2. DMA Mux通道未使能或源未正确绑定。3. TCD中的START位未置位软件启动时。4. 外设未产生请求硬件启动时。5. 触发条件未满足若配置了触发。1. 检查eDMA的通道使能寄存器ERQ。2. 检查DMA Mux的CHCONFIGx寄存器确认ENBL位和源编号正确。3. 检查TCD的CSR[START]位或软件触发寄存器。4. 检查外设的DMA请求使能位及其状态如SPI的发送缓冲区空标志。5. 检查定时器是否运行并产生触发信号。DMA只传输一次就停止1.BITER设置为1。2. 外设请求在第一次传输后被禁用例如SPI传输完成后自动关闭了DMA请求。3. 使用了“始终启用”源但未配置通道链接或循环。1. 检查BITER值确保主循环迭代次数正确。2. 检查外设配置确保DMA请求在传输过程中持续有效。对于SPI可能需要使能“连续传输”模式。3. 若需连续传输考虑使用通道链接主循环链接回自身或配置外设产生连续请求。数据传输地址错乱1.SOFF/DOFF设置错误。2.SMOD/DMOD设置错误导致地址回绕不在预期位置。3.SLAST/DLAST_SGA计算错误。1. 重新计算偏移量。记住偏移是在每次传输后加上的单位是字节。2. 仔细计算缓冲区大小确保2^N大于等于缓冲区字节大小且地址对齐正确。3.SLAST/DLAST_SGA是在主循环完成后加的。用于将地址复位到行首或下一个缓冲区。使用公式SLAST - (次循环传输次数 * SOFF)。中断不产生1.INT_MAJ或INT_HALF位未使能。2. eDMA全局中断或通道中断在NVIC中未使能。3. 中断标志被意外清除。4. 主循环未完成CITER未减到0或半满条件未达到。1. 检查TCD中CSR寄存器的中断使能位。2. 检查eDMA的中断使能寄存器及MCU的NVIC配置。3. 在中断服务程序ISR中必须读取相应的中断标志寄存器INT以清除标志位否则会持续触发中断。4. 在调试器中查看CITER的当前值。系统卡死或进入硬件错误1.最常见总线访问错误。DMA试图访问非法或未初始化的内存/外设地址。2. TCD字段配置矛盾导致eDMA引擎出现未定义行为。3. 在DMA传输过程中修改了正在被使用的TCD。1. 仔细检查SADDR和DADDR确保它们指向有效的、可访问的内存区域或外设寄存器。特别是外设寄存器地址必须绝对正确。2. 确保NBYTES是SSIZE和DSIZE中较大者的整数倍。确保地址偏移和模数设置不自相矛盾。3.绝对禁止在通道激活ACTIVE1时修改其TCD。修改前务必禁用通道或使用双缓冲Scatter/Gather机制。5.3 高级优化与避坑心得带宽控制BWC的妙用在内存到内存或到高速外设的传输中全速DMA可能会占用大量总线带宽导致CPU或其他主设备如另一个DMA访问延迟增加影响系统实时性。通过设置TCD中的BWC字段可以强制DMA引擎在每次读-写操作后插入空闲周期从而主动限制其带宽占用率为其他总线主设备留出时间片。优先级与抢占PreemptioneDMA支持通道优先级和抢占。高优先级通道可以抢占低优先级通道的传输。这在处理高实时性中断响应的数据流如音频和低优先级后台搬运任务时非常有用。合理规划通道优先级可以确保关键数据流不被阻塞。散点/收集Scatter/Gather的真正威力E_SG功能不仅仅是加载下一个TCD。你可以构建一个TCD链表或数组每个TCD描述一段不连续内存区域的传输。eDMA在主循环完成后自动加载下一个TCD从而实现将分散在内存各处的数据块自动收集到连续区域或将连续数据分散写入不同位置。这在处理视频帧缓冲区、网络数据包聚合等场景下能极大简化软件逻辑。对齐至关重要确保源和目标地址按照SSIZE和DSIZE的要求进行对齐例如32位传输要求4字节对齐。非对齐访问在某些架构上会导致性能下降或总线错误。SOFF和DOFF也应是传输大小的整数倍。关闭DMA的时机在系统进入低功耗模式前务必妥善停止所有DMA活动。先通过eDMA寄存器停止通道再关闭时钟源。否则DMA可能试图访问已下电的内存或外设导致系统故障。深入掌握DMA Mux和eDMA意味着你能将MCU的数据搬运能力发挥到极致构建出真正高效、实时、可靠的嵌入式系统。它要求开发者不仅了解寄存器配置更要理解数据流、时序和系统架构。开始时可能会觉得繁琐但一旦打通它将成为一个无比强大的工具让你设计的系统在性能上脱颖而出。