Tiva μDMA控制器寄存器详解与实战配置指南

1. 项目概述与μDMA核心价值

在嵌入式系统开发中,尤其是面对Tiva™ TM4C1292NCZAD这类高性能ARM Cortex-M微控制器时,如何高效、实时地处理海量数据流,是决定系统性能上限的关键。无论是从ADC采集传感器波形,通过UART收发大量数据,还是搬运图像帧缓冲区,如果这些操作都依赖CPU通过软件循环一个个字节地搬运,那CPU将深陷于枯燥的“搬运工”角色,无法执行更复杂的算法和逻辑判断,系统响应性也会大打折扣。这时,直接内存访问(DMA)技术就成了解放CPU、提升系统并行处理能力的“神器”。

而Tiva系列微控制器集成的微直接内存访问(μDMA)控制器,更是将DMA的灵活性和智能化提升到了一个新的高度。它不仅仅是一个简单的数据搬运工,更是一个配备了独立状态机、支持多种复杂传输模式、可精细配置的智能数据引擎。其核心魅力在于,通过一套精心设计的寄存器集,开发者可以像指挥交响乐团一样,精确编排每一个数据通道的行为:何时开始、传输多少、从哪里来到哪里去、传输完成后做什么,甚至可以在多个任务间无缝切换。

理解并熟练配置这些寄存器,是从“能跑起来”到“跑得流畅、跑得稳定”的必经之路。很多新手在初次接触μDMA时,面对数十个寄存器可能会感到无从下手。其实,只要抓住“通道控制结构”和“控制器配置寄存器”这两条主线,就能理清脉络。本文将聚焦于后者——那些位于0x400F.F000基地址的μDMA控制器寄存器,深入解析它们每一位的含义、联动关系以及在实际项目中的配置技巧。我们将绕过枯燥的罗列,直接切入如何用这些寄存器搭建起高效可靠的数据传输管道,并结合乒乓(Ping-Pong)、散聚(Scatter-Gather)等高级模式,让你真正掌握μDMA的实战能力。

2. μDMA控制器寄存器全景与访问基础

在深入每个寄存器之前,我们必须建立两个核心认知:内存中的通道控制结构控制器本身的配置寄存器。这是理解μDMA如何工作的基石。

通道控制结构位于系统内存中,由开发者定义。它是一个数据结构,包含了某次传输任务的所有参数:源地址、目的地址、传输数据量、传输模式、数据宽度等。每个通道都有两套这样的结构:主(Primary)和备(Alternate),这是实现乒乓、散聚等高级模式的基础。控制器会从内存中读取这些结构来执行任务。

控制器配置寄存器则映射在微控制器的固定地址空间(0x400F.F000),用于全局管理和控制μDMA引擎本身。它们不定义具体的传输任务,而是控制任务如何被触发、执行以及状态反馈。例如,开启或关闭整个DMA控制器、启用某个通道、设置通道优先级、查询错误状态等,都是通过这些寄存器完成的。

访问这些寄存器,本质上就是对这个地址空间进行读写操作。在C语言中,我们通常通过定义好的硬件抽象层(HAL)库(如TivaWare)提供的函数或宏来操作,但理解其底层内存映射对于调试和深度优化至关重要。所有寄存器的偏移地址都是相对于基地址0x400F.F000计算的。例如,DMA状态寄存器(DMASTAT)的偏移是0x000,那么它的完整地址就是0x400F.F000 + 0x000 = 0x400F.F000

注意:在访问这些寄存器前,必须确保系统总线时钟(如AHB)已经启用,并且μDMA控制器所在的系统外设时钟(在系统控制模块中)已被使能。否则,对寄存器的读写操作可能无效或导致总线错误。

