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