news 2026/9/28 20:04:09

DMA原理详解:从408考研到STM32嵌入式实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
DMA原理详解:从408考研到STM32嵌入式实战

1. 从一道408真题说起:DMA到底在考什么

如果你正在啃计算机组成原理,尤其是唐朔飞或者白中英那套教材,翻到I/O那一章的时候,大概率会被一堆控制方式绕晕:程序查询、程序中断、DMA、通道……名字听着都懂,但一到做题就分不清谁是谁。2024年408那道第45题考的就是DMA,很多人栽在“周期挪用”和“停止CPU访存”这两个概念的细节上。

DMA,全称Direct Memory Access,直接存储器访问。说白了,它就是一个“搬砖队长”——数据在主存和I/O设备之间搬运这件事,以前是CPU亲自一箱一箱扛,现在CPU说“我太忙了,找个专职搬运工吧”,这个搬运工就是DMA控制器。CPU只需要告诉它:从哪搬、搬到哪、搬多少、搬完了喊我一声。剩下的具体搬运过程,DMA控制器自己搞定,CPU该干嘛干嘛去。

这篇文章我打算把DMA方式从“为什么需要它”到“具体怎么工作”再到“考试怎么考、实际怎么用”完整捋一遍。不管你是正在准备408考研的学生,还是学STM32时被串口DMA、ADC多通道DMA搞得头大的嵌入式新手,又或者只是想把计算机组成原理里这块知识补扎实的开发者,这篇内容都能让你把DMA这件事彻底搞明白。我会尽量用生活化的类比把原理讲透,同时把408考试里那些容易踩的坑、常考的细节都标出来。

2. 为什么会有DMA:三种I/O控制方式的进化逻辑

2.1 从“死等”到“打断”再到“专职搬运”

要理解DMA,得先知道它前面两代方案差在哪。

程序查询方式是最原始的。CPU给I/O设备发个命令,然后就在那儿循环检查状态寄存器——“好了没?好了没?好了没?”设备没准备好,CPU就一直在那空转。这就好比你点了外卖,然后站在门口一直盯着猫眼等,啥也干不了。效率极低,CPU和I/O设备完全串行工作。

程序中断方式进了一步。CPU发完命令就去干别的事了,设备准备好之后主动发一个中断信号给CPU,CPU收到中断后暂停手头的活,转去处理数据传送。这就像外卖到了骑手给你打电话,你放下手头的事去拿。比死等强多了,但每次传送一个字节或一个字都要打断CPU一次。如果传1MB数据,按每次传4字节算,那就是26万次中断。CPU光忙着响应中断、保存现场、恢复现场了,真正干活的时间被切得稀碎。

DMA方式的思路完全不同。它不是“一个字节一个字节地打断CPU”,而是“整块整块地搬,搬完了再说”。CPU只需要在开始的时候做一次初始化配置,然后DMA控制器接管总线,直接在内存和I/O设备之间开一条数据通道。数据搬完了,DMA控制器再发一个中断告诉CPU“活干完了”。整个过程中,CPU只在开头和结尾参与,中间完全不用管。

这三种方式的进化逻辑其实就一条主线:让CPU越来越少地参与数据搬运的具体过程。程序查询是CPU全程参与,程序中断是CPU频繁参与,DMA是CPU几乎不参与。再往后还有通道方式,那是更高级的形态,连DMA控制器的初始化都能批量处理,这里不展开。

2.2 DMA的核心价值:解放CPU

DMA最核心的价值就四个字:解放CPU。在需要大量数据高速传送的场景下,比如磁盘读写、网络数据包收发、图像采集、音频播放,数据量动辄几KB到几MB,如果还用中断方式一个字节一个字节地传,CPU基本上就被绑死了。

我拿STM32上的实际场景举个例子。你用ADC采集8个通道的模拟量,采样率设到100kHz,每个通道每次采12位数据。如果用中断方式,每采一个点就进一次中断,100kHz就是每秒10万次中断。STM32的主频就算跑到168MHz,光处理中断上下文切换就够呛,根本没时间跑你的主循环逻辑。但换成DMA方式,ADC采完的数据自动通过DMA搬到内存数组里,你只需要在DMA传输完成中断里处理一批数据就行了。CPU占用率从接近100%直接降到个位数。