寄存器的类型(Type)指明了其行为:

  • RO (Read-Only):只读,通常用于状态反馈,如DMASTAT。
  • RW (Read-Write):可读写,用于配置,如DMACFG。
  • WO (Write-Only):只写,通常用于触发动作或清除标志,如DMASWREQ。
  • RW1C (Read/Write 1 to Clear):可读,但通过写1来清除位,常用于中断或错误状态标志,如DMAERRCLR中的ERRCLR位。

在编程时,务必遵循“读-修改-写”的原则来操作寄存器的特定位,避免影响其他无关位的状态。通常使用HWREG()宏配合位掩码和位操作来完成。

3. 核心控制与状态寄存器详解

这一组寄存器是μDMA控制器的“大脑”和“仪表盘”,负责全局的开关、状态监控和基础资源配置。

3.1 DMA状态寄存器 (DMASTAT)

DMASTAT寄存器是调试时最常查看的寄存器之一,它提供了控制器和通道的实时快照。

  • 位[31:21]: 保留位。读取值不确定,写入时应保留原值。
  • 位[20:16] DMACHANS: 这是一个非常重要的只读字段,它报告了当前μDMA控制器硬件支持的通道数量减一。例如,如果读出的值是0x1F(十进制31),那么支持的通道数就是31+1=32个。这个值在芯片设计时固定,软件可以读取它来动态适配不同型号的Tiva MCU。
  • 位[15:8]: 保留位。
  • 位[7:4] STATE:控制状态机状态。这是诊断DMA卡死或异常的核心字段。它指示了DMA控制器内部状态机的当前状态:
    • 0x0: 空闲(Idle),控制器没有进行任何传输。
    • 0x1: 正在读取通道控制数据(即从内存加载通道控制结构)。
    • 0x2/0x3: 正在读取源/目的末端指针。
    • 0x4/0x5: 正在读取源数据/写入目的数据,即正在进行实际的数据搬运。
    • 0x6: 等待μDMA请求清除。通常发生在一次突发(Burst)传输完成后,等待外设撤销其DMA请求信号。
    • 0x7: 正在写回通道控制数据(如更新剩余传输计数)。
    • 0x8: 停滞(Stalled)。这是一个关键错误状态,通常意味着DMA在访问总线时遇到了问题(如访问了非法地址或总线错误),或者传输过程中发生了错误。遇到此状态需要检查总线配置和地址参数。
    • 0x9: 完成(Done)。单次传输任务完成。
    • 0xA-0xF: 未定义。
  • 位[3:1]: 保留位。
  • 位[0] MASTEN: 主使能状态位(只读)。反映DMACFG寄存器中MASTEN位的当前值。0表示控制器被禁用,1表示已启用。

实操心得:当你的DMA传输没有按预期发生时,第一个检查点就是DMASTAT。先看MASTEN是否为1,确保控制器已全局使能。然后看STATE字段,如果长时间处于0x8(Stalled),几乎可以断定是总线地址错误或内存访问权限问题(例如,试图向只读的Flash地址写入数据)。DMACHANS字段则可以用来验证你的软件是否运行在预期的芯片型号上。

3.2 DMA配置寄存器 (DMACFG)

这是一个非常简单的只写寄存器,只有一个有效位,但它是整个μDMA的“总开关”。

  • 位[31:1]: 保留位。写入时必须为0。
  • 位[0] MASTEN: 控制器主使能位。
    • 0: 禁用整个μDMA控制器。所有通道活动停止,寄存器(除了DMASTAT等少数)可能无法访问。
    • 1: 使能μDMA控制器。这是进行任何DMA操作的前提。

配置示例

// 使能 μDMA 控制器 HWREG(UDMA_BASE + UDMA_O_CFG) = 1; // UDMA_BASE 通常是 0x400F.F000, UDMA_O_CFG 是偏移量 0x004

在系统初始化阶段,通常在配置完系统时钟和外设后,尽早使能此位。在低功耗模式下,可能需要禁用DMA以节能。

3.3 DMA通道控制基址指针寄存器 (DMACTLBASE)

