<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          STM32 DMA理解

          作者: 時(shí)間:2016-11-11 來(lái)源:網(wǎng)絡(luò) 收藏
          通道配置過程

          1、在DMA_CPARx寄存器總設(shè)置外設(shè)寄存器的地址。發(fā)生外設(shè)數(shù)據(jù)傳輸請(qǐng)求時(shí),這個(gè)地址將是傳輸?shù)脑椿蚰繕?biāo)

          本文引用地址:http://www.ex-cimer.com/article/201611/316942.htm

          2、在DMA_CMARx寄存器中設(shè)置數(shù)據(jù)存取器的地址,發(fā)生外設(shè)數(shù)據(jù)傳輸請(qǐng)求時(shí),傳輸?shù)臄?shù)據(jù)將從這個(gè)地址讀出或?qū)懭脒@個(gè)地址

          3、在DMA_CMARx寄存器中設(shè)置要傳輸?shù)臄?shù)據(jù)量,在每個(gè)數(shù)據(jù)傳輸后,這個(gè)數(shù)值遞減。

          4、在DMA_CCRx寄存器的PL位中設(shè)置通道的優(yōu)先級(jí)

          5、在DMA_CCRx寄存器中設(shè)置數(shù)據(jù)傳輸方向、循環(huán)模式、外設(shè)和寄存器的增量模式、外設(shè)和存儲(chǔ)器的數(shù)據(jù)寬度、傳輸一半產(chǎn)生中斷或傳輸完成產(chǎn)生中斷

          6、設(shè)置DMA_CCRx寄存器的ENABLE位,啟動(dòng)該通道

          一旦啟動(dòng)了DMA通道,它即可響應(yīng)連到該通道上的外設(shè)的DMA請(qǐng)求

          當(dāng)傳輸一般的數(shù)據(jù)后,半傳輸標(biāo)志(HTIF)將被置1,當(dāng)設(shè)置了半傳輸中斷位時(shí),

          將產(chǎn)生一個(gè)中斷請(qǐng)求,在數(shù)據(jù)傳輸結(jié)束后,傳輸完成標(biāo)志被置1,當(dāng)設(shè)置了允許傳輸完成中斷位后,將產(chǎn)生一個(gè)中斷請(qǐng)求。

          循環(huán)模式

          循環(huán)模式用于處理循環(huán)緩沖區(qū)和連續(xù)的數(shù)據(jù)傳輸(如ADC的掃描模式),在DMA_CCRx寄存器中的CIRC位用于開啟這一功能,當(dāng)啟動(dòng)了循環(huán)模式,數(shù)據(jù)傳輸?shù)臄?shù)目變?yōu)?時(shí),將會(huì)自動(dòng)地被恢復(fù)成配置通道時(shí)設(shè)置的初值,DMA操作將會(huì)繼續(xù)進(jìn)行。

          存儲(chǔ)器到存儲(chǔ)器模式

          DMA通道的操作可以在沒有外設(shè)請(qǐng)求的情況下進(jìn)行,這種操作就是存儲(chǔ)器到存儲(chǔ)器模式。當(dāng)設(shè)置了DMA_CCRx寄存器中的MEM2MEM位之后,在軟件設(shè)置了DMA_CCRx寄存器中的EN位啟動(dòng)DMA通道時(shí),DMA傳輸將馬上開始,當(dāng)DMA_CNDTRx寄存器變?yōu)?時(shí),DMA傳輸結(jié)束,存儲(chǔ)器到存儲(chǔ)器模式不能與循環(huán)模式同時(shí)使用

          DMA首先,初始化,要了解觸發(fā)源,也可通過軟件編程設(shè)置具體的時(shí)間,具體條件來(lái)觸發(fā)DMA數(shù)據(jù)傳輸,DMA的觸發(fā)源是事件(1)、首先開啟時(shí)鐘

          RCC_APBPeriphClockCmd(RCC_APBPeriph_DMA1,ENABLE);//開啟DMA時(shí)鐘

          結(jié)構(gòu)體(DMA_InitTypeDef)說(shuō)明:

            PeripheralBaseAddr:外設(shè)地址 CPAR

            MemoryBaseAddr: 存儲(chǔ)器地址 CMAR

            DIR:        傳輸方向(從外設(shè)讀/從存儲(chǔ)器讀)

            BufferSize:     傳輸數(shù)量

            PeripheralInc:    外設(shè)地址增量模式(傳完一個(gè)數(shù)后地址是否+1)

            MemoryInc:     存儲(chǔ)器地址增量模式

            PeripheralDataSize: 外設(shè)數(shù)據(jù)寬度(Byte / Half Word / Word)

            MemoryDataSize:  存儲(chǔ)器數(shù)據(jù)寬度

            Mode:        循環(huán)/正常

            Priority:       優(yōu)先級(jí)

            M2M:        存儲(chǔ)器到存儲(chǔ)器模式

          DMA_DeInit(DMA_Channel1);

          默認(rèn)初始化配置

          DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base;

          DMA_PeripheralBaseAddr是給DMA一個(gè)起始地址,在程序中如果這個(gè)是內(nèi)存模式,這給的是一個(gè)定義的一個(gè)數(shù)組的指針,如buffer;其中USART1_DR_Base是自己定義的一個(gè)地址,這個(gè)地址的定義就是USART1_DR這個(gè)寄存器的地址。

          需要注意的是,這個(gè)地址的定義,是由兩部分組成的,基準(zhǔn)地址+偏移地址,在此過程中,基準(zhǔn)地址=0x4001 3800而偏移地址=0x04,所以最終地址為:0x4001 3804

          DMA_InitStructure.DMA_MemoryBaseAddr = (u32)Send_Buffer;

          這個(gè)同樣也是一個(gè)地址變量,這個(gè)地址的存放要發(fā)送的數(shù)據(jù)的

          DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

          設(shè)置DMA的傳輸方向,這個(gè)可以是雙向傳輸,也可以是單向傳輸,在庫(kù)文件中有這樣的定義;指定該外設(shè)是DMA的源還是目的地
          DMA_DIR_PeripheralDST:該外設(shè)是DMA的目的地(要接受的設(shè)備地址)
          DMA_DIR_PeripheralSRC:該外設(shè)是DMA的源(及要傳輸?shù)臄?shù)據(jù))

          DMA_InitStructure.DMA_BufferSize = Send_BufferSize;

          這句話時(shí)設(shè)置DMA在傳輸時(shí)緩沖區(qū)的長(zhǎng)度,一般需要給此緩沖區(qū)定義一個(gè)存儲(chǔ)區(qū),這個(gè)參數(shù)的單位有三種類型:Byte、HalfWord、Word,其中有:
          Byte:8位
          HalfWord:16位
          Word:32位

          DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

          設(shè)置DMA的外設(shè)遞增模式,如果是設(shè)置成SPI模式,則讀取數(shù)據(jù)的時(shí)候會(huì)向下一個(gè)地址移位在這里因?yàn)槲覀兊耐庠O(shè)是USART,則這個(gè)外設(shè)的地址始終是USART1_DR_Base,不需要進(jìn)行自加即遞增模式。

          DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

          這句是設(shè)置DMA的內(nèi)存遞增模式,當(dāng)需要訪問多個(gè)內(nèi)存參數(shù)時(shí),需要使用這個(gè)

          DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;

          設(shè)置DMA在訪問外設(shè)時(shí)操作的數(shù)據(jù)長(zhǎng)度為Byte

          DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;

          設(shè)置DMA在訪問內(nèi)存時(shí)操作的數(shù)據(jù)長(zhǎng)度為Byte

          DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;

          設(shè)置DMA模式,這里是普通模式,即傳輸完成后就關(guān)閉了DMA,還有循環(huán)模式,后面說(shuō)明。

          DMA_InitStructure.DMA_Priority = DMA_Priority_High;

          設(shè)置DMA的優(yōu)先級(jí)別:可以分為4級(jí):VeryHigh,High,Medium,Low.

          DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

          設(shè)置DMA的2個(gè)內(nèi)存中的變量互相訪問的

          DMA_Init(DMA_Channel1,&DMA_InitStructure);

          前面那些都是對(duì)DMA結(jié)構(gòu)體成員的設(shè)置,在次再統(tǒng)一對(duì)DMA整個(gè)模塊做一次初始化,使得DMA各成員與上面的參數(shù)一致。

          DMA_Cmd(DMA_Channel1,ENABLE);

          使能DMA傳輸。

           SMT32系列微控制器低端型號(hào)中僅包含DMA1,支持7個(gè)通道;高端型號(hào)還包括DMA2,支持5個(gè)通道。它的每個(gè)通道可任意指定工作模式,如內(nèi)存到內(nèi)存、內(nèi)存到外設(shè)或外設(shè)到內(nèi)存等。當(dāng)涉及到外設(shè)時(shí),一般是由外設(shè)來(lái)觸發(fā)DMA的一次傳輸,如串口收到數(shù)據(jù)的標(biāo)志位可觸發(fā)DMA.

            DMA的每次傳輸都分為4個(gè)階段:申請(qǐng)仲裁、地址計(jì)算、總線存取和應(yīng)答。除總線存取階段,其他3個(gè)階段都只需要一個(gè)系統(tǒng)周期,并且不占用總線,可在DMA控制器內(nèi)部并發(fā)地執(zhí)行。總線存取階段,每個(gè)字(4字節(jié))的傳輸需要3個(gè)系統(tǒng)周期。DMA和CPU工作在交替方式下,不會(huì)相互阻塞。DMA各個(gè)通道可獨(dú)立設(shè)置優(yōu)先級(jí),當(dāng)訪問同一資源時(shí)高優(yōu)先級(jí)通道先獲得資源。

          采用時(shí)鐘的4個(gè)比較/捕獲通道加DMA可以產(chǎn)生出4路不同頻率和占空比的方波。這里為簡(jiǎn)化篇幅,只列出了產(chǎn)生一路方波的代碼。基本原理是:將時(shí)鐘的4個(gè)通道設(shè)置為反轉(zhuǎn)模式(即計(jì)數(shù)器與比較捕獲寄存器相等時(shí),其對(duì)應(yīng)的CPU引腳電平發(fā)生反轉(zhuǎn)),設(shè)置計(jì)數(shù)器為向上計(jì)數(shù)到0xFFFF的模式;然后預(yù)先計(jì)算好需要引腳反轉(zhuǎn)的時(shí)刻,并使能對(duì)應(yīng)通道的DMA請(qǐng)求。這樣,當(dāng)計(jì)數(shù)器與比較/捕獲寄存器的值相等時(shí),由DMA將下一個(gè)需要引腳電平反轉(zhuǎn)的時(shí)刻送入到比較/捕獲寄存器。

          這里將DMA設(shè)置為從內(nèi)存到外設(shè)的半字(2個(gè)字節(jié))環(huán)形傳輸。開啟DMA全滿和半滿中斷,在中斷處理函數(shù)中不斷填充新的時(shí)刻值,即可保證產(chǎn)生的波形不間斷。假設(shè)存放時(shí)刻值的緩沖長(zhǎng)度為N,則每N/2個(gè)點(diǎn)才中斷一次,這樣CPU就不需要頻繁進(jìn)入中斷,執(zhí)行效率比較高。由此也可以看出,緩沖越大,對(duì)中斷響應(yīng)的實(shí)時(shí)性要求也越低,當(dāng)然這時(shí)中斷的處理時(shí)間也越長(zhǎng)。以下為示例代碼:

          需要注意的是,比較/捕獲寄存器的預(yù)加載功能必須禁止掉。我們需要的是寫入比較/捕獲寄存器的值立即與計(jì)數(shù)器相比較輸出,而無(wú)需等待一個(gè)更新事件。

          采用DMA+TIMx的方式來(lái)捕獲上升沿和下降沿時(shí)刻,有利于提高系統(tǒng)的實(shí)時(shí)性和執(zhí)行效率。通過TIMx的捕獲功能將方波的電平跳變時(shí)刻記錄在比較/捕獲寄存器中,然后DMA將該值自動(dòng)傳輸?shù)絻?nèi)存,只有當(dāng)DMA觸發(fā)半滿或全滿事件時(shí)CPU才需要進(jìn)入中斷處理數(shù)據(jù)。通過記錄方波的上升沿和下降沿時(shí)刻,然后將兩個(gè)時(shí)刻相減,進(jìn)而就能得到所有低沿和高沿的寬度,最后進(jìn)行后續(xù)的分析處理。這種方式下中斷頻率僅為方波頻率的4/N(N為緩沖區(qū)大小)。

          測(cè)試中STM32系列微控制器工作在36 MHz,可產(chǎn)生出1路最高1.5 MHz的方波,可捕獲1 MHz的方波,而此時(shí)CPU的執(zhí)行幾乎不受影響。這里采用DMA來(lái)實(shí)現(xiàn)方波的產(chǎn)生和捕獲,極大地提高了系統(tǒng)的實(shí)時(shí)性和執(zhí)行效率,減少了中斷次數(shù),節(jié)省了寶貴的資源。這種方案也可以用來(lái)實(shí)現(xiàn)高效的模擬串口。另外,若有多個(gè)DMA同時(shí)工作,應(yīng)考慮最壞情況下DMA的響應(yīng)時(shí)間,以避免錯(cuò)誤發(fā)生。

          1、DMA普通模式和循環(huán)模式的區(qū)別
          循環(huán)模式:用于處理一個(gè)環(huán)形的緩沖區(qū),每輪傳輸結(jié)束時(shí)數(shù)據(jù)傳輸?shù)呐渲脮?huì)自動(dòng)地更新為初始狀態(tài),DMA傳輸會(huì)連續(xù)不斷地進(jìn)行。
          普通模式:在DMA傳輸結(jié)束時(shí),DMA通道被自動(dòng)關(guān)閉,進(jìn)一步的DMA請(qǐng)求將不被滿足。
          2、DMA傳輸需要指定的條件:
          傳輸源:DMA控制器從傳輸源讀出數(shù)據(jù);
          傳輸目標(biāo):DMA控制器將數(shù)據(jù)傳輸?shù)哪繕?biāo);
          觸發(fā)信號(hào):用于觸發(fā)一次數(shù)據(jù)傳輸?shù)膭?dòng)作,執(zhí)行一個(gè)單位的傳輸源至傳輸目標(biāo)的數(shù)據(jù)傳輸。可以用來(lái)控制傳輸?shù)膯?dòng)條件。



          關(guān)鍵詞: STM32DM

          評(píng)論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();