这就是DMA存在的意义:把CPU从繁重的数据搬运工作中解放出来,让它专注于计算和控制。

2.3 DMA与中断的本质区别

很多人学到这里会有一个疑问:DMA和中断到底有什么本质区别?不都是CPU不用一直等着吗?

区别在于谁来搬数据。中断方式下,数据传送本身还是CPU在执行中断服务程序时完成的——CPU执行指令,把数据从I/O接口读到寄存器,再写到内存。DMA方式下,数据传送是由DMA控制器这个硬件直接完成的,CPU根本不碰数据。CPU只是“授权”DMA控制器使用总线,然后就不管了。

打个比方。中断方式就像你请了个助理,但每次搬东西还是你自己动手,助理只负责提醒你“该搬了”。DMA方式就像你请了个搬运工,你告诉他“把这堆货从A搬到B”,然后你就可以去开会了,搬运工自己推着车一趟一趟搬,搬完了跟你说一声。

这个区别直接决定了:中断方式下,每传一个数据单位都要执行若干条指令,速度受限于CPU执行指令的速度;DMA方式下,数据传送由硬件直接控制,速度可以接近总线的极限带宽。

3. DMA控制器的内部结构与工作原理

3.1 DMA控制器的核心组成

DMA控制器不是随便就能当搬运工的,它内部有一套完整的逻辑。一个典型的DMA控制器包含以下关键部件:

地址寄存器:包括内存地址寄存器和设备地址寄存器。内存地址寄存器存放当前要访问的内存地址,每传一个数据就自动加一(或减一)。设备地址寄存器存放I/O设备的接口地址。

字计数器:记录还剩多少数据没传。初始化时填入要传送的总字数,每传一个字自动减一,减到零就表示传完了,发出中断信号。

控制逻辑:负责解析CPU发来的控制命令,管理DMA请求和总线应答的时序,决定什么时候占用总线、什么时候释放总线。

状态寄存器:记录DMA控制器当前的状态,比如是否正在传输、是否出错、是否完成等。

数据缓冲寄存器:在内存和I/O设备之间做临时缓冲,协调两边速度差异。

这些部件协同工作,让DMA控制器能够独立完成数据搬运任务。CPU在初始化阶段把源地址、目的地址、传送长度、传送方向等信息写入DMA控制器的寄存器,然后启动DMA。之后DMA控制器就按照这些参数自动执行。

3.2 DMA的工作流程拆解

DMA的完整工作流程可以分成三个阶段:

第一阶段:初始化。CPU执行一段程序,把DMA控制器需要的参数写进去。具体包括:内存起始地址、I/O设备地址、传送字数、传送方向(读还是写)、是否开启中断等。这一步CPU是主动参与的,但只做一次。

第二阶段:数据传送。DMA控制器向CPU发出总线请求(HOLD信号),CPU在当前总线周期结束后响应,发出总线允许信号(HLDA),把总线控制权交给DMA控制器。DMA控制器获得总线控制权后,直接在内存和I/O设备之间传送数据。每传一个字,地址寄存器加一,字计数器减一。这个过程可能持续很多个总线周期。

第三阶段:结束处理。当字计数器减到零,DMA控制器释放总线,向CPU发出中断请求。CPU响应中断,执行中断服务程序,检查传送是否成功,然后进行后续处理。

这里有一个关键细节:DMA控制器占用总线的方式。它不是一直霸占着总线不放,而是每次传送一个数据单位就释放一次总线,或者传完一组数据后释放。具体采用哪种方式,取决于DMA控制器的类型和工作模式。

3.3 三种DMA传送方式:停止CPU访存、周期挪用、交替访问

这是408考试的高频考点,也是很多人容易搞混的地方。