这是连接“控制器配置寄存器”和“内存中通道控制结构”的桥梁,是μDMA配置中最关键的一步之一。

  • 位[31:10] ADDR: 通道控制表基地址的高22位��你需要在内存中(通常是SRAM区)分配一块区域,用于存放所有通道的主控制结构(可能还有备控制结构)。这个地址必须1024字节对齐(即低10位为0)。控制器会用这个基地址加上通道号偏移来定位每个通道的控制结构。
  • 位[9:0]: 保留位(只读为0)。

为什么必须1024字节对齐?这是硬件设计上的要求,目的是简化地址计算,提高访问效率。每个通道的控制结构占用16字节(4个32位字)。对于32个通道,主控制表需要32*16=512字节。如果启用备控制结构,则需要另外512字节,总共1024字节。对齐要求确保了整个控制表位于一个对齐的内存块中。

配置步骤与计算

  1. 在内存中定义一个对齐的数组作为控制表。例如:
    // 强制编译器将控制表对齐到1024字节边界 #pragma DATA_ALIGN(controlTable, 1024) // 或者使用C11的 _Alignas _Alignas(1024) static uint32_t controlTable[256]; // 256个uint32_t = 1024字节
  2. 将这个数组的地址(其低10位必然为0)右移10位后,写入DMACTLBASE的ADDR字段。
    uint32_t baseAddr = (uint32_t)controlTable; // 确保地址对齐 ASSERT((baseAddr & 0x3FF) == 0); // 写入寄存器(取高22位) HWREG(UDMA_BASE + UDMA_O_CTLBASE) = (baseAddr >> 10);

3.4 DMA备选通道控制基址指针寄存器 (DMAALTBASE)

这是一个只读寄存器,硬件自动计算并返回备选控制结构表的基地址。其值固定为DMACTLBASE + 0x200(即512字节偏移)。在配置散聚传输模式时,源地址指针会指向一个任务列表,而这个列表中的任务描述符最终会被加载到以DMAALTBASE为基址的备选控制结构区域中执行。软件无需手动计算此地址,直接读取该寄存器即可使用。

4. 通道使能、请求与优先级管理

配置好控制表基址后,下一步就是管理具体的通道:如何启动、如何触发、谁先谁后。

4.1 通道使能设置与清除 (DMAENASET, DMAENACLR)

这两个寄存器用于独立地启用或禁用每个DMA通道。每个位对应一个通道(位0对应通道0)。

  • DMAENASET (RW): 写1到某位,使能对应通道。读取该寄存器返回所有通道的当前使能状态。
  • DMAENACLR (WO): 写1到某位,清除DMAENASET中对应的位,从而禁用该通道。

重要机制:当一个通道的传输任务完成(到达传输终点)时,硬件会自动清除DMAENASET中对应的位,即通道会自动禁用。这意味着每次传输都需要重新使能通道(除非使用自动重载模式,如Ping-Pong)。这是防止DMA失控的重要安全机制。

配置示例:使能通道5。

// 使能通道5 HWREG(UDMA_BASE + UDMA_O_ENASET) = (1 << 5); // 检查通道5是否已使能 uint32_t enaStatus = HWREG(UDMA_BASE + UDMA_O_ENASET); if (enaStatus & (1 << 5)) { // 通道5已使能 } // 禁用通道5 HWREG(UDMA_BASE + UDMA_O_ENACLR) = (1 << 5);

4.2 通道软件请求寄存器 (DMASWREQ)

除了外设硬件自动发出DMA请求,软件也可以主动触发一次传输。向DMASWREQ寄存器的某位写1,就会为对应通道产生一个软件请求。该位会在请求被响应后自动清零。

应用场景

  1. 内存到内存的传输:没有外设参与,纯粹由软件发起数据块搬运。
  2. 测试与调试:在不连接实际外设的情况下,验证DMA通道和控制结构配置是否正确。
  3. 手动触发单次传输:在某些需要精确控制传输时机的场景。

注意:要使软件请求生效,该通道必须已被使能(DMAENASET对应位为1),并且其请求未被屏蔽(DMAREQMASKSET对应位为0)。

4.3 通道请求掩码设置与清除 (DMAREQMASKSET, DMAREQMASKCLR)

这两个寄存器用于屏蔽或允许外设对特定通道的硬件DMA请求。

  • DMAREQMASKSET (RW): 写1到某位,将屏蔽对应通道的外设硬件请求。读取返回当前掩码状态。
  • DMAREQMASKCLR (WO): 写1到某位,将清除DMAREQMASKSET中的对应位,从而允许外设请求。

核心作用

  1. 通道复用:当一个物理通道可能被多个外设源(通过DMACHMAPn配置)分时复用时,可以通过掩码来切换当前有效的请求源。
  2. 纯软件控制:当设置掩码后,该通道将不再响应外设硬件请求,此时只能通过DMASWREQ进行软件触发。这在一些非实时或复杂调度的传输中很有用。
  3. 传输安全:在配置通道控制结构或传输过程中,暂时屏蔽请求可以防止外设在不合适的时机发起传输,导致数据错乱。

4.4 通道优先级设置与清除 (DMAPRIOSET, DMAPRIOCLR)

μDMA支持两个优先级级别:默认优先级和高优先级。当多个通道同时产生请求时,高优先级通道会被优先服务。

  • DMAPRIOSET (RW): 写1到某位,将对应通道设置为高优先级。
  • DMAPRIOCLR (WO): 写1到某位,将对应通道恢复为默认优先级。

策略建议:通常将服务于高速、实时性要求高的外设(如ADC连续采样、高速SPI)的通道设置为高优先级。而服务于低速或对实时性不敏感的外设(如UART、定时器触发)的通道使用默认优先级即可。注意,优先级只在仲裁时起作用,一旦高优先级通道开始一次突发传输,它就会占用总线直到本次突发完成,期间即使有更高优先级的请求到来也不会被中断(即非抢占式)。

5. 高级传输模式的关键控制寄存器

乒乓和散聚模式是μDMA的精华所在,它们实现了数据流的无缝衔接和复杂传输任务的自动化调度。以下寄存器是管理这些模式的核心。

5.1 通道主/备控制结构选择寄存器 (DMAALTSET, DMAALTCLR)

在乒乓和散聚模式下,每个通道有两套控制结构:主(Primary)和备(Alternate)。控制器在执行过程中会在两套结构间切换。这两个寄存器用于手动查询或设置当前使用的是哪套结构。

  • DMAALTSET (RW): 写1到某位,强制对应通道使用备控制结构。读取该寄存器可以知道每个通道当前正在使用哪套结构(0=主,1=备)。
  • DMAALTCLR (WO): 写1到某位,强制对应通道使用主控制结构。

关键点:在乒乓(Ping-Pong)模式散聚(Scatter-Gather)模式下,硬件会自动管理这两个寄存器的位。当一次传输(由主或备结构定义)完成时,硬件会自动切换DMAALTSET中的状态位,并加载另一套控制结构开始下一次传输。因此,在配置这些高级模式时,通常不需要软件手动操作DMAALTSET/DMAALTCLR。软件的角色是正确初始化两套控制结构,并设置好传输模式。

软件介入的场景

  1. 模式初始化后:在启动传输前,确保通道从主控制结构开始。可以在初始化后写DMAALTCLR来确保状态位为0。
  2. 动态任务切换:在复杂的散聚传输中,如果软件需要动态改变即将执行的任务链,它可能需要先暂停通道(通过DMAENACLR),手动修改DMAALTSET状态和控制表内容,再重新使能。
  3. 错误恢复:如果传输因错误停止,软件可能需要检查DMAALTSET状态,以确定错误发生在哪套控制结构上,从而进行针对性恢复。

