一、理論理解部分。
1、直接存儲器存取(DMA)用來提供在外設和存儲器之間或者存儲器和存儲器之間的高速數據傳輸。
2、無須CPU干預,數據可以通過DMA快速移動,這就節省了CPU的資源來做其他操作。
3、兩個DMA控制器有12個通道(DMA1有7個通道,DMA2有5個通道),每個通道專門用來管理來自一個或者多個外設對存儲器訪問的請求。
4、還有一個沖裁器協調各個DMA請求的優先權。在同一個DMA模塊上,多個請求間的優先權可以通過軟件編程設置(共有四級:很高、高、中和低),優先權設置相等時由硬件決定(請求0優先請求1,)
5、每個通道都有三個事件標志(DMA半傳輸、DMA傳輸完成和DMA傳輸出錯),這三個事件標志邏輯或成為一個單獨的中斷請求。
6、閃存、SRAM、外設的SRAM、APB1、APB2和AHB外設均可作為訪問的源和目標。
7、可編程的數據傳輸數目:最大為65535
8、如果外設要想通過DMA 來傳輸數據,必須先給DMA 控制器發送DMA 請求,DMA 收到請求信號之后,控制器會給外設一個應答信號,當外設應答后且DMA 控制器收到應答信號之后,就會啟動DMA 的傳輸,直到傳輸完畢。DMA 有DMA1 和DMA2 兩個控制器,DMA1 有7 個通道,DMA2有5 個通道,不同的DMA 控制器的通道對應着不同的外設請求,這決定了我們在軟件編程上該怎么設置,具體見DMA 請求映像表。
9、
仲裁器當發生多個DMA 通道請求時,就意味着有先后響應處理的順序問題,這個就由仲裁器也管理。仲裁器管理DMA 通道請求分為兩個階段。第一階段屬於軟件階段,可以在DMA_CCRx 寄存器中設置,有4 個等級:非常高、高、中和低四個優先級。第二階段屬於硬件階段,如果兩個或以上的DMA通道請求設置的優先級一樣,則他們優先級取決於通道編號,編號越低優先權越高,比如通道0 高於通道1。
(為了解決多個DMA請求時,就有先后順序,有一個仲裁器管理,分為兩部分:1、軟件處理,可以設置非常高、高、中、和低四個優先級,2、優先級一樣,則看他們的編號,編號越低優先權越高)
DMA數據配置的詳細解說:
使用DMA,最核心就是配置要傳輸的數據,包括數據從哪里來,要到哪里去,傳輸的數據的單位
是什么,要傳多少數據,是一次傳輸還是循環傳輸等等。
從哪里來到哪里去
我們知道DMA 傳輸數據的方向有三個:從外設到存儲器,從存儲器到外設,從存儲器到存儲器。
具體的方向DMA_CCR 位4 DIR 配置:0 表示從外設到存儲器,1 表示從存儲器到外設。
這里面涉及到的外設地址由DMA_CPAR 配置,存儲器地址由DMA_CMAR 配置。
要傳多少,單位是什么
當我們配置好數據要從哪里來到哪里去之后,我們還需要知道我們要傳輸的數據是多少,數據的
單位是什么。以串口向電腦發送數據為例,我們可以一次性給電腦發送很多數據,具體多少由
DMA_CNDTR 配置,這是一個32 位的寄存器,一次最多只能傳輸65535 個數據。要想數據傳輸正
確,源和目標地址存儲的數據寬度還必須一致,串口數據寄存器是8 位的,所以我們定義的要發送的
數據也必須是8 位。外設的數據寬度由DMA_CCR 的PSIZE[1:0]配置,可以是8/16/32 位,存儲器
的數據寬度由DMA_CCR 的MSIZE[1:0]配置, 可以是8/16/32 位。
在DMA 控制器的控制下,數據要想有條不紊的從一個地方搬到另外一個地方,還必須正確設置
兩邊數據指針的增量模式。外設的地址指針由DMA_CCRx 的PINC 配置,存儲器的地址指針由
MINC 配置。以串口向電腦發送數據為例,要發送的數據很多,每發送完一個,那么存儲器的地址指
針就應該加1,而串口數據寄存器只有一個,那么外設的地址指針就固定不變。具體的數據指針的增量
模式由實際情況決定。
什么時候傳輸完成
數據什么時候傳輸完成,我們可以通過查詢標志位或者通過中斷的方式來鑒別。每個DMA 通道
在DMA 傳輸過半、傳輸完成和傳輸錯誤時都會有相應的標志位,如果使能了該類型的中斷后,則會
產生中斷。有關各個標志位的詳細描述請參考DMA 中斷狀態寄存器DMA_ISR 的詳細描述。傳輸完
成還分兩種模式,是一次傳輸還是循環傳輸,一次傳輸很好理解,即是傳輸一次之后就停止,要想再傳
輸的話,必須關斷DMA 使能后再重新配置后才能繼續傳輸。循環傳輸則是一次傳輸完成之后又恢復
第一次傳輸時的配置循環傳輸,不斷的重復。具體的DMA_CCR 寄存器的CIRC 循環模式位控制。
二、編程要用的成員:
1、DMA_DIR : 傳輸方向選擇, 可選外設到存儲器、存儲器到外設。它設定DMA_CCR 寄存器的DIR[1:0]位的值。這里並沒有存儲器到存儲器的方向選擇, 當使用存儲器到存儲器時,只需要把其中一個存儲器當作外設使用即可。
(DMA_DIR_PeripheralDST:外設作為數據傳輸的目的地 DMA_DIR_PeripheralSRC:外設作為數據傳輸的來源)
2、DMA_PeripheralInc:
DMA_MemoryInc= //內存地址寄存器遞增與否
DMA_PeripheralInc= //外設地址寄存器遞增與否
如果配置DMA_PeripheralInc_Enable,使能外設地址自動遞增功能,它設定DMA_CCR 寄存器的PINC 位的值;一般外設都是只有一個數據寄存器,所以一般不會使能該位。(自動遞增的意思就是:相當路邊的自動出售飲料機器一樣,當你買了一瓶汽水,拿出來了,然后后面有自動補上去,這就是自動遞增,這里的數據也是一樣,始終拿第一個數據,其他的會自動遞增上來,不好意思,由於理解錯誤,現在做一下修改:是拿水瓶的手是)
3、DMA_BufferSize= //設定待傳輸數目
4、DMA_M2M= //使能DMA通道的內存到內存傳輸
5、DMA_MemoryBaseAddr= //存儲器地址
6、DMA_MemoryDataSize= //內存數據寬度
7、DMA_PeripheralDataSize= //外設數據寬度
8、DMA_Mode= //工作模式,優先級
9、DMA_PeripheralBaseAddr= //外設地址
10、DMA_Priority= //軟件設置通道的優先級