停止CPU访存方式:DMA控制器要传数据的时候,直接向CPU发一个信号,要求CPU暂停使用总线。CPU收到信号后,在当前总线周期结束后交出总线控制权,DMA控制器开始连续传送一整块数据,传完之后再把总线还给CPU。这种方式下,DMA传送期间CPU完全不能访存,只能做那些不需要访问内存的操作(比如执行寄存器运算)。优点是控制简单,适合数据量很大的情况;缺点是CPU被“冻住”了一段时间,影响CPU效率。

周期挪用方式:也叫周期窃取。DMA控制器每次只“偷”一个总线周期来传一个数据,传完立刻还给CPU。如果CPU正在使用总线,DMA控制器就等一个周期;如果CPU不用总线(比如CPU正在执行不需要访存的指令),DMA控制器就趁机传一个数据。这种方式对CPU的影响最小,因为CPU只是在偶尔需要访存的时候被“插队”了一下。缺点是DMA控制器的控制逻辑更复杂,而且每个数据传送都要经历一次总线请求和应答的过程,效率相对低一些。

交替访问方式:把总线时间分成固定的时间片,一部分给CPU用,一部分给DMA用,两者交替使用总线,互不干扰。这种方式不需要总线请求和应答的过程,效率高,但需要更复杂的时序控制,实际中用得不多。

传送方式CPU影响控制复杂度适用场景
停止CPU访存大,CPU完全停止访存简单数据量大、高速传送
周期挪用小,CPU偶尔等待较复杂一般场景,最常用
交替访问无,CPU和DMA分时使用最复杂对时序要求严格的场景

考试里经常考的是:周期挪用方式下,DMA控制器和CPU争用总线的优先级问题。一般来说,DMA请求的优先级高于CPU访存,因为I/O设备的数据传送有实时性要求,如果数据没及时取走可能会丢失。但CPU的指令执行不能被打断太久,所以DMA也不能无限期占用总线。

4. DMA与CPU的协作细节:总线仲裁与优先级

4.1 总线请求与应答的完整时序

DMA控制器要使用总线,必须经过一套“申请-批准”的流程。这套流程的时序在408考试里经常以选择题或大题的形式出现。

当DMA控制器准备好传送数据时,它会向CPU发出总线请求信号(通常叫HOLD或BR)。CPU收到请求后,不会立刻响应,而是等当前总线周期结束。为什么要等?因为CPU可能正在执行一条需要访存的指令,如果中途被打断,指令执行就不完整了。所以CPU会在当前总线周期完成后,发出总线允许信号(HLDA或BG),同时把地址总线、数据总线和控制总线置为高阻态,让出总线控制权。

DMA控制器收到HLDA信号后,获得总线控制权,开始传送数据。传送完成后,DMA控制器释放总线,撤销HOLD信号。CPU检测到HOLD信号撤销后,重新获得总线控制权,继续执行被暂停的操作。

这个过程中有一个容易忽略的细节:CPU在发出HLDA信号后,并不是完全停止工作。CPU内部的一些操作(比如寄存器之间的运算、指令译码)可以继续进行,只是不能访问内存。这就是为什么停止CPU访存方式下,CPU并不是“死机”,只是“不能访存”。

4.2 DMA请求的优先级为什么高于CPU访存

这个问题在考试里经常以“为什么DMA请求优先级高于CPU访存请求”的形式出现。答案的核心在于数据丢失的风险。

I/O设备的数据传送往往有实时性要求。比如磁盘读出的数据,如果不及时取走,下一批数据来了就会覆盖掉;比如ADC采样的数据,如果不及时搬走,下一次采样就会覆盖上一次的结果。而CPU访存请求晚一点处理,顶多是CPU执行慢一点,不会导致数据丢失。所以DMA请求的优先级必须高于CPU访存请求。

但这里有一个平衡:DMA也不能无限期占用总线。如果DMA一直霸占总线,CPU就无法取指令、无法读写数据,整个系统就卡住了。所以实际设计中,DMA控制器通常会在传送完一个数据块后主动释放总线,给CPU一个喘息的机会。

4.3 DMA与中断的配合使用

DMA和中断不是互斥的,而是配合使用的。DMA负责数据传送,中断负责传送完成后的通知。

