DMA(Direct Memory Access)常譯為“存儲(chǔ)器直接存取”。早在Intel的8086平臺(tái)上就有了DMA應(yīng)用了。
一個(gè)完整的微控制器通常由CPU、存儲(chǔ)器和外設(shè)等組件構(gòu)成。這些組件一般在結(jié)構(gòu)和功能上都是獨(dú)立的,而各個(gè)組件的協(xié)調(diào)和交互就由CPU完成。如此一來,CPU作為整個(gè)芯片的核心,其處理的工作量是很大的。如果CPU先從A外設(shè)拿到一個(gè)數(shù)據(jù)送給B外設(shè)使用,同時(shí)C外設(shè)又需要D外設(shè)提供一個(gè)數(shù)據(jù)。。。這樣的數(shù)據(jù)搬運(yùn)工作將使CPU的負(fù)荷顯得相當(dāng)繁重。
嚴(yán)格的說,搬運(yùn)數(shù)據(jù)只是CPU的比較不重要的一種工作。CPU最重要的工作室進(jìn)行數(shù)據(jù)運(yùn)算,從加減乘除到一些高級(jí)的運(yùn)算,包括浮點(diǎn)、積分、微分、FFT等。CPU還需要負(fù)責(zé)復(fù)雜的中斷申請(qǐng)和響應(yīng),以保證芯片的實(shí)時(shí)性能。
理論上常見的控制外設(shè),比如Usart、I2C、SPI甚至是USB等通信接口,單純的利用CPU進(jìn)行協(xié)議模擬也是可以實(shí)現(xiàn)的,比如51單片機(jī)經(jīng)常使用I/O口模擬I2C協(xié)議通信。但這樣既浪費(fèi)了CPU的資源,同時(shí)實(shí)現(xiàn)后的性能表現(xiàn)往往和使用專門的硬件模塊實(shí)現(xiàn)的效果相差甚遠(yuǎn)。從這個(gè)角度來看,各個(gè)外設(shè)控制器的存在,無疑降低了CPU的負(fù)擔(dān),解放了CPU的資源。
數(shù)據(jù)搬運(yùn)這一工作占用了大部分的CPU資源,成為了降低CPU的工作效率的主要原因之一。于是需要一種硬件結(jié)構(gòu)分擔(dān)CPU這一職能——DMA。
從數(shù)據(jù)搬運(yùn)的角度看,如果要把存儲(chǔ)地址A的數(shù)值賦給另外一個(gè)地址上B的變量,CPU實(shí)現(xiàn)過程為首先讀出A地址上的數(shù)據(jù)存儲(chǔ)在一個(gè)中間變量,然后再轉(zhuǎn)送到B地址的變量上。使用DMA則不需要中間變量,直接將A地址的數(shù)值傳送到B地址的變量里。無疑減輕了CPU的負(fù)擔(dān),也提高了數(shù)據(jù)搬運(yùn)的效率。
stm32中DMA1有7個(gè)通道,DMA2有5個(gè)通道。DMA掛載的時(shí)鐘為AHB總線,其時(shí)鐘為72Mhz,所以可以實(shí)現(xiàn)高速數(shù)據(jù)搬運(yùn)。
stm32的DMA1通道一覽表
stm32使用DMA的相關(guān)操作:
1、DMA的配置
void DMA_Configuration(void){ DMA_InitTypeDefDMA_InitStructure; //DMA設(shè)置: //設(shè)置DMA源:內(nèi)存地址&串口數(shù)據(jù)寄存器地址 //方向:內(nèi)存-->外設(shè) //每次傳輸位:8bit //傳輸大小DMA_BufferSize=SENDBUFF_SIZE //地址自增模式:外設(shè)地址不增,內(nèi)存地址自增1 //DMA模式:一次傳輸,非循環(huán) //優(yōu)先級(jí):中 DMA_DeInit(DMA1_Channel4);//串口1的DMA傳輸通道是通道4 DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base; DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;//外設(shè)作為DMA的目的端 DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE;//傳輸大小 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外設(shè)地址不增加 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//內(nèi)存地址自增1 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
//DMA_Mode_Normal(只傳送一次), DMA_Mode_Circular(不停地傳送) DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;//(DMA傳送優(yōu)先級(jí)為中等) DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel4, &DMA_InitStructure);}
注:
1、傳輸通道:
通過查表,串口1的發(fā)送對(duì)應(yīng)的是DMA的通道4,所以此處選擇通道4.
2、DMA傳輸方式:
(1)DMA_Mode_Normal,正常模式,當(dāng)一次DMA數(shù)據(jù)傳輸完后,停止DMA傳送,對(duì)于上例而言,就是DMA_PeripheralDataSize_Byte個(gè)字節(jié)的傳送完成后,就停止傳送。
(2)DMA_Mode_Circular
循環(huán)模式,當(dāng)傳輸完一次后,重新接著傳送,永不停息。
2、外設(shè)的DMA方式設(shè)置
將串口1設(shè)置成DMA模式:
USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
3、待傳輸數(shù)據(jù)的定義和初始化
#define SENDBUFF_SIZE 10240vu8 SendBuff[SENDBUFF_SIZE];
for(i=0;i
4、開始DMA傳輸(使能對(duì)應(yīng)的DMA通道)DMA_Cmd(DMA1_Channel4, ENABLE);
5、DMA傳輸?shù)耐瓿?/p>
while(DMA_GetFlagStatus(DMA1_FLAG_TC4) == RESET) { LED_1_REV; //LED翻轉(zhuǎn) Delay(); //浪費(fèi)時(shí)間 }
當(dāng)傳輸完成后,就會(huì)跳出上面的死循環(huán)。
-
cpu
+關(guān)注
關(guān)注
68文章
10889瀏覽量
212379 -
STM32
+關(guān)注
關(guān)注
2270文章
10915瀏覽量
356743 -
dma
+關(guān)注
關(guān)注
3文章
566瀏覽量
100743
原文標(biāo)題:聊聊STM32中DMA模塊的使用
文章出處:【微信號(hào):weixin21ic,微信公眾號(hào):21ic電子網(wǎng)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論