做嵌入式開發時,大家是不是都有過這種崩潰場景:
很多初學者遇到這種情況,第一反應是“是不是代碼寫得不夠高效”。但事實是:你再怎么優化循環,CPU 親自搬數據就是效率低。
解決方案其實很明確——用 DMA(Direct Memory Access,直接存儲器訪問)。如果你會合理使用 DMA,很多“看似不可避免的性能瓶頸”都能迎刃而解。今天我們就來聊聊 DMA 的工作原理、常見應用和實戰技巧。
一、DMA 究竟是什么?
DMA 的核心思路很簡單:把數據搬運工作交給硬件去做。
在沒有 DMA 的情況下,數據傳輸的流程大概是:
- 外設產生數據;
- CPU 中斷響應;
- CPU 把數據讀出來放到內存。
而有了 DMA:
- 外設和 DMA 控制器直接“勾搭”;
- 數據繞過 CPU,直接搬到內存。
這樣一來,CPU 不用再做“快遞員”,可以專心處理邏輯,系統響應速度和并發能力都能上一個臺階。
二、DMA 的常見應用場景
1. 串口數據接收(UART DMA)
如果你做過大數據量的串口通信,就會發現中斷方式很容易丟數據。
- DMA 可以配置成循環緩沖區,數據一來就自動寫入 RAM;
- CPU 只需要在合適的時候檢查緩沖區,不用每個字節都處理中斷。
2. ADC 連續采樣
- 普通方式下,CPU 每次采樣要響應 ADC 中斷,很快就“累趴”;
- 用 DMA,可以把采樣結果自動存到數組里,形成數據流,CPU 后續再批量處理。
3. 內存到外設數據傳輸
比如 SPI 發送、DAC 輸出波形:
- 傳統方式要一個字節一個字節寫寄存器;
- DMA 可以直接把內存中的一段緩沖區刷到外設寄存器,效率極高。
4. 內存到內存傳輸
一些芯片的 DMA 支持內存塊搬運,可以用來快速清零數組、搬運數據結構,CPU 不用一個循環一個循環寫。
三、DMA 配置的關鍵要點
很多同學第一次用 DMA,發現配置比想象中復雜。其實總結起來,主要是以下幾個步驟:
- 確定通道/流
- DMA 控制器通常有多個通道,對應不同的外設。
- 要查手冊,看你的外設掛在哪個 DMA 通道上。
- 配置源地址和目的地址
- 源地址可以是外設寄存器,比如 ADC_DR。
- 目的地址一般是內存數組。
- 有時候是反過來,比如內存 → SPI。
- 配置傳輸方向
- 外設到內存(ADC、UART RX);
- 內存到外設(SPI TX、DAC);
- 內存到內存。
- 配置數據長度和傳輸模式
- 單次搬運幾個字節?總共搬多少?
- 是循環模式(buffer 自動回繞)還是普通模式?
- 啟動 DMA
- 記得在外設使能之前配置好 DMA;
- 啟動順序有講究,比如 UART DMA 要先開 DMA 再開 UART 接收。
四、實戰技巧:避免常見坑
技巧 1:循環緩沖 vs 普通模式
- 如果數據源是持續的(比如串口、ADC),用循環緩沖更穩。
- 如果只是一次性發送一段數據(比如 SPI 發命令),普通模式即可。
技巧 2:善用中斷回調
DMA 雖然能自動搬數據,但你還是得知道“什么時候搬完”。
- 可以開傳輸完成中斷,在回調函數里處理數據。
- 對于循環模式,可以用半傳輸中斷,做到“邊采集邊處理”。
技巧 3:緩存對齊問題
有些 MCU 的 DMA 對地址有對齊要求,比如 4 字節對齊,否則性能下降甚至報錯。寫代碼前要看手冊。
技巧 4:注意總線帶寬
DMA 不是“無限快”,它也占用內存總線。
- 多個 DMA 通道同時工作時,可能會互相搶占。
- 解決方法:錯峰啟動,或者降低非關鍵任務的優先級。
技巧 5:與 CPU 配合
DMA 搬數據的同時,CPU 可能要訪問同一片內存。
- 要小心數據一致性問題,可以用“雙緩沖”或者加鎖機制。
五、案例分享
案例 1:ADC + DMA 實現波形采集
某項目需要 10kHz 的 ADC 采樣,用中斷方式 CPU 占用率高達 70%。
→ 換成 DMA 循環搬運到數組,CPU 占用率直接降到 5% 以下,系統反應流暢。
案例 2:UART 接收不丟包
串口調試工具長時間發送數據,CPU 用中斷處理時經常丟字節。
→ 改用 DMA + 環形緩沖 + IDLE 中斷檢測幀間隔,接收穩定,再也沒掉過包。
案例 3:SPI 高速傳輸
某 OLED 屏幕更新一幀圖像需要傳 8KB 數據,用循環寫寄存器方式刷新率只有 20fps。
→ DMA 一次傳輸緩沖區,刷新率提高到 60fps,畫面流暢無比。
六、總結
DMA 對嵌入式開發來說,是“必學技能”之一。很多人初學時嫌它復雜,繼續讓 CPU 自己“跑腿”,結果系統卡頓、性能不達標。其實只要掌握幾個要點:
- 了解外設和 DMA 通道的映射關系;
- 正確配置源地址、目的地址和傳輸模式;
- 結合中斷回調實現數據處理;
- 注意帶寬和緩存一致性問題。
你就能真正實現“零 CPU 占用的高速傳輸”,讓系統既高效又穩定。
-
cpu
+關注
關注
68文章
11276瀏覽量
224933 -
數據傳輸
+關注
關注
9文章
2199瀏覽量
67579 -
dma
+關注
關注
3文章
582瀏覽量
105916
發布評論請先 登錄
CW32L052單片機支持DMA實現高速數據傳輸
ADXRS453Z的芯片支持使用STM32單片機的DMA數據傳輸功能嗎?
Serial RapidIO接口DMA數據傳輸
請問ADXRS453Z的芯片支持使用STM32單片機的DMA數據傳輸功能嗎?
DMA的數據傳輸速率是多少?
怎么實現基于FPGA的具有流量控制機制的高速串行數據傳輸系統設計?
stm32數據傳輸的相關資料分享
DMA進行數據傳輸和CPU進行數據傳輸的疑問
基于FPDP的高速數據傳輸系統設計
基于Zynq-7000的SRIO高速數據傳輸設計與實現
DMA數據傳輸在SPEAR300實現高速串口驅動設計
stm32數據傳輸
DMA 實戰指南:零 CPU 占用玩轉高速數據傳輸
評論