具体来说,DMA控制器在传送完指定数量的数据后,会向CPU发出一个中断请求。CPU响应这个中断,执行相应的中断服务程序。这个中断服务程序通常做这些事情:检查DMA状态寄存器确认传送是否成功、处理传送过程中可能出现的错误、准备下一次DMA传送的参数、通知上层软件数据已经就绪。

这种配合方式的好处是:CPU不需要在数据传送过程中频繁介入,只需要在传送完成后处理一次。对于大批量数据传送,效率提升非常明显。

在STM32的实际开发中,DMA传输完成中断是最常用的中断之一。比如你用串口DMA发送一帧数据,配置好DMA之后调用发送函数,然后就可以去处理其他任务了。当DMA把整帧数据都发送完毕后,触发传输完成中断,你在中断里可以置一个标志位或者启动下一次发送。整个过程CPU只在开头配置和结尾处理时参与,中间完全不占用。

5. 408考试中DMA的高频考点与解题套路

5.1 周期挪用方式下的总线占用计算

这是408大题里经常出现的计算题类型。题目通常会给出:CPU主频、总线周期、DMA传送一个数据需要的时间、数据传送量等参数,让你计算DMA传送期间CPU实际可用于访存的时间比例。

解题的关键是搞清楚周期挪用方式下,DMA每次只占用一个总线周期。假设CPU的主频为f,一个总线周期为T,DMA传送一个数据需要一个总线周期。如果DMA要传送N个数据,那么DMA总共需要N个总线周期。在这N个总线周期里,CPU无法访存。但CPU并不是完全不能工作,它可以在DMA不占用总线的那些周期里正常访存。

具体计算时要注意:DMA请求和CPU访存请求可能同时发生,这时候DMA优先。所以实际CPU可用的总线周期数 = 总周期数 - DMA占用的周期数。如果题目还给出了CPU访存概率(比如CPU有50%的指令需要访存),那计算会更复杂一些。

我拿一道典型题目举例:CPU主频500MHz,总线周期为2个时钟周期,DMA传送一个数据需要一个总线周期。现在要用DMA传送1000个数据,求DMA传送期间CPU可用于访存的时间比例。

解题思路:总线周期 = 2 / 500MHz = 4ns。DMA传送1000个数据需要1000个总线周期 = 4000ns。在这4000ns内,CPU的总线周期数也是1000个(因为总线周期相同)。DMA占用了1000个总线周期中的1000个?不对,这里要仔细。DMA每传送一个数据占用一个总线周期,传送1000个数据占用1000个总线周期。但CPU在这段时间内也有1000个总线周期可用。如果DMA和CPU争用总线,DMA优先,那么CPU实际可用的总线周期数 = 1000 - 1000 = 0?这显然不对。

问题出在:DMA传送1000个数据并不是在1000个连续的总线周期内完成的。DMA控制器发出请求后,CPU响应需要时间,DMA获得总线后传送一个数据,然后释放总线。下一个数据又要重新请求。所以实际的时间线是:DMA请求 -> CPU响应 -> DMA传送 -> DMA释放 -> CPU使用总线 -> DMA再次请求……这样交替进行。

在周期挪用方式下,DMA传送一个数据后释放总线,CPU至少可以获得一个总线周期来访存(如果CPU有访存需求的话)。所以CPU可用于访存的时间比例取决于DMA请求的频率和CPU访存的需求。如果DMA连续不断地请求,CPU可能只能获得很少的总线周期。

这类题目的标准解法是:先算出DMA传送一个数据的平均时间间隔,再算出在这个间隔内CPU可以使用的总线周期数,最后求比例。具体计算要看题目给出的条件,关键是理解“周期挪用”的含义——DMA每次只借一个周期,借完就还。

5.2 DMA传送过程的中断次数计算

另一个高频考点是:用DMA方式传送一批数据,总共会产生多少次中断?

答案通常是一次。因为DMA控制器在传送完所有数据后才发一次中断。但要注意题目中的细节:如果题目说“每传送一个数据块就中断一次”,那就要看数据块的大小。比如总共传1MB数据,DMA每次最多传4KB,那就是256次中断。

