DMA这三个字母,如果你正在啃408的计算机组成原理,大概率已经在输入输出系统那一章被它绊过一跤。教材上给的定义很干脆——直接存储器存取,数据在内存和外设之间搬来搬去,不用CPU插手。但真到做题的时候,很多人还是分不清它和中断方式到底差在哪,为什么DMA能解放CPU,周期挪用又是怎么个挪法。这篇就把DMA方式从"为什么需要它"到"考试怎么考"完整拆一遍,顺带把那些教材上一笔带过、但做题时处处是坑的细节补上。
1. 从程序查询到DMA:CPU到底被谁拖住了
1.1 三种控制方式的本质区别
I/O设备和主机之间传数据,核心矛盾只有一个:CPU太快,外设太慢。一台主频3GHz的处理器,一个时钟周期大约0.33纳秒,而一个机械硬盘读写一个扇区动辄几毫秒,两者差了将近七个数量级。这个速度鸿沟决定了CPU不能傻等着外设,必须有一套机制来协调。
程序查询方式是最原始的做法。CPU不断读取设备状态寄存器,检查数据是否准备好。设备没准备好就继续查,准备好了就传一个字节或一个字。这种方式的问题显而易见——CPU的时间几乎全耗在"查岗"上,真正干活的时间被严重挤压。你可以把它理解成一个前台接待员,每隔十秒就跑去仓库问货到了没有,来回跑的路上什么正事都干不了。
程序中断方式进了一步。CPU发完I/O命令后就去执行别的程序,设备准备好数据后主动发中断信号通知CPU,CPU暂停当前工作转去处理数据传送。这就像仓库管理员货到了给你打个电话,你再去取。效率提升明显,但每次传送一个字节或一个字都要打断CPU一次,中断处理本身有开销——保存现场、跳转中断服务程序、恢复现场,这些动作加起来可能比传送一个字节本身还费时间。对于高速外设(比如磁盘、网卡)大批量传数据,中断方式的中断开销会大到不可接受。
DMA方式则是彻底换了个思路。既然CPU只是负责"搬砖"这个动作本身不需要动脑子,那就找一个专门的搬运工——DMA控制器(DMAC)来干这件事。CPU只需要告诉DMAC:从哪个设备读、写到内存哪个位置、传多少数据、传完了告诉我一声。剩下的搬运工作DMAC自己完成,CPU该干嘛干嘛去。
1.2 DMA的核心价值:把CPU从搬运工变成指挥官
理解DMA的价值,关键在于区分"数据传送"和"数据处理"这两件事。在程序查询和中断方式下,数据传送这个动作本身是由CPU执行的——数据必须经过CPU的寄存器中转,从设备到CPU再到内存,或者反过来。CPU在这里扮演的是搬运工的角色,虽然中断方式下它只在数据准备好时才搬,但搬这个动作还是它做的。
DMA方式下,数据传送的路径变成了设备↔内存直连,数据不再经过CPU。DMAC接管了地址总线和数据总线的控制权,直接在内存和外设之间开辟一条数据通道。CPU的角色从搬运工升级成了指挥官——它只负责下达命令和接收完成通知,具体的搬运工作全部交给DMAC。
这个变化带来的性能提升是数量级的。以磁盘读取为例,假设一个扇区512字节,中断方式下需要中断512次(每次传一个字节),每次中断开销假设50个时钟周期,总共就是25600个时钟周期纯开销。DMA方式下只需要在开始和结束时各处理一次,中间的数据传送完全由硬件完成,CPU开销几乎可以忽略。
1.3 为什么408特别爱考DMA
翻翻历年408真题,DMA相关的考点出现频率相当高。原因很简单:DMA是I/O控制方式演进的终点,它把前面几种方式的优缺点都串起来了。一道题可以同时考中断和DMA的对比、考周期挪用和停止CPU访存的区别、考DMAC的组成和工作流程、考总线仲裁,知识点密度极大,特别适合出综合题。
而且DMA这个概念在实际工程中无处不在。STM32的串口DMA发送、ADC多通道DMA采集、SPI DMA传输,这些嵌入式开发中的常规操作,底层原理就是408教材上讲的DMAC工作流程。把408的DMA搞透了,看这些实际应用的配置代码会顺畅很多。
2. DMAC内部到底装了些什么
2.1 四个核心寄存器各管什么
DMAC不是一块黑盒,它内部有几个关键寄存器,每个都有明确分工。理解这些寄存器的作用,是搞懂DMA工作流程的基础。
内存地址寄存器(MAR)存放数据在内存中的起始地址。如果是设备到内存的传送,MAR指向数据要写入的内存首地址;如果是内存到设备,MAR指向数据要读出的内存首地址。每传送一个数据,MAR自动加一(或减一),指向下一个存储单元。
设备地址寄存器(DAR)存放I/O设备的地址,也就是设备接口中数据寄存器的端口号。这个地址在传送过程中通常不变,因为数据总是从同一个设备端口读出或写入。
传送长度计数器(WC)记录还需要传送多少个数据。每传送一个数据,WC减一。当WC减到零时,表示传送完成,DMAC向CPU发出中断请求。这个计数器决定了DMA传送的批量大小。
控制与状态寄存器(CSR)存放控制信息和状态信息。控制位包括传送方向(读/写)、是否允许中断、DMA使能等;状态位包括传送完成标志、错误标志等。CPU通过读写这个寄存器来启动DMA、查询状态、响应中断。
考试中经常考的一个细节:MAR和WC在每次传送后都要修改,而DAR通常不变。如果题目问"哪些寄存器在DMA传送过程中需要修改",答案就是MAR和WC。
2.2 DMAC与CPU、内存、设备的连接关系
DMAC在系统中的位置很特殊,它同时连接着三样东西:CPU、内存、I/O设备。但它和CPU之间不是主从关系,而是共享总线的对等关系。这就引出了一个关键问题——总线归谁用。
DMAC需要控制总线才能进行数据传送,而CPU也要用总线取指令、读写数据。两者不能同时使用总线,必须有仲裁机制。常见的做法是DMAC向CPU发送总线请求信号(HOLD),CPU在当前总线周期结束后让出总线控制权,发出总线响应信号(HLDA),DMAC获得总线控制权后开始传送数据,传完后释放总线,CPU重新接管。
这个"让出-接管-释放"的过程,就是DMA传送对CPU最直接的影响。CPU不是完全不受影响,而是在DMA传送期间无法访问内存。这个影响的大小,取决于DMAC采用哪种总线占用方式。
2.3 数据传送方向与工作模式
DMAC支持三种数据传送方向:设备到内存(读操作)、内存到设备(写操作)、内存到内存(某些DMAC支持)。408考试主要考前两种。
设备到内存的流程:设备数据准备好后向DMAC发DMA请求,DMAC向CPU发总线请求,获得总线控制权后,从设备读取数据写入MAR指向的内存单元,MAR加一,WC减一,判断WC是否为零,不为零则继续,为零则释放总线并向CPU发中断。
内存到设备的流程类似,只是数据方向反过来:从MAR指向的内存单元读出数据写入设备,其余步骤相同。
这里有一个容易混淆的点:DMA请求和中断请求是两回事。DMA请求是设备向DMAC发出的,表示"我有数据要传";中断请求是DMAC向CPU发出的,表示"数据传完了"。前者在每个数据传送前都可能发生,后者只在整批数据传送完成后发生一次。
3. 三种DMA传送方式:CPU到底被偷走多少时间
3.1 停止CPU访存:最简单也最霸道
停止CPU访存方式下,DMAC一旦获得总线控制权,就独占总线直到整批数据传送完毕才释放。在这段时间里,CPU完全无法访问内存,只能执行那些不需要访存的指令(比如寄存器运算),实际上大部分时间处于停滞状态。
这种方式的优点是控制简单,DMAC不需要复杂的仲裁逻辑。缺点是CPU被长时间挂起,内存利用率也不高——DMAC传送数据时可能只需要占用部分内存周期,但停止CPU访存方式下整个内存周期都被DMAC占着,浪费了内存带宽。
从数据传送效率看,这种方式适合数据传送速率极高的场景,比如高速磁盘阵列。但在408考试中,它更多是作为一个对比基准出现,用来和周期挪用、周期交替方式做比较。
3.2 周期挪用:偷一个周期还一个周期
周期挪用(也叫周期窃取)是考试中最常考的方式。它的核心思想是:DMAC不独占总线,而是在CPU不使用总线的那些时钟周期里"偷"一个周期来完成一次数据传送。
具体来说,当设备有DMA请求时,DMAC向CPU申请总线。CPU在当前总线周期结束后让出一个总线周期给DMAC,DMAC利用这个周期完成一次数据传送,然后立即释放总线。CPU继续执行下一条指令。如果下一条指令不需要访存,CPU甚至感觉不到总线被偷走过。
这种方式下,DMA传送对CPU的影响被降到最低。每次DMA传送只占用一个内存周期,CPU的执行速度最多降低到原来的几分之一(取决于DMA请求的频率)。但代价是DMAC需要更复杂的控制逻辑,因为每次传送都要重新申请总线。
这里有一个计算题常考的点:如果DMA请求频率很高,CPU可能每个总线周期都要让出一次,此时CPU的性能会下降到接近停止CPU访存方式的水平。所以周期挪用方式下,DMA请求的频率决定了CPU性能的下降程度。
3.3 周期交替:CPU和DMAC轮流坐庄
周期交替方式介于前两者之间。它把时间划分为固定长度的周期块,每个周期块内,一部分时间给CPU访存,一部分时间给DMAC传送数据。比如一个周期块包含4个时钟周期,其中2个给CPU,2个给DMAC,交替进行。
这种方式的好处是CPU和DMAC都有确定的总线使用时间,不会出现某一方被完全饿死的情况。缺点是灵活性差,如果CPU或DMAC在分配给自己的时间段内没有访存需求,这段时间就白白浪费了。
三种方式的对比可以用一个表格来总结:
| 对比维度 | 停止CPU访存 | 周期挪用 | 周期交替 |
|---|---|---|---|
| 总线控制权 | DMAC独占 | 按需申请 | 固定分配 |
| CPU受影响程度 | 最大 | 最小 | 中等 |
| DMAC控制复杂度 | 最简单 | 最复杂 | 中等 |
| 内存利用率 | 最低 | 最高 | 中等 |
| 适用场景 | 高速大批量传送 | 低速随机传送 | 中速规律传送 |
3.4 一个具体的计算例子
假设某系统时钟频率为100MHz,一个总线周期包含4个时钟周期,即总线周期为40ns。CPU执行一条指令平均需要2个总线周期(取指和访存各一次)。现在有一个DMA请求,每次传送一个32位数据,传送速率为每秒500万次。
在周期挪用方式下,每次DMA传送占用一个总线周期(40ns),每秒500万次DMA请求意味着每秒占用500万×40ns=0.2秒的总线时间。也就是说,CPU有20%的时间无法使用总线。如果CPU原本执行一条指令需要80ns,现在由于总线被占用,平均每条指令的执行时间会延长。具体延长多少取决于DMA请求和CPU访存的冲突概率。
这个计算在408真题中经常出现,关键是要区分清楚时钟周期、总线周期、指令周期这几个概念,以及DMA传送占用的是哪个级别的时间单位。
4. DMA与中断的配合:为什么DMA传送完成后还要中断
4.1 DMA不处理异常,中断负责善后
一个常见的困惑是:既然DMA已经解放了CPU,为什么传送完成后还要发中断?直接让CPU轮询状态寄存器不就行了吗?
答案在于效率。如果CPU轮询,它就必须周期性地检查DMAC的状态寄存器,这又回到了程序查询方式的老路。而中断方式下,CPU在DMA传送期间可以完全不管,直到DMAC主动通知它。所以DMA和中断不是替代关系,而是配合关系——DMA负责数据搬运,中断负责通知CPU搬运完成。
更进一步,DMA传送过程中可能出现异常情况,比如设备故障、数据校验错误、总线错误等。这些异常需要CPU介入处理,而DMAC本身没有处理异常的能力,只能通过中断把CPU叫来处理。所以中断在DMA体系中承担的是"异常处理和善后"的角色。
4.2 中断服务程序在DMA流程中的位置
完整的DMA传送流程中,中断服务程序出现在最后一步。以磁盘读取为例:
- CPU初始化DMAC:设置MAR指向内存缓冲区首地址,DAR指向磁盘接口数据端口,WC设置为要读取的字节数,CSR设置传送方向为设备到内存、允许中断。
- CPU启动DMA,然后转去执行其他程序。
- 磁盘控制器从磁盘读取数据,每准备好一个字节(或一个字),向DMAC发DMA请求。
- DMAC向CPU申请总线,获得后从磁盘接口读取数据写入内存,MAR加一,WC减一。
- 重复步骤3-4直到WC减到零。
- DMAC向CPU发中断请求。
- CPU响应中断,执行中断服务程序,检查传送是否成功,处理可能的异常,然后继续原来的程序。
中断服务程序在这里做的事情很少——检查状态、处理异常、通知上层软件数据已就绪。真正耗时的数据搬运已经被DMAC做完了。
4.3 中断优先级与DMA请求的优先级关系
在同时有DMA请求和中断请求的情况下,谁的优先级更高?这个问题在408中经常以选择题形式出现。
一般来说,DMA请求的优先级高于中断请求。原因很直接:DMA请求对应的是数据传送,如果得不到及时响应,数据可能丢失(比如设备的数据寄存器被新数据覆盖);而中断请求对应的是CPU的后续处理,晚一点响应通常不会导致数据丢失。所以当DMAC和CPU同时竞争总线时,总线仲裁器通常优先满足DMAC。
但这个优先级关系不是绝对的。在某些系统中,如果中断请求对应的是紧急事件(比如电源故障),可能会被赋予更高的优先级。408考试中如果没有特别说明,默认DMA请求优先级高于中断请求。
5. 408真题中的DMA考点拆解
5.1 常见题型与解题思路
408中DMA相关题目主要有以下几种类型:
概念辨析题:问DMA方式和中断方式的区别,或者问DMA方式下CPU是否完全不需要干预。这类题的关键是记住DMA的三个"不"——数据不经过CPU、CPU不参与搬运、但CPU仍需初始化和善后。
计算题:给定DMA传送速率、总线周期、CPU指令执行时间等参数,计算CPU性能下降百分比,或者计算DMA传送占用总线的比例。解题关键是理清时间单位,区分时钟周期、总线周期、存取周期。
流程排序题:给出DMA传送的若干步骤,要求排序。这类题需要熟记DMAC的工作流程,特别是总线请求和DMA请求的先后顺序。
寄存器功能题:问MAR、WC、DAR、CSR各自的作用,或者问传送过程中哪些寄存器需要修改。
5.2 一道典型真题的完整分析
以某年408真题为例(题目大意):某系统采用周期挪用方式DMA,CPU主频500MHz,CPI为4(即每条指令平均4个时钟周期),DMA传送速率为每秒2MB,每次DMA传送4字节。求CPU用于DMA的时间比例。
解题步骤:
- 计算DMA传送次数:每秒2MB ÷ 4字节 = 500K次/秒。
- 每次DMA传送占用一个总线周期。假设一个总线周期等于一个时钟周期(简化处理),则每次占用2ns。
- DMA每秒占用总线时间:500K × 2ns = 1ms。
- CPU每秒总时间:1秒 = 1000ms。
- CPU用于DMA的时间比例:1ms / 1000ms = 0.1%。
如果题目进一步问CPU性能下降多少,则需要考虑DMA占用总线时CPU是否完全停滞。在周期挪用方式下,如果CPU恰好不需要访存,则性能不受影响;如果需要访存,则被延迟。实际计算中通常简化为CPU性能下降比例等于DMA占用总线比例。
5.3 容易踩的坑
第一个坑:混淆DMA请求和中断请求。DMA请求是设备发给DMAC的,中断请求是DMAC发给CPU的。考试中经常把这两个概念对调来迷惑考生。
第二个坑:忽略DMA传送前的初始化开销。有些题目问"DMA方式下CPU完全不参与数据传送,对吗?"答案是错的,因为CPU需要初始化DMAC(设置寄存器),传送完成后还需要处理中断。
第三个坑:周期挪用方式下,DMA传送占用的是总线周期还是时钟周期。这取决于题目给出的条件。如果题目说"每次DMA传送占用一个总线周期",那就用总线周期计算;如果说"占用一个时钟周期",就用时钟周期计算。审题时务必看清。
第四个坑:DMA传送过程中MAR和WC的修改时机。是在传送前修改还是传送后修改?标准流程是:传送一个数据后,MAR加一,WC减一,然后判断WC是否为零。所以判断WC是否为零是在修改之后进行的。
6. 从408到实际工程:DMA在嵌入式中的真实样子
6.1 STM32串口DMA发送的配置逻辑
学408的时候可能觉得DMA是个抽象概念,但如果你用过STM32的HAL库配置串口DMA发送,会发现教材上的DMAC寄存器在代码里都有对应。
以STM32F4的串口DMA发送为例,配置流程大致如下:
// 1. 使能DMA时钟和串口时钟 __HAL_RCC_DMA1_CLK_ENABLE(); __HAL_RCC_USART1_CLK_ENABLE(); // 2. 配置DMA流 hdma_usart1_tx.Instance = DMA1_Stream6; hdma_usart1_tx.Init.Channel = DMA_CHANNEL_4; hdma_usart1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; // 内存到外设 hdma_usart1_tx.Init.PeriphInc = DMA_PINC_DISABLE; // 外设地址不变 hdma_usart1_tx.Init.MemInc = DMA_MINC_ENABLE; // 内存地址递增 hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; hdma_usart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; hdma_usart1_tx.Init.Mode = DMA_NORMAL; // 普通模式,传完停止 hdma_usart1_tx.Init.Priority = DMA_PRIORITY_HIGH; HAL_DMA_Init(&hdma_usart1_tx); // 3. 关联DMA到串口 __HAL_LINKDMA(&huart1, hdmatx, hdma_usart1_tx); // 4. 启动DMA发送 HAL_UART_Transmit_DMA(&huart1, buffer, length);对照408的知识点:Direction对应CSR中的传送方向位,PeriphInc和MemInc对应MAR和DAR是否递增,Mode对应是否循环传送,Priority对应总线仲裁优先级。教材上的抽象概念在这里全部落地了。
6.2 DMA缓冲区的双缓冲机制
实际工程中,DMA传送经常配合双缓冲使用。原因很简单:如果只有一个缓冲区,DMA正在往缓冲区写数据时,CPU不能读这个缓冲区,否则会读到不完整的数据。双缓冲机制下,DMA写缓冲区A时CPU读缓冲区B,DMA写完后切换,CPU读A,DMA写B,如此交替。
这个机制在408教材中通常不涉及,但它是DMA在实际系统中发挥威力的关键。STM32的DMA支持双缓冲模式(DMA_MODE_CIRCULAR配合两个内存地址),可以在不中断数据流的情况下实现连续采集。
6.3 DMA传送完成中断的实际处理
在STM32中,DMA传送完成会触发中断,对应408中讲的"DMAC向CPU发中断请求"。中断服务程序通常做这几件事:
void DMA1_Stream6_IRQHandler(void) { if (__HAL_DMA_GET_FLAG(&hdma_usart1_tx, DMA_FLAG_TCIF6)) { __HAL_DMA_CLEAR_FLAG(&hdma_usart1_tx, DMA_FLAG_TCIF6); // 传送完成,通知上层应用 dma_tx_complete_callback(); } }这段代码和408中描述的中断服务程序做的事情完全一致:检查状态标志、清除标志、执行善后处理。区别只在于408用文字描述,这里用代码实现。
7. 几个反复被问到的细节问题
7.1 DMA方式下CPU和DMAC会同时访存吗
不会。DMA传送和CPU访存都需要使用内存总线,而内存总线在同一时刻只能被一个主设备控制。所以DMAC获得总线控制权时,CPU无法访存;CPU使用总线时,DMAC必须等待。这正是周期挪用方式下"偷周期"的由来——DMAC只能在CPU不使用总线的间隙插入自己的传送。
但有一种例外情况:如果系统采用多端口存储器(比如双端口RAM),内存有多个访问端口,CPU和DMAC可以同时访问不同的端口。这种设计在高端系统中存在,但408考试中默认单端口存储器,CPU和DMAC不能同时访存。
7.2 DMA传送是否影响CPU的指令执行
影响程度取决于DMA传送方式。停止CPU访存方式下,CPU完全无法访存,只能执行寄存器运算类指令,实际上大部分时间停滞。周期挪用方式下,CPU只在DMA传送的那个总线周期被延迟,其他时间正常执行。周期交替方式下,CPU在分配给自己的时间段内正常执行,在DMAC的时间段内停滞。
从指令执行的角度看,DMA传送影响的是需要访存的指令(取指、读写数据),不影响纯寄存器运算指令。但现代CPU中取指本身就需要访存,所以实际上几乎所有指令都会受到不同程度的影响。
7.3 DMA传送的优先级一定高于中断吗
不一定,但通常如此。DMA请求的紧迫性来自数据可能丢失的风险——如果设备的数据寄存器被新数据覆盖,旧数据就丢了。中断请求的紧迫性来自事件的时效性,但大多数情况下晚几个周期处理不会造成数据丢失。所以系统设计时通常给DMA更高的总线优先级。
但在某些实时系统中,如果某个中断对应的是紧急事件(比如故障保护),可能会通过总线仲裁器给中断更高的优先级。408考试中如果没有特别说明,默认DMA优先级高于中断。
7.4 为什么DMA传送不需要CPU参与,却还需要CPU初始化
因为DMAC本身没有智能,它不知道要传什么数据、传到哪里、传多少。这些信息必须由CPU通过程序设置到DMAC的寄存器中。CPU初始化DMAC的过程,本质上是在告诉DMAC"做什么",而DMAC执行传送的过程是"怎么做"。CPU负责决策,DMAC负责执行。
这就像你给快递员一个包裹和地址,快递员负责送,但送什么、送到哪是你决定的。DMA传送完成后,CPU还需要处理中断,相当于确认快递是否送达、有没有损坏。
7.5 周期挪用方式下DMA请求的频率上限是多少
理论上,如果DMA请求频率等于总线周期频率,即每个总线周期都有DMA请求,那么CPU每个总线周期都要让出总线,此时CPU的性能下降到接近停止CPU访存方式。但实际上,DMA请求频率受限于设备的传送速率,通常远低于总线频率。
以磁盘为例,假设磁盘传送速率为100MB/s,每次DMA传送4字节,则DMA请求频率为25M次/秒。如果总线周期为10ns(100MHz),则总线周期频率为100M次/秒。DMA请求频率25M次/秒,意味着每4个总线周期才有一次DMA请求,CPU有75%的总线周期可以使用。这个比例在实际系统中是可以接受的。
8. 把DMA放进整个I/O体系里看
8.1 DMA在I/O控制方式演进中的位置
I/O控制方式的演进路线是:程序查询→程序中断→DMA→通道→I/O处理机。每一步都在减少CPU对I/O操作的介入程度。
程序查询方式下,CPU全程参与,效率最低。程序中断方式下,CPU只在数据传送时介入,但每次传送一个字节或一个字都要介入一次。DMA方式下,CPU只在整批数据传送前后介入,中间完全不参与。通道方式下,CPU只需要发一条I/O指令,通道自己执行通道程序完成整批数据的传送,CPU介入程度进一步降低。I/O处理机方式下,I/O处理机是一台独立的处理器,有自己的指令系统,可以执行完整的I/O程序,CPU几乎完全不介入。
DMA在这个演进链条中处于中间位置——它解决了数据搬运的效率问题,但没有解决I/O控制的智能化问题。通道和I/O处理机则进一步把控制逻辑也从CPU手中接管了。
8.2 DMA与通道的区别
通道本质上是一个简化版的处理器,它能执行通道程序(由通道指令组成),控制多台设备的I/O操作。DMA控制器只能控制一台或少数几台设备,且只能执行固定的传送操作,不能执行程序。
从408考试的角度,DMA和通道的区别主要体现在:DMA是硬件控制器,通道是处理器;DMA控制单台设备,通道控制多台设备;DMA执行固定操作,通道执行通道程序。这些区别在选择题中经常出现。
8.3 DMA在现代计算机中的位置
现代计算机中,DMA已经无处不在。显卡通过DMA与内存交换纹理数据,网卡通过DMA收发网络包,硬盘通过DMA读写数据,甚至CPU内部的一些加速器也通过DMA与内存交互。可以说,没有DMA,现代计算机的I/O性能会倒退几个数量级。
408教材中讲的DMA是最基本的模型,实际系统中的DMA控制器要复杂得多——支持分散-聚集(scatter-gather)、支持多通道、支持优先级仲裁、支持错误纠正等。但核心原理没有变:CPU下达命令,DMAC执行搬运,完成后中断通知CPU。
我在实际调试STM32的ADC多通道DMA采集时,最深的体会是:DMA配置中最容易出错的地方不是寄存器设置,而是缓冲区对齐和传送长度的匹配。如果缓冲区没有按数据宽度对齐,或者传送长度设置错误,DMA会静默地传错数据,而且不会报错。这种问题在408考试中不会遇到,但在实际工程中非常常见。所以每次配置DMA,我都会先检查这三个参数:源地址、目的地址、传送长度,确保它们和数据宽度、缓冲区大小完全匹配。