1. 程式人生 > >STM32 DMA簡述

STM32 DMA簡述

串口數據 sar amp lds 時也 工業 流程 同時 數據

STM32 DMA簡述

DMA (Direct Memory Access) 直接內存存儲器,在做數據傳輸時能夠大大減輕CPU的負擔。

DMA的作用

DMA提供了一個關於數據的高數傳輸通道,這個通道不占用CPU的資源。換句話說,通過DMA通道,你在傳輸大規模數據的時候CPU同時也能夠去幹其他事。

你可以控制DMA通道的接入口,靈活配置傳輸的數據源和目的地。以下幾個是常用的DMA傳輸路徑:

從外設到內存

從內存A區域傳到內存B區域

從一個外設傳輸到另一個外設

從內存傳輸數據到外設

....

DMA流程分析

在stm32中,DMA是以類似外設的形式添加到內核之外的,下面我們來看具體的框圖:
技術分享圖片

從上圖我們可以看到,DMA通過系統總線連接到了APB1和APB2總線,也連接到了SRAM,Flash和Cortex內核。

我們發現,DMA是獨立在內核之外的,其系統總線連接了所有模塊,而且這個連接過程並沒有經過內核。這也印證了前文所說的,在使用DMA通道傳輸數據時,並不占用CPU資源。

再仔細觀察上圖,圖中除了總線之外,還有標有DMA請求字樣的黑色箭頭。外設需要向DMA發送請求,並應答通過後才能夠啟動傳輸。具體過程如下:

①在發生一個事件後,外設發送一個請求信號到DMA控制器。DMA控制器根據通道的優先權處理請求。

②當DMA控制器開始訪問外設的時候,DMA控制器立即發送給外設一個應答信號。

③當外設從DMA控制器得到應答信號時,外設立即釋放它的請求。

④在釋放請求後,DMA控制器撤銷應答信號。

DMA配置

在我們想要使用DMA的時候,我們該怎麽啟用他呢?我們通過一個配置函數來實現,在函數內部設置DMA傳輸的各種參數,最後使能它。代碼如下:

void USARTx_DMA_Config(void)
{
        DMA_InitTypeDef DMA_InitStructure;
    
        // 開啟DMA時鐘
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
        // 設置DMA源地址:串口數據寄存器地址*/
         DMA_InitStructure.DMA_PeripheralBaseAddr = USART_DR_ADDRESS;
        // 內存地址(要傳輸的變量的指針)
        DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff;
        // 方向:從內存到外設    
        DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
        // 傳輸大小 
        DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE;
        // 外設地址不增       
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
        // 內存地址自增
        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
        // 外設數據單位   
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
        // 內存數據單位
        DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;  
        // DMA模式,一次或者循環模式
        DMA_InitStructure.DMA_Mode = DMA_Mode_Normal ;
        //DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;   
        // 優先級:中    
        DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; 
        // 禁止內存到內存的傳輸
        DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
        // 配置DMA通道         
        DMA_Init(USART_TX_DMA_CHANNEL, &DMA_InitStructure);     
        // 使能DMA
        DMA_Cmd (USART_TX_DMA_CHANNEL,ENABLE);
}

這是一個將串口和DMA連接起來的配置代碼,傳輸方向為從內存到外設。當然想要實現完整的功能,還需要其他代碼,你可以參考機械工業出版社出的那本STM32庫開發實戰指南

STM32 DMA簡述