还有一种情况:题目问的是“DMA传送过程中CPU被中断的次数”。如果DMA采用停止CPU访存方式,CPU在DMA传送期间完全不参与,传送完成后才被中断一次。如果采用周期挪用方式,CPU在DMA传送期间可能被“插队”多次,但这些不是中断,只是总线周期的让出。中断仍然只有传送完成后的那一次。

考试里经常把“总线请求次数”和“中断次数”混在一起考。总线请求次数可能很多(每次DMA传送一个数据都要请求一次总线),但中断次数只有一次(传送完成后)。这两个概念要分清楚。

5.3 DMA与中断方式的对比分析题

这类题目通常以简答题或综合分析题的形式出现,要求比较DMA和中断方式在数据传送上的区别。答题时要抓住几个核心维度:

数据传送的发起者:中断方式下,数据传送由CPU执行中断服务程序完成;DMA方式下,数据传送由DMA控制器硬件完成。

CPU的参与程度:中断方式下,每传一个数据CPU都要介入;DMA方式下,CPU只在初始化和结束时介入。

传送速度:中断方式受限于CPU执行指令的速度;DMA方式受限于总线带宽,通常更快。

适用场景:中断方式适合数据量小、速度要求不高的场景;DMA方式适合数据量大、速度要求高的场景。

对CPU的影响:中断方式下CPU频繁被打断,效率低;DMA方式下CPU几乎不受影响,效率高。

答题时最好能结合具体的例子来说明,比如“磁盘读写用DMA,键盘输入用中断”,这样更有说服力。

6. 从408到实战:DMA在嵌入式开发中的典型应用

6.1 STM32串口DMA收发:从配置到调试

学408的时候觉得DMA是个抽象概念,但到了STM32上,DMA是实打实要配置的。我拿串口DMA收发举个例子,这是嵌入式开发中最常见的DMA应用场景。

用STM32CubeMX配置串口DMA的步骤大致是这样的:先使能串口,然后在DMA Settings里添加DMA请求。串口发送对应DMA通道的Memory-to-Peripheral模式,串口接收对应Peripheral-to-Memory模式。优先级一般设中等或高,数据宽度根据串口数据格式设8位或16位。模式选择Normal(单次传输)还是Circular(循环传输),取决于你的应用场景。

配置完成后生成代码,在main函数里调用HAL_UART_Transmit_DMA()就可以启动DMA发送。这个函数会把数据地址、长度等信息写入DMA控制器,然后立刻返回,不阻塞CPU。你可以接着执行其他任务。当DMA发送完成后,会触发DMA传输完成中断,在中断回调函数里可以置标志位或者启动下一次发送。

这里有几个实操中容易踩的坑。第一个坑是DMA传输完成中断和串口发送完成中断的区别。DMA传输完成中断表示DMA已经把数据从内存搬到了串口数据寄存器,但串口可能还在发送最后一个字节。如果要确保数据完全发送完毕,应该用串口的TC(Transmission Complete)中断,而不是DMA的传输完成中断。我当初就因为这个坑,在DMA传输完成中断里立刻切换了RS485的收发方向,结果最后一个字节没发完就被截断了。

第二个坑是DMA缓冲区的生命周期。DMA传输是异步的,你传给DMA的缓冲区指针在传输完成之前必须保持有效。如果你在栈上定义了一个局部数组,然后调用DMA发送函数,函数返回后栈被回收,DMA还在往那个地址搬数据,就会出问题。所以DMA缓冲区一定要用全局数组或者静态数组,或者用动态内存分配并确保在传输完成前不被释放。

第三个坑是DMA和CPU同时访问同一块内存的冲突。如果DMA正在往某个数组里写数据,CPU同时去读这个数组,可能会读到半新半旧的数据。解决办法是用双缓冲或者乒乓缓冲,DMA写一块的时候CPU读另一块,通过中断切换。

6.2 ADC多通道采集+DMA:解放CPU的经典案例

ADC多通道采集是DMA的另一个经典应用。STM32的ADC可以配置成扫描模式,依次采集多个通道。如果不用DMA,每采完一个通道就要进一次中断读取数据,CPU占用率很高。用DMA之后,ADC每采完一个通道,DMA自动把数据搬到内存数组里,采完所有通道后触发一次DMA传输完成中断。

