【STM32 系列】DMA —— 直接存儲器存取
引言
這個最近也忘了,自用。
簡介

- 存儲器(SRAM、Flash)和外設之間數據傳輸、存儲器和存儲器之間數據傳輸。
- 通道就是數據轉運路徑,一個數據要進行轉運,就要占用一個通道。如果有多個通道進行數據轉運, 它們之間可以各轉各的,互不干擾。
- 1、使用軟件觸發以后,DMA就會將數據以最快的速度全部轉運完成。一般用于存儲器到存儲器之間的轉運。
2、使用硬件觸發,就可以有一定的時機。例如ADC,可以觸發一次DMA,DMA轉運一次。一般用于外設到存儲器的轉運。
3、每一個DMA的通道,其硬件觸發源是不一樣的,想要使用某一個硬件的觸發源,就要使用它連接的通道,而不能任意選擇。
存儲器
所謂的外設只不過是STM32特定指定了可以轉運外設的存儲器,本質上其實都是存儲器到存儲器之間的數據轉運。
- ROM:只讀存儲器,非易失性、掉電不丟失的存儲器。
- RAM:隨機存儲器,易失性、掉電丟失的存儲器。
DMA存取

- 總線矩陣:其左邊是主動單元,擁有存儲器的訪問權;右邊的是被動單元,只能被左邊的主動單元讀寫.
- 仲裁器:雖然DMA有多個通道可以獨立轉運數據,但是DMA總線只有一條,所以所有的通道都只能分時復用這一條DMA總線。產生了沖突,仲裁器就會根據通道的優先級,來決定使用先后。
- AHB從設備:DMA作為外設的自身的寄存器。所以DMA即是總線矩陣的主動單元,可以讀寫各種寄存器;也是AHB總線上的被動單元,CPU可以通道AHB總線對DMA進行配置。
- DMA請求:DMA的硬件觸發源,比如DMA轉換完成、串口接收到數據,需要觸發DMA轉運數據的時候,就會向DMA發出硬件觸發信號。
- CPU和DMA直接訪問Flash的話,只能讀取而不可寫入。
- SRAM是運行內存,可以任意讀寫。
DMA工作

- 傳輸計數器:指定DMA需要轉運幾次,是一個自減計數器。減到0后,就不再進行轉運,并且自增的起始地址也會恢復到原本的起始地址。
- 自動重裝器:在傳輸在傳輸計數器自減到0后將其重裝到初始值,決定了轉運的模式。如果不使能,就是單次轉運模式;如果使能,就是循環轉運模式。
- M2M:存儲器到存儲器。使能M2M時,DMA就會選擇軟件觸發,以最快的速度連續不斷的觸發DMA,將傳輸計數器清零,完成一輪轉換(注意與ADC的軟件觸發不太一樣,這里可以理解為連續觸發),并且軟件觸發和自動重裝器不能一起用。不使能M2M時,可以選擇硬件觸發,觸發源可以選擇ADC、串口、定時器等外設,硬件達到某一個時機時,傳輸一個信號來觸發DMA轉運。
- 開關控制:DMA_CMD函數,使能后,DMA就能進行轉運。
DMA工作條件
- 開關控制,DMA使能。
- 傳輸計數器必須大于0。
- 觸發源必須有觸發信號,觸發一次轉運一次,傳輸計數器自減一次。
- 當傳輸計數器等于0,且沒有自動重裝時,無論是否觸發,DMA都不會再進行轉運,此時就要失能開關控制(DMA_CMD)關閉DMA,給傳輸計數器寫一個數,再使能開關控制開啟DMA,才能繼續工作(不能在DMA開啟時寫入傳輸計數器)。
DMA請求
- DMA每一個通道都有數據選擇器,可以選擇硬件或者軟件觸發。
- 每一個通道的硬件觸發源不同,想要用不同的外設來觸發,就必須選擇某個特定的通道。假如選擇軟件觸發,那么通道就可以任意選擇。(每個通道都支持軟件觸發和特定的硬件觸發)
- 到底在一個通道上選擇哪一個外設觸發源,是根據其中某個外設開啟了DMA輸出來決定的(如ADC_DMACMD),必須使用庫函數開啟某個外設的DMA輸出才會有效。
數據寬度與對齊
- 數據寬度都一樣,就是正常的一個個轉運。
- 假如目標的數據寬度比源端的數據寬度大,那就在目標數據前面多出的高位補0。
- 假如目標數據寬度比源端數據寬度小,那么就會把多出來的高位舍棄。
DMA數據轉運

存儲器到存儲器之間的轉運,使用軟件觸發,不需要等待硬件時機,盡快轉運完成即可。
ADC掃描+DMA

- 左邊ADC有七個通道,觸發以后,七個通道依次進行AD轉換,轉換的結果都放到ADC_DR數據寄存器中。
- 在每一個單獨的通道轉換完成后,進行一次DMA數據轉運,且目的地址進行自增。
-
DMA配置
- 外設地址寫入ADC_DR寄存器的地址。
- 存儲器的地址在SRAM中定義一個數組ADValue,將ADValue的地址當作存儲器的地址。
- uint16_t位的數據,故數據寬度為半字傳輸。
- 從ADC_DR寄存器將數據轉運到DMA,那么外設地址不自增,存儲器地址自增。
- 此處通道有七個,故傳輸計數器寫7。
- ADC如果是單次掃描,那么DMA的傳輸計數器可以不自動重裝,轉換一輪就停止;如果ADC是連續掃描模式,那么DMA就可以使用自動重裝,在ADC啟動下一輪轉換的時候,DMA也啟動下一輪轉運,ADC和DMA同步工作。
- 使用ADC硬件觸發DMA,因為ADC_DR的值是在ADC單個通道轉換完成后才會有效,故DMA轉運的時機需要和ADC單個通道轉換完成同步,故選擇ADC硬件觸發。ADC掃描模式在一個單獨的通道轉換完成以后,沒有任何標志位,也不會觸發中斷,但是會產生DMA請求,去觸發DMA轉運。
- DMA最常見的用途就是配合ADC的掃描模式,因為ADC掃描模式有數據覆蓋的特征。
博客導航
本文來自博客園,作者:膝蓋中箭衛兵,轉載請注明原文鏈接:http://www.rzrgm.cn/Skyrim-sssuuu/p/18774947

浙公網安備 33010602011771號
https://orcid.org/0000-0001-5102-772X