什么是DMA
DMA,Direct Memory Access,直接內(nèi)存訪問,是一種不經(jīng)過CPU而直接從內(nèi)存存取數(shù)據(jù)的數(shù)據(jù)交換模式。在DMA模式下,CPU只需要向DMA控制器下達指令,傳輸數(shù)據(jù)由DMA來完成,數(shù)據(jù)傳送完再把信息反饋給CPU,這樣能夠減少CPU的資源占有率。DMA由硬件實現(xiàn),從共用系統(tǒng)數(shù)據(jù)總線的角度看,DMA和CPU是競爭對手的關(guān)系,當完成一批數(shù)據(jù)的傳輸工作之后,快速設(shè)備可以向CPU發(fā)出中斷請求,報告本次傳輸結(jié)束的同時,請示下一步的操作要求。
應(yīng)用場合
DMA應(yīng)用于快速設(shè)備和主存儲器成批交換數(shù)據(jù)的場合,DMA應(yīng)用在數(shù)據(jù)交換,既能夠保證數(shù)據(jù)傳輸?shù)臏蚀_性,即不丟失快速設(shè)備提供出來的數(shù)據(jù),也能夠進一步減少快速設(shè)備讀寫操作對CPU的干擾。
DMA中斷和普通中斷的區(qū)別
兩者最大的不同表現(xiàn)為對CPU的干擾程度不同:DMA 傳送方式的優(yōu)先級高于程序中斷,兩者的區(qū)別主要表現(xiàn)在對CPU的干擾程度不同。中斷請求不但使CPU停下來,而且要CPU執(zhí)行中斷服務(wù)程序為中斷請求服務(wù),這個請求包括了對斷點和現(xiàn)場的處理以及CPU與外設(shè)的傳送,所以CPU付出了很多的代價;DMA請求僅僅使CPU暫停一下,不需要對斷點和現(xiàn)場的處理,并且是由DMA控制外設(shè)與主存之間的數(shù)據(jù)傳送,無需CPU的干預,DMA只是借用了一點CPU的時間而已。還有一個區(qū)別就是,CPU對這兩個請求的響應(yīng)時間不同,對中斷請求一般都在執(zhí)行完一條指令的時鐘周期末尾響應(yīng),而對DMA的請求,由于考慮它的高效性,CPU在每條指令執(zhí)行的各個階段之中都可以讓給DMA使用,是立即響應(yīng)?!MA主要由硬件來實現(xiàn),此時高速外設(shè)和內(nèi)存之間進行數(shù)據(jù)交換不通過CPU的控制,而是利用系統(tǒng)總線。DMA方式是I/O系統(tǒng)與主機交換數(shù)據(jù)的主要方式之一,另外還有程序查詢方式和中斷方式。
DMA特性
● 12個 獨立的可配置的通道(請求)DMA1 有7個通道, DMA2有5個通道
● 每個通道都直接連接專用的硬件DMA請求,每個通道都同樣支持軟件觸發(fā)。這些功能通過軟件來配置。
● 在七個請求間的優(yōu)先權(quán)可以通過軟件編程設(shè)置(共有四級:很高、高、中等和低),假如在相等優(yōu)先權(quán)時由硬件決定(請求0優(yōu)先于請求1 ,依此類推) 。
● 獨立的源和目標數(shù)據(jù)區(qū)的傳輸寬度(字節(jié)、半字、全字),模擬打包和拆包的過程。源和目標地址必須按數(shù)據(jù)傳輸寬度對齊。
● 支持循環(huán)的緩沖器管理
● 每個通道都有3個事件標志(DMA 半傳輸, DMA傳輸完成和DMA傳輸出錯),這3個事件標志邏輯或成為一個單獨的中斷請求。
● 存儲器和存儲器間的傳輸
● 外設(shè)和存儲器,存儲器和外設(shè)的傳輸
● 閃存、 SRAM、外設(shè)的SRAM、 APB1 APB2和AHB外設(shè)均可作為訪問的源和目標。
● 可編程的數(shù)據(jù)傳輸數(shù)目:最大為65536
DMA配置過程
(1)外設(shè)寄存器地址;DMA_CPARx(x=1-7),DMA1和DMA2共享用7個,DMA2沒有6和7
(2)存儲器地址;DMA_CMARx(x=1-7),DMA1和DMA2共享用7個99,DMA2沒有6和7
(3)傳輸量,DMA_CNDTRx,只用bit0-15,0-65535,只在DMA_CCRx的EN為0時,可寫,減為0時,不會發(fā)生任何數(shù)據(jù)傳輸,除非使用循環(huán)模式;傳輸數(shù)據(jù)寬度,傳輸方向,DMA_CCRx
(4)循環(huán)/正常模式,地址增量模式(包括外設(shè)和存儲器的地址),DMA_CCRx
(5)通道優(yōu)先級,DMA_CCRx
(6)中斷請求標志,DMA_ISR和DMA_IFCR
DMA的工作過程及循環(huán)模式、存儲器到存儲器模式
配置DMA完后,并且使能了DMA,當發(fā)生外設(shè)數(shù)據(jù)傳輸請求時,如果傳輸量不為0,在DMA的控制下,數(shù)據(jù)以指定的方向,以傳輸數(shù)據(jù)寬度,從源地址傳輸?shù)侥繕说刂?,一次傳輸完成,傳輸量減1,此時如果開啟了地址增量模式,那么下一個源地址、目標地址將會是前一個地址加上增量值,增量值取決于所選的數(shù)據(jù)寬度(8位+1,16位+2,32位+4),當源地址設(shè)定的數(shù)據(jù)寬度小于目標地址的數(shù)據(jù)寬度,那么源數(shù)據(jù)全部寫入目標地址后,目標地址剩下的位置將寫0,當大于時,目標地址將全被寫滿,源數(shù)據(jù)未寫部分將被舍棄。如果開啟了循環(huán)模式,數(shù)據(jù)傳輸量變?yōu)?時,將會自動恢復成配置通道時設(shè)置的初值,DMA操作繼續(xù)執(zhí)行。
如果開啟了中斷(傳輸錯誤中斷、傳輸完成中斷、半傳輸中斷),將會產(chǎn)生相應(yīng)的中斷事件。三種不同中斷共用一個中斷函數(shù),但可以通過中斷標志區(qū)分。
當設(shè)置了DMA_CCRx的MEM2MEM位,在軟件設(shè)置了DMA_CCRx的EN位啟動DMA傳輸,DMA傳輸立即開始,當傳輸量減為0,傳輸結(jié)束。注意存儲器到存儲器模式不能和循環(huán)模式共同使用。
DMA的DMA_ISR和DMA_IFCR的區(qū)別
DMA_ISR,存儲中斷標志位,由硬件置位,使用了前28位,共7個通道,每個通道使用4位,分別是GIFx(全局中斷)、TCIFx(傳輸完成)、HTIFx(半傳輸)、TEIFx;特別地,GIFx 置1時,表示有中斷發(fā)生。
DMA_IFCR,中斷標志清除寄存器,由軟件置位, 使用了前28位,共7個通道,每個通道使用4位,分別是CGIFx(全局中斷)、CTCIFx(傳輸完成)、CHTIFx(半傳輸)、CTEIFx;寫入0不起作用,寫入1清除DMA_ISR相應(yīng)的標志位。
錯誤管理
讀寫一個保留的地址區(qū)域,將會產(chǎn)生DMA傳輸錯誤。當在DMA讀寫操作時發(fā)生DMA傳輸錯誤時,硬件會自動地清除發(fā)生錯誤的通道所對應(yīng)的通道配置寄存器(DMA_CCRx)的EN位,該通道操作被停止。此時,在DMA_IFT寄存器中對應(yīng)該通道的傳輸錯誤中斷標志位(TEIF)將被置位,如果在DMA_CCRx寄存器中設(shè)置了傳輸錯誤中斷允許位,則將產(chǎn)生中斷。
操作一個不支持字節(jié)或半字寫的AHB設(shè)備
當DMA模塊開始一個AHB的字節(jié)或半字寫操作時,數(shù)據(jù)將在HWDATA[31:0]總線中未使用的部分重復。因此,如果DMA以字節(jié)或半字寫入不支持字節(jié)或半字寫操作的AHB設(shè)備時(即HSIZE不適于該模塊),不會發(fā)生錯誤, DMA將按照下面兩個例子寫入32位HWDATA數(shù)據(jù):
● 當HSIZE=半字時,寫入半字’0xABCD’, DMA將設(shè)置HWDATA總線為’0xABCDABCD’。
● 當HSIZE=字節(jié)時,寫入字節(jié)’0xAB’, DMA將設(shè)置HWDATA總線為’0xABABABAB’。
假定AHB/APB橋是一個AHB的32位從設(shè)備,它不處理HSIZE參數(shù),它將按照下述方式把任何AHB上的字節(jié)或半字按32位傳送到APB上:
● 一個AHB上對地址0x0(或0x1 、 0x2或0x3)的寫字節(jié)數(shù)據(jù)’0xB0’操作,將轉(zhuǎn)換到APB上對地址0x0的寫字據(jù)’0xB0B0B0B0’操作。
● 一個AHB上對地址0x0(或0x2)的寫半字數(shù)據(jù)’0xB1B0’操作,將轉(zhuǎn)換到APB上對地址0x0的寫字數(shù)據(jù)’0xB1B0B1B0’操作。
例如,如果要寫入APB后備寄存器(與32位地址對齊的16位寄存器),需要配置存儲器數(shù)據(jù)源寬度(MSIZE)為’16位’,外設(shè)目標數(shù)據(jù)寬度(PSIZE)為’32位’。
注意:
(1)存儲器到存儲器模式下,可以使用任意DMA通道;
(2)開啟DMA數(shù)據(jù)傳輸模式,除了存儲器到存儲器的數(shù)據(jù)傳輸,其他外設(shè)的DMA傳輸,不僅要支持DMA,還要在使用的時候,自己開啟DMA功能,比如USART1的DMA開啟為,USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);
(3)外設(shè)的DMA,還要注意選擇的通道是否正確。