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