配置要点:ADC配置成扫描模式、连续转换模式(或者由定时器触发),DMA配置成Circular模式,这样DMA会循环搬运,不需要每次重新启动。数据宽度设为半字(16位),因为ADC结果是12位的,用16位存储方便对齐。

这里有一个细节:ADC的DMA请求是在每次转换完成后发出的。如果ADC配置成连续转换模式,DMA会连续不断地搬运数据。如果配置成单次转换模式,每次转换完成后DMA搬一次,然后需要软件再次启动ADC。实际项目中,通常用定时器触发ADC转换,这样采样率精确可控,DMA在后台默默搬运,CPU只需要定期处理数据数组就行了。

我做过一个项目,用STM32F4的ADC采集三相电流电压,6个通道,采样率20kHz。用DMA搬运数据,CPU占用率不到5%。如果换成中断方式,20kHz的采样率,每采一个通道进一次中断,6个通道就是120kHz的中断频率,CPU基本上什么都干不了。

6.3 DMA传输中的常见问题与排查思路

DMA用起来爽,但出问题的时候也让人头疼。我整理了几个常见问题和排查思路。

问题一:DMA传输不启动。排查步骤:检查DMA时钟是否使能(很多人忘了开DMA控制器的时钟)、检查DMA通道是否配置正确、检查外设的DMA请求是否使能、检查DMA传输方向是否正确。

问题二:DMA传输的数据不对。排查步骤:检查源地址和目的地址是否正确、检查数据宽度是否匹配(比如外设是8位数据,DMA配成了16位,就会出错)、检查地址是否递增(有些外设的地址是固定的,不能递增)、检查DMA缓冲区的对齐方式。

问题三:DMA传输完成中断不触发。排查步骤:检查中断是否使能、检查NVIC中的中断优先级配置、检查DMA传输完成标志是否被清除、检查DMA模式是Normal还是Circular(Circular模式下传输完成中断的行为不同)。

问题四:DMA和CPU争用总线导致系统卡顿。排查步骤:检查DMA的优先级配置、考虑使用周期挪用方式而不是停止CPU访存方式、优化DMA传输的数据块大小,避免一次传输太长时间。

问题现象可能原因排查方法
DMA不启动时钟未使能、通道配置错误检查RCC配置、检查DMA通道映射
数据错误地址错误、数据宽度不匹配检查源/目的地址、检查数据对齐
中断不触发中断未使能、标志未清除检查NVIC配置、检查中断标志位
系统卡顿DMA优先级过高、传输块太大调整优先级、减小传输块大小

7. DMA方式的知识边界与常见误区

7.1 DMA能替代中断吗

不能。DMA和中断解决的是不同的问题。DMA解决的是“数据怎么搬”的问题,中断解决的是“事情发生了怎么通知”的问题。DMA传送完成后,还是需要通过中断来通知CPU。而且不是所有I/O设备都适合用DMA,比如键盘、鼠标这种低速设备,数据量小,用中断就够了,上DMA反而是杀鸡用牛刀。

7.2 DMA传送一定比中断快吗

不一定。DMA的优势在于大批量数据传送时CPU占用率低,但单次传送的延迟不一定比中断低。因为DMA需要总线请求和应答的过程,如果数据量很小,这个开销可能比直接中断处理还大。所以选择哪种方式,要看数据量和实时性要求。

7.3 DMA控制器能同时处理多个设备吗

一个DMA控制器通常有多个通道,可以同时处理多个设备的DMA请求。但同一时刻只有一个通道能获得总线控制权。多个通道之间需要仲裁,优先级高的通道先获得服务。在STM32中,DMA1和DMA2各有多个通道,每个通道可以独立配置,但同一时刻只有一个通道在传输。

7.4 学了408的DMA,在实际开发中有什么用