5.2 通道UseBurst设置与清除 (DMAUSEBURSTSET, DMAUSEBURSTCLR)

这个寄存器控制通道对外设请求类型的响应方式,对性能有显著影响。

  • DMAUSEBURSTSET (RW): 写1到某位,配置对应通道仅响应突发(Burst)请求,忽略单次(Single)请求。
  • DMAUSEBURSTCLR (WO): 写1到某位,清除上述设置,使��道响应单次和突发请求。

理解请求类型

  • 单次请求(Single Request):外设每准备好一个数据单元(如一个字节、半字)就产生一次请求。DMA控制器响应一次,传输一个数据单元。
  • 突发请求(Burst Request):外设准备好一组数据单元(数量由通道控制结构中的ARBSIZE字段定义,如4、8个)后,产生一次请求。DMA控制器响应一次,连续传输完这一整组数据。

为什么要用UseBurst?

  • 提升效率:突发传输减少了总线仲裁和地址建立/撤销的次数,在传输连续数据块时能显著提升总线利用率和整体吞吐量。
  • 外设支持只有支持突发请求模式的外设才能从此设置中受益。例如,某些ADC或DMA-aware的存储器接口。对于仅支持单次请求的外设(如标准UART),设置此位将导致DMA完全无法响应。

硬件自动行为:这是一个非常智能的设计。即使你设置了UseBurst,当剩余待传输数据量小于突发大小时,硬件会自动清除该位(即切换回响应单次请求),以确保最后几个数据能被正确传输。传输完成后,该位保持清除状态。如果需要开始新一轮的突发传输,软件需要重新设置它。

配置建议:在初始化通道时,如果确认外设支持突发模式且传输的数据量较大,可以设置此位。例如,用于从支持突发读的SRAM区域搬运数据到另一个区域。

6. 通道映射与源选择寄存器

在复杂的系统中,一个物理DMA通道可能需要被多个不同的外设事件触发。Tiva的μDMA通过通道映射寄存器提供了这种灵活性。

6.1 DMA通道映射选择寄存器 (DMACHMAP0-3)

这是比旧的DMACHASGN寄存器更灵活的机制。DMACHMAP0-3四个寄存器,每个管理8个通道(共32通道)。每个通道由一个4位字段(CHxSEL)控制,其值对应一个特定的外设请求源,具体映射关系需要查阅芯片数据手册的“Table 9-1”(在输入资料的676页提及)。

例如,DMACHMAP0的位[3:0]是CH0SEL,它决定了通道0的请求源。默认值为0,通常映射到某个默认外设(如SSI0 Rx)。通过修改这个字段,你可以将通道0重新分配给另一个外设(如UART0 Rx)。

新软件应使用DMACHMAPn:数据手册明确指出,新软件应使用DMACHMAPn寄存器,而非旧的DMACHASGN。DMACHMAPn提供了更精细的控制(4位选择 vs. 1位开关)。

配置示例:假设根据手册,值0x5代表ADC0序列发生器0(ADC0 SS0)。我们想将通道5配置为ADC0的DMA源。

// 假设 UDMA_BASE 已定义 // DMACHMAP0 管理通道 0-7,通道5由 DMACHMAP0 的 CH5SEL 字段控制(位[23:20]) uint32_t regValue = HWREG(UDMA_BASE + UDMA_O_CHMAP0); // 读取当前值 regValue &= ~(0xF << 20); // 清零通道5的4位选择字段(CH5SEL) regValue |= (0x5 << 20); // 设置通道5选择ADC0 SS0 (假设0x5是ADC0) HWREG(UDMA_BASE + UDMA_O_CHMAP0) = regValue; // 写回

重要提示:在改变通道映射时,务必确保该通道已被禁用(DMAENASET对应位为0),且没有正在进行或挂起的传输,否则可能导致不可预知的行为。

7. 错误处理与调试支持寄存器

可靠的系统必须能处理异常。μDMA提供了简单的错误检测机制。

7.1 DMA总线错误清除寄存器 (DMAERRCLR)

这是一个状态兼清除寄存器。当μDMA控制器在执行传输过程中遇到总线错误(例如,访问了一个不存在的内存地址,或试图写入只读的Flash区域)时,该寄存器的ERRCLR位(位0)会被硬件置1。

  • 位[31:1]: 保留。
  • 位[0] ERRCLR: 总线错误状态位。读为1表示有未处理的总线错误。通过向该位写1可以清除这个错误标志(RW1C类型)。

错误发生时的硬件行为

  1. 发生总线错误的通道会被自动禁用(其DMAENASET位被清零)。
  2. DMAERRCLR寄存器的ERRCLR位被置1。
  3. 其他通道的传输不受影响。

软件错误处理流程

  1. 定期或在DMA传输完成中断中检查DMAERRCLR寄存器。
  2. 如果ERRCLR为1,表示发生了总线错误。
  3. 软件应记录错误信息(例如,通过查询DMAALTSET确定出错时正在使用哪套控制结构,检查控制结构中的地址字段)。
  4. 向ERRCLR位写1以清除错误标志
  5. 根据需要重新配置并启用出错的通道。

调试技巧:在开发阶段,可以在主循环或低优先级任务中定期打印DMASTAT和DMAERRCLR的状态,以便快速捕获DMA相关的运行时错误。结合STATE字段和ERRCLR位,可以大致定位问题是配置错误(地址不对齐、权限错误)还是总线冲突。

8. 实战配置流程与常见问题排查

理解了各个寄存器后,我们将其串联起来,形成一个完整的μDMA通道配置与使用流程。

8.1 标准内存到内存传输配置流程

  1. 系统初始化:启用系统时钟和μDMA模块时钟(通过SYSCTL模块)。
  2. 使能μDMA控制器:写DMACFG寄存器,将MASTEN位置1。
  3. 配置控制表基址:在内存中分配1024字节对齐的空间,将其地址右移10位后写入DMACTLBASE寄存器。
  4. 初始化通道控制结构:在控制表中找到目标通道(例如通道ch)对应的主控制结构位置(地址 =controlTableBase + ch * 16)。填充该结构:
    • SRCENDPTR: 源数据结束地址(指向最后一个数据元素后的地址)。
    • DSTENDPTR: 目的数据结束地址。
    • CONTROL: 设置数据量(XFERSIZE)、源/目的地址增量模式、数据宽度、仲裁大小(ARBSIZE)和传输模式(例如,基础模式0x0)。
  5. (可选)配置通道映射:如果使用外设触发,通过DMACHMAPn寄存器将通道映射到特定外设。
  6. (可选)配置请求类型:如果外设支持突发且希望优化,设置DMAUSEBURSTSET对应位。
  7. (可选)设置优先级:如果需要,通过DMAPRIOSET设置高优先级。
  8. 使能通道:写DMAENASET寄存器,将对应位置1。
  9. 触发传输
    • 如果是外设触发,确保外设已配置好并开始产生DMA请求。
    • 如果是软件触发,写DMASWREQ寄存器对应位为1。
  10. 等待传输完成:可以通过查询通道使能位(DMAENASET)是否被硬件自动清除,或者使能DMA传输完成中断来获知。
  11. 处理结果与清理:传输完成后,通道自动禁用。如需再次传输,重复步骤4(更新控制结构)和步骤8、9。

8.2 乒乓模式配置要点

乒乓模式用于创建双缓冲区,实现数据生产与消费的完全并行。

  1. 准备两个缓冲区:Buffer_A和Buffer_B。
  2. 初始化两套控制结构
    • 主控制结构:配置为乒乓模式(XFERMODE=0x3),源/目地址指向Buffer_A,传输大小设为缓冲区容量。设置传输完成产生中断。
    • 备控制结构:同样配置为乒乓模式(XFERMODE=0x3),源/目地址指向Buffer_B,传输大小设为缓冲区容量。设置传输完成产生中断。
    • 关键:两套结构的XFERMODE都必须设为乒乓模式。
  3. 配置控制表基址(同上)。
  4. 使能通道
  5. 启动传输(通过外设或软件请求)。
  6. 中断服务程序:当主或备结构传输完成中断发生时,意味着一个缓冲区已满(或已空)。在ISR中:
    • 处理刚满的缓冲区(例如,CPU处理Buffer_A的数据)。
    • 无需手动切换DMAALTSET,硬件会自动在两组控制结构间切换。
    • 确保在处理数据的同时,DMA正在向另一个缓冲区(Buffer_B)填充(或取出)下一批数据。

8.3 常见问题与排查表

问题现象可能原因排查步骤与解决方法
DMA传输完全不启动1. 全局未使能。
2. 通道未使能。
3. 控制表基址未配置或不对齐。
4. 外设请求被屏蔽。
1. 检查DMACFG.MASTEN是否为1。
2. 检查DMAENASET对应位。
3. 检查DMACTLBASE寄存器值,并确认controlTable地址1024字节对齐。
4. 检查DMAREQMASKSET对应位是否为0(未屏蔽)。
传输数据量不对或地址错误1. 控制结构中XFERSIZE计算错误。
2. SRCENDPTR/DSTENDPTR设置错误。
3. 地址增量模式配置错误。
1. XFERSIZE是传输次数。数据总量 = XFERSIZE * 数据宽度(字节)。
2.*ENDPTR应指向最后一个要传输的数据元素之后的位置。例如,传输10个uint32_t,起始地址src,则SRCENDPTR = src + 10*4
3. 确认SRCINC/DSTINC字段与你的数据布局匹配(不变、递增、递减)。
传输中途停止或只进行一次1. 传输模式配置为基础模式(单次)。
2. 乒乓/散聚模式配置错误。
3. 外设请求停止。
1. 检查CONTROL中的XFERMODE字段。需要连续传输应使用Ping-Pong或Auto模式。
2. 乒乓模式需两套结构都设为模式0x3。散聚模式需正确设置任务列表和模式0x5。
3. 检查外设是否持续产生请求(对于外设触发模式)。
系统进入HardFault或总线错误1. DMA访问了非法地址(如Flash写、保留区)。
2. 总线竞争或仲裁问题。
1.首先检查DMAERRCLR.ERRCLR位,若为1则清除之。检查控制结构中的地址值。
2. 检查DMASTAT.STATE是否为0x8(Stalled)。
3. 确保源/目的地址是软件可读/写的有效内存(如SRAM)。
使用乒乓模式时缓冲区覆盖1. CPU处理缓冲区的速度慢于DMA填充速度。
2. 中断处理太慢或丢失。
1. 优化CPU端数据处理算法或增大缓冲区。
2. 确保DMA传输完成中断优先级设置合理,ISR执行时间足够短。可以考虑使用双缓冲指针交换策略,让ISR只负责切换指针。
软件请求(DMASWREQ)无效1. 通道未使能。
2. 通道请求被屏蔽。
1. 确认DMAENASET对应位为1。
2. 确认DMAREQMASKSET对应位为0(允许请求)。
3. 注意:写DMASWREQ后,该位会自动清零,但传输可能尚未开始,需等待通道使能位清零或中断发生。

最后一点经验:μDMA的调试,逻辑分析仪或示波器查看总线信号固然强大,但很多时候,精心放置的断点配合对DMASTAT、DMAENASET、DMAALTSET等寄存器的观察,就能解决大部分问题。尤其是在配置复杂模式时,一步一步单步执行初始化代码,并验证每个关键寄存器是否被写入预期值,是避免低级错误的最有效方法。记住,μDMA是一个强大的协处理器,把它配置对了,它就能默默地为你高效工作,彻底解放CPU。