找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

帖子
查看: 2467|回復(fù): 1
打印 上一主題 下一主題
收起左側(cè)

STM32的DMA

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:105323 發(fā)表于 2016-2-12 21:12 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
  什么是DMA?其全稱是:Direct MemoryAccess;根據(jù)ST公司提供的相關(guān)信息,DMA是STM32中一個(gè)獨(dú)立與Cortex-M3內(nèi)核的模塊,有點(diǎn)類似與ADC、PWM、TIMER等模塊;主要功能是通信“橋梁”的作用,可以將所有外設(shè)映射的寄存器“連接”起來,這樣就可以高速問各寄存器,其傳輸不受CPU的支配,傳輸還是雙向的;例如,從“表面”上看,它可以將flash中的數(shù)據(jù)與儲(chǔ)存器中變量建立通訊,還可以將一外設(shè)的積存器或緩沖器與另外設(shè)的寄存器或緩沖器建立雙向通訊,有點(diǎn)像把外設(shè)硬件之間用“導(dǎo)線”連接在一起了。其間的通訊不占CPU資源,訪問速度高,對(duì)于實(shí)時(shí)性強(qiáng)的應(yīng)用將是一個(gè)很好的選擇;就像我們?nèi)艘粯�,我們平常�?xí)慣性的動(dòng)作是不用經(jīng)過大腦思考的,比如說眨眼睛,呼吸等。DMA就是負(fù)責(zé)這些工作的,但它沒人這么智能,需要將它設(shè)置好了它才會(huì)正常工作。當(dāng)然,對(duì)于實(shí)時(shí)性非常強(qiáng)的,建議還是采用專用的DSP芯片。
怎樣啟用DMA?首先,眾所周知的是初始化,任何設(shè)備啟用前都要對(duì)其進(jìn)行初始化,要對(duì)模塊初始化,還要先了解該模塊相應(yīng)的結(jié)構(gòu)及其函數(shù),以便正確的設(shè)置;由于DMA較為復(fù)雜,我就只談?wù)凞MA的基本結(jié)構(gòu)和和常用函數(shù),這些都是ST公司提供在庫函數(shù)中的。在一個(gè)重要的條件就是觸發(fā)源是什么,就是說什么時(shí)候進(jìn)行DMA數(shù)據(jù)傳輸呢?這叫觸發(fā)信號(hào)。也可以通過軟件編程設(shè)置具體時(shí)間,具體條件來觸發(fā)DMA數(shù)據(jù)傳輸,DMA的觸發(fā)源是事件,下面代碼是一個(gè)標(biāo)準(zhǔn)DMA設(shè)置,當(dāng)然實(shí)際應(yīng)用中可根據(jù)實(shí)際情況進(jìn)行裁減,當(dāng)然這之前得開啟DMA時(shí)鐘:

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);//開啟DMA1時(shí)鐘

結(jié)構(gòu)體(DMA_InitTypeDef)說明:
  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);
上面這句是給DMA配置通道,根據(jù)ST提供的資料,STM3210Fx中DMA包含7個(gè)通道(CH1~CH7),也就是說可以為外設(shè)或memory提供7座“橋梁”(請(qǐng)?jiān)试S我使用橋梁一詞,我覺得更容易理解,哈哈,別“拍磚”呀�。�
DMA_InitStructure.DMA_PeripheralBaseAddr =ADC1_DR_Address;
上面語句中的DMA_InitStructure是一個(gè)DMA結(jié)構(gòu)體,在庫中有聲明了,當(dāng)然使用時(shí)就要先定義了;DMA_PeripheralBaseAddr是該結(jié)構(gòu)體中一個(gè)數(shù)據(jù)成員,給DMA一個(gè)起始地址,好比是一個(gè)buffer起始地址,數(shù)據(jù)流程是:外設(shè)寄存器àDMA_PeripheralBaseAddàmemory中變量空間(或flash中數(shù)據(jù)空間等),ADC1_DR_Address是我定義的一個(gè)地址變量;
DMA_InitStructure.DMA_MemoryBaseAddr =(u32)ADC_ConvertedValue;
上面這句很顯然是DMA要連接在Memory中變量的地址,ADC_ConvertedValue是我自己在memory中定義的一個(gè)變量;
DMA_InitStructure.DMA_DIR =DMA_DIR_PeripheralSRC;
上面的這句是設(shè)置DMA的傳輸方向,就如前面我所說的,DMA可以雙向傳輸,也可以單向傳輸,這里設(shè)置的是單向傳輸,如果需要雙向傳輸:把DMA_DIR_PeripheralSRC改成DMA_DIR_PeripheralDST即可。
DMA_InitStructure.DMA_BufferSize = 2;
上面的這句是設(shè)置DMA在傳輸時(shí)緩沖區(qū)的長度,前面有定義過了buffer的起始地址:ADC1_DR_Address,為了安全性和可靠性,一般需要給buffer定義一個(gè)儲(chǔ)存片區(qū),這個(gè)參數(shù)的單位有三種類型:Byte、HalfWord、word,我設(shè)置的2個(gè)half-word(見下面的設(shè)置);32位的MCU中1個(gè)half-word占16bits。
DMA_InitStructure.DMA_PeripheralInc =DMA_PeripheralInc_Disable;
上面的這句是設(shè)置DMA的外設(shè)遞增模式,如果DMA選用的通道(CHx)有多個(gè)外設(shè)連接,需要使用外設(shè)遞增模式:DMA_PeripheralInc_Enable;我的例子里DMA只與ADC1建立了聯(lián)系,所以選用DMA_PeripheralInc_Disable
DMA_InitStructure.DMA_MemoryInc =DMA_MemoryInc_Enable;
上面的這句是設(shè)置DMA的內(nèi)存遞增模式,DMA訪問多個(gè)內(nèi)存參數(shù)時(shí),需要使用DMA_MemoryInc_Enable,當(dāng)DMA只訪問一個(gè)內(nèi)存參數(shù)時(shí),可設(shè)置成:DMA_MemoryInc_Disable。
DMA_InitStructure.DMA_PeripheralDataSize =DMA_PeripheralDataSize_HalfWord;上面的這句是設(shè)置DMA在訪問時(shí)每次操作的數(shù)據(jù)長度。有三種數(shù)據(jù)長度類型,前面已經(jīng)講過了,這里不在敘述。DMA_InitStructure.DMA_MemoryDataSize =DMA_MemoryDataSize_HalfWord;
與上面雷同。在此不再說明。
DMA_InitStructure.DMA_Mode =DMA_Mode_Circular;
上面的這句是設(shè)置DMA的傳輸模式:連續(xù)不斷的循環(huán)模式,若只想訪問一次后就不要訪問了(或按指令操作來反問,也就是想要它訪問的時(shí)候就訪問,不要它訪問的時(shí)候就停止),可以設(shè)置成通用模式:DMA_Mode_Normal
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è)memory中的變量互相訪問的
DMA_Init(DMA_Channel1,&DMA_InitStructure);
前面那些都是對(duì)DMA結(jié)構(gòu)體成員的設(shè)置,在次再統(tǒng)一對(duì)DMA整個(gè)模塊做一次初始化,使得DMA各成員與上面的參數(shù)一致。
DMA_Cmd(DMA_Channel1,ENABLE);
這一句我想我就不羅嗦了,大家一看就明白。








分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:160651 發(fā)表于 2017-1-7 22:02 | 只看該作者
受教了
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表