这个问题我被问过很多次。408里讲的DMA原理是通用的,虽然具体的寄存器配置和硬件细节跟STM32不完全一样,但核心概念是一样的:地址寄存器、字计数器、总线请求、周期挪用、传输完成中断。理解了这些概念,再看STM32的DMA配置手册,就会发现只是换了个名字而已。而且408考试里那些计算题,训练的是你对总线时序和系统性能的分析能力,这种能力在实际做嵌入式性能优化时非常有用。

8. 我踩过的DMA坑与实操心得

最后分享几个我在实际项目中使用DMA时踩过的坑,都是教材上不会写的。

第一个坑:DMA传输完成中断里不能做耗时操作。DMA传输完成中断通常频率不低,如果中断服务程序里做了太多事情,会影响其他中断的响应。我一般只在中断里置一个标志位,具体处理放到主循环里做。

第二个坑:DMA缓冲区的Cache一致性问题。如果你的MCU有Cache(比如STM32H7系列),DMA直接访问内存时可能绕过Cache,导致CPU读到的是Cache里的旧数据。解决办法是在DMA传输前后做Cache清理或无效化操作。这个问题在F4系列上不存在(F4没有Cache),但到了H7上就必须考虑。

第三个坑:DMA和中断的优先级配置。DMA传输完成中断的优先级不能设得太低,否则可能被其他中断阻塞,导致数据处理不及时。但也不能设得太高,否则会影响其他关键中断。我一般把DMA中断设成中等优先级,具体要看系统里有哪些中断源。

第四个坑:DMA传输长度寄存器的位宽限制。STM32的DMA传输长度寄存器通常是16位的,最大传输长度是65535。如果要传的数据超过这个数,需要分多次传输。我当初传一张240x320的RGB565图片,数据量是153600字节,超过了65535,结果DMA只传了一部分就停了。后来改成每次传一行或者用双缓冲才解决。

第五个坑:DMA请求的使能时机。有些外设的DMA请求需要在使能外设之前配置好,有些则相反。比如STM32的ADC,需要先配置DMA,再使能ADC的DMA请求,最后启动ADC转换。顺序搞错了DMA就不会工作。这个在参考手册里写得很清楚,但初学者容易忽略。

DMA这个东西,理论上学一遍,实际用一遍,再回头看看408的题目,会发现那些概念都变得很具体。唐朔飞教材里讲的“周期挪用”“停止CPU访存”,在STM32的参考手册里就是DMA模式配置和优先级设置。白中英教材里讲的“DMA控制器组成”,在STM32里就是DMA_HandleTypeDef结构体里的那些成员。把理论和实践对上号,这块知识就真正扎实了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/28 20:03:12

零权重改动TTFT下降77%:推理加速的隐藏战场

每次在技术群里看到"怎么让模型推理更快"这个问题,十有八九的回答会指向三件事:量化、剪枝、蒸馏。这三板斧确实有效,但它们都落在同一个维度上——改权重。可最近这一年我复现了几轮推理优化项目,结论有点反直觉&#…

作者头像 李华
网站建设 2026/9/28 20:01:49

Windows上打arm64 deb包:容器化打包与验证实战指南

最早接到“在 Windows 上打一个 arm64 的 deb 包”这个需求时,我内心是拒绝的。我手头是一台 Windows 笔记本,目标设备是一块 arm64 架构的 Linux 板子,要分发的是一个内部用的命令行小工具。当时我的第一反应是:deb 不是 Linux 的…

作者头像 李华
网站建设 2026/9/28 20:01:47

GPU细粒度调度失效:Die Scaling下的硬件与软件协同优化

1. 项目概述:这不只是芯片变大,而是调度逻辑的底层地震GPU Die Scaling——这个词听起来像半导体行业的内部黑话,但如果你最近在调试一个PyTorch训练任务,发现batch size从32降到16后GPU利用率反而从45%飙升到88%,或者…

作者头像 李华
网站建设 2026/9/28 19:58:53

ISP、ICP与IAP详解:从固件烧录原理到OTA远程升级

你是不是也经历过这种场景:手里捏着一片STM32,好不容易焊接好板子,把ST-Link插上去,点了几下下载按钮,程序就跑起来了。你觉得这事挺简单,直到有一天同事问你“ISP和ICP到底啥区别”,你打开百度…

作者头像 李华