DSP28335 中DMA的配置和使用


本文根據下面的鏈接整理而成:

http://bbs.elecfans.com/jishu_900708_1_1.html

http://bbs.21ic.com/icview-690422-1-1.html

http://blog.csdn.net/wu159632/article/details/7543599

http://bbs.21ic.com/icview-800778-1-1.html

 

依次來看:

 

零:

該文檔記述了ADC在使用EPWM1的SOCA觸發情況下,用DMA直接將Result0-16搬到存儲區的方法。此方法而不需要使用ADC中斷來存出結果,從而節約了CPU資源。使用該方法需注意以

下幾點:
   1.DMA是從Result0-16的映射區取轉化結果,即DMASource= &AdcMirror.ADCRESULT0;
   2.目的地址需要在RAML4-RAML7,即#pragma DATA_SECTION(DMABuf1,"DMARAML4");DMABuf1是目的變量名,即DMADest=&DMABuf1[0];
   3.DMA如果采用SEQ1觸發,需將SEQ1的中斷打開,即AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1=1;但是不需要手動清除SEQ1的中斷標志,ADC工作在啟停模式下,每次轉化完成后也不

需要復位排序器,即不需要每次設置AdcRegs.ADCTRL2.bit.RST_SEQ1=1;因為DMA每次存儲后他會自動清除中斷標志和復位排序器。
   4.DMA傳輸結果時,對於原地址和目的地址的移動主要通過三種方式來執行,
   1)burst傳輸;burst傳輸是由每一個ADC中斷標志觸發,ADC每次轉化完成,該傳輸模式啟動,原地址和目的地址的移動通過計數方式執行,首先要告訴原地址的首地址,即

DmaRegs.CH1.SRC_BEG_ADDR_SHADOW = (Uint32)DMA_Source;= &AdcMirror.ADCRESULT0;其次得告知每次出發傳輸多少數據,即DmaRegs.CH1.BURST_SIZE.all = bsize,如bsize=9,

就是一次burst傳輸10個數據;然后要告訴下次發送數據的地址和接收數據的地址,即DmaRegs.CH1.SRC_BURST_STEP = srcbstep;DmaRegs.CH1.DST_BURST_STEP = desbstep,傳輸一

個16位或32位數據,將執行一次地址偏移(原地址的首地+DmaRegs.CH1.SRC_BURST_STEP和目的首地址+DmaRegs.CH1.DST_BURST_STEP), DmaRegs.CH1.BURST_SIZE.all也將減1,

當 DmaRegs.CH1.BURST_SIZE.all=0時,本次burst傳輸完成。
   2)transfer傳輸,transfer傳輸有兩個功能。一是確定多少次transfer傳輸后來執行DMA中斷,二是確定下次burst傳輸的原首地址和目的首地址,他都是在上一次burst傳輸完

成后,源和目的地址的基礎上進行偏移,transfer傳輸由三個寄存器管理,DmaRegs.CH1.TRANSFER_SIZE = tsize;
他告訴DSP多少次burst傳輸,執行DMA中斷一次,如tsize=9,就是10次burst傳輸中斷一次。DmaRegs.CH1.SRC_TRANSFER_STEP = srctstep;這個寄存器告訴DSP下次burst傳輸的源

首地址,他是在上次burst傳輸的最后一個源數據的地址上進行偏移;DmaRegs.CH1.DST_TRANSFER_STEP = deststep,這個寄存器告訴DSP下次burst傳輸的目的首地址,他是在上次

burst傳輸的最后一個目的地址上進行偏移;
   3)wrap傳輸,可實現循環傳輸,DmaRegs.CH1.SRC_WRAP_SIZE = srcwsize;是指源burst傳輸srcwsize+1后,源地址就要返回,下次burst傳輸源的首地址為

DmaRegs.CH1.SRC_ADDR_SHADOW +DmaRegs.CH1.SRC_WRAP_STEP;DmaRegs.CH1.SRC_ADDR_SHADOW是本輪wrap傳輸DmaRegs.CH1.SRC_BEG_ADDR_SHADOW的映射寄存器值,

DmaRegs.CH1.SRC_WRAP_STEP為wrap傳輸源的首地址偏移量。DmaRegs.CH1.DST_WRAP_SIZE = deswsize;是指burst傳輸deswsize+1后,目的地址就要返回,下次burst傳輸目的首地

址為DmaRegs.CH1.DST_ADDR_SHADOW+DmaRegs.CH1.DST_WRAP_STEP;DmaRegs.CH1.DST_ADDR_SHADOW,是本輪wrap傳輸DmaRegs.CH1.DST_ADDR_SHADOW的映射寄存器值,

DmaRegs.CH1.DST_WRAP_STEP為傳輸目的首地址偏移量(transfer傳輸,DmaRegs.CH1.DST_TRANSFER_STEP是相對於最受一個數據的地址偏移量)。所以wrap傳輸和transfer傳輸二

選一與burst傳輸搭配即可。要想屏蔽wrap傳輸,需將DmaRegs.CH1.SRC_WRAP_SIZE和DmaRegs.CH1.DST_WRAP_SIZE的值設定的比DmaRegs.CH1.TRANSFER_SIZE大。
   5.即使在使用wrap傳輸時,只要burst傳輸次數達到DmaRegs.CH1.TRANSFER_SIZE,在DMA中斷開啟的情況下,DMA還是會進入中斷。
   6.在非持續模式下,如果想在某段地址內采用覆蓋式存儲,需在中斷內對源和目的首地址重新賦值,並要重新令DmaRegs.CH1.CONTROL.bit.RUN = 1。
   7.在持續模式下,如果想在某段地址內采用覆蓋式存儲,只需在中斷內對源和目的首地址重新賦值。

  下面以ADC 6通道,轉化50次一次中斷為例,來配置地址偏移。
采用transfer傳輸:
DMACH1AddrConfig(volatile Uint16 *DMA_Dest,volatile Uint16 *DMA_Source);
DMACH1BurstConfig(5,1,50);
DMACH1TransferConfig(49,-5,-250+1);
DMACH1WrapConfig(100,100,100,100);//禁止wrap傳輸
采用wrap傳輸
DMACH1AddrConfig(volatile Uint16 *DMA_Dest,volatile Uint16 *DMA_Source);
DMACH1BurstConfig(5,1,50);
DMACH1WrapConfig(0,0,5,1);
DMACH1TransferConfig(49,0,0)//如果要50次一中斷,DmaRegs.CH1.TRANSFER_SIZE =49;

 

一、官網例程

DMACH1BurstConfig(3,1,10);//
DMACH1TransferConfig(9,1,0);//
DMACH1WrapConfig(1,0,0,1);//

cnsxgh回復:

樓主這個例子應該是ADC-DMA里面的。那根據樓主這個程序,應該只有3個通道。假設是ADC1,ADC2,ADC3,ADC4。
相應的目標地址是DMA[0]-DMA[30]。
DMACH1BurstConfig(3,1,10);//這里,BURST3個字,表示ADC有四個通道。源地址步長是1,表示源地址指針ADC1完了就是ADC2再完了就是ADC3
//目標地址步長是10,表示ADC1的數據挪到DMA[0],ADC2的數據挪到DMA[10],ADC3的數據挪到DMA[20].
DMACH1TransferConfig(9,0,1);//9,表示了一共采10次。
DMACH1WrapConfig(0,0,0,1);//第一個0,表示一Transfer后,就要進行地址回繞,第二個0,回繞步長不增長。第四個,1,表示目標地址回繞后增加1.即第二輪采采集時,ADC1->DMA[1],ADC2->DMA[11],ADC3->DMA[21]

 

二、用幀數、幀內個數來解釋

 

DMA(Direct Memory Access),即直接存儲器存取,是一種快速傳送數據的機制。它的優點在於一旦控制器初始化完成,數據開始傳送,DMA就可以脫離CPU,獨立完成數據傳送。不需要依於CPU的大量中斷負載,從而節省大量的CPU資源。

TMS320F28335具有6通道DMA,而且每個通道具有獨立的PIE中斷。DMA的觸發源種類有很多,可以配置為ADC、MCBSPs、外部中斷、CPU定時器、ePWM1-6 ADCSOCA and ADSOCB和軟件等出發方式。DMA可以對L4-L7 16Kx16 SARAM、XINTF外部接口、ADC、MCBSPs、ePWM1-6/HRPWM1-6映射到Peripheral Frame 3空間的寄存器進行數據操作。工作方式可以配置為32位或者16位。吞吐量最高為4時鍾/字。需要注意的是,當DMA對MCBSPs進行數據操作時,只能配置為16位工作模式,而且最大的吞吐量為5時鍾/字。具體原因參考一下TI的數據手冊。下面以TI的例程為例詳細講解一下DMA配置。

28335 DMA的配置主要是一下幾個函數,可以在DSP2833x_DMA.c找到。

函數及配置詳解:

void DMACHxAddrConfig(volatile Uint16 *DMA_Dest,volatile Uint16 *DMA_Source)

參數解析:配置DMA的數據目的地址和源地址(跟函數中參數的排序相同,下同)。

void DMACHxBurstConfig(Uint16 bsize, int16 srcbstep, int16 desbstep)

參數解析:配置每幀大小、幀內源地址增加偏移和幀內源地址增加偏移。地址增加偏移就是指傳輸一個字(或幀)之后地址增量。

void DMACHxTransferConfig(Uint16 tsize, int16 srctstep, int16 deststep)

參數解析:配置每次觸發DMA轉移多少幀、幀間源地址增加偏移和幀間源地址增加偏移。

void DMACHxWrapConfig(Uint16 srcwsize, int16 srcwstep, Uint16 deswsize, int16 deswstep)

參數解析:配置源地址偏移總量、重載的源地址、目的地址偏移總量、重載的目的地址。也就是說在源地址(或者目的地址)偏移量超過所設置的偏移總量的時候重載所設置的新的源地址(或者目的地址)。我是這么理解的。

void DMACHxModeConfig(Uint16 persel, Uint16 perinte, Uint16 oneshot, Uint16 cont, Uint16 synce, Uint16 syncsel, Uint16 ovrinte, Uint16 datasize, Uint16 chintmode, Uint16 chinte)

參數解析:配置觸發源選擇、觸發源使能、ONESHOT使能、繼續模式使能、外設同步使能、同步對象選擇(源同步還是目的同步)、溢出中斷使能、工作方式選擇(16位還是32位)、產生中斷模式選擇(開始還是結束)、產生中斷使能。

 

三、用脈沖個數及幀來解釋

 

  void DMACH1AddrConfig(volatile Uint16 *DMA_Dest,volatile Uint16 *DMA_Source)
        源地址有兩個,一個A為用於傳輸時(隨每個字節遞增),另一個B作為返回的備份(當一幀結束后,重新裝載入A)
        目的地址有兩個,一個A為用於傳輸時(隨每個字節遞增),另一個B作為返回的備份(當一幀結束后,重新裝載入A)
        每次啟動DMA相應通道,都會把B裝載入A
        void DMACH1BurstConfig(Uint16 bsize, int16 srcbstep, int16 desbstep)
        Bsize: 每一個脈沖傳遞的字的個數,實際脈沖數為bsize+1
        Srcbstep:每傳遞一個字后,源地址A增量
        Desbstep:每傳遞一個字后,目的地址A增量

        void DMACH1TransferConfig(Uint16 tsize, int16 srctstep, int16 deststep)
        Tsize:每一幀的脈沖個數,脈沖遞減到0時(即一幀傳遞完成,也是DMA傳遞完成),產生DMA中斷。實際幀數為tsize+1
        Srctstep:每個脈沖的最后一個字傳遞結束后,源地址A增量
        Deststep:每個脈沖的最后一個字傳遞結束后,目的地址A增量

        void DMACH1WrapConfig(Uint16 srcwsize, int16 srcwstep, Uint16 deswsize, int16 deswstep)
        Srcwsize:當已經傳遞的脈沖數為srcwsize+1的整數倍時,源地址(B)增加srcwstep(常為0),並裝載入源地址A
        Deswsize:當已經傳遞的脈沖數為deswsize+1的整數倍時,目的地址(B)增加deswstep(常為0),並裝載入目的地址A

        void DMACH1ModeConfig(Uint16 persel, Uint16 perinte, Uint16 oneshot, Uint16 cont, Uint16 synce, Uint16 syncsel, Uint16 ovrinte, Uint16 datasize, Uint16 chintmode, Uint16 chinte)
        Persel:選擇觸發DMA的外設中斷源
        Perinte:外設中斷使能,
        Oneshot:使能時,外設產生一次中斷,就能夠把一幀傳遞完。禁止,外設產生一次中斷,只能傳遞一個脈沖
        Cont:使能時,每次DMA結束后,需要再次啟動DMA時,就不需要調用void StartDMACH1(void)。禁止時,重啟DMA,需要調用void StartDMACH1(void)
        Datasize:設置每個字是16位或者32位
        Chintmode:設置DMA中斷是在DMA啟動或者結束時產生
        Chinte:DMA相應通道的中斷使能(外設級)。
        注:Perinte和Chinte同時使能時,才能進入DMA通道中斷
        僅Perinte使能,可以傳輸數據,但是不進入通道的中斷程序

        void StartDMACH1(void)
        首次啟動DMA,若Cont為禁止,每次DMA結束后,需要再次啟動DMA時需要調用
        只開啟相應用於觸發的外設級中斷,不開啟PIE對應位,則能夠觸發DMA而不觸發CPU的中斷程序
        經過DMACH1ModeConfig配置的中斷,DMA會自動清除相應外設級的中斷標志位,不用程序清除。

 

三個一結合,就看明白了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM