DMA應用例項詳解

2021-08-21 09:52:38 字數 3567 閱讀 5031

dma應用例項詳解

閒來無事,學習了下dma的相關知識和使用。平時看到的dma都是簡單的儲存器到暫存器或者暫存器到儲存器這樣單類的傳輸。學習完dma後,我想寫個比較綜合點的dma學習例項,不僅能增加自己對dma的深入應用,也同時發表於此給網友提供參考。之所以說多知識,例項涉及到儲存器到暫存器和暫存器到儲存器,以及dma中斷使用等相關知識。

例項內容:微控制器採集ad值通過dma傳輸給ram儲存器(就是定義的變數),同時又將儲存器資料傳輸給串列埠輸出,實現ad採集與串列埠輸出的轉換。

1.主函式部分

int main(void)

}

2.dma1_ch1中斷函式

void dma1_channel1_irqhandler()

}

3.adc初始化

void adcinit(adc_typedef* adcx , u8 channel_num)

4.adc通道配置,並獲取相應模組下通道的adc值(這裡只用到通道配置就夠了)

u16 get_adcvalue(adc_typedef* adcx ,u8 adc_channel_x ,u8 rank)

5.dma_adc初始化

//名稱:dma adc初始化

void dmax_adcx_init(dma_channel_typedef* dmax_channelx ,u32 dma_dir_peripheral*** , u32 memorybaseaddr, u32 peripheralbaseaddr,u16 dma_buffersize)

if(dma2_channel1 <= dmax_channelx && dma2_channel5 >= dmax_channelx)

dma_deinit(dmax_channelx);//

dma_initstruct.dma_buffersize = dma_buffersize;//dma傳輸的資料量

dma_initstruct.dma_m2m = dma_m2m_disable; //儲存器到儲存器傳輸失能

dma_initstruct.dma_memorybaseaddr = memorybaseaddr;//儲存器基位址(可為sram或flash,程式變數一般位於sram)

dma_initstruct.dma_memorydatasize = dma_memorydatasize_halfword;//儲存器傳輸資料寬度16(可選8,16,32位)

dma_initstruct.dma_memoryinc = dma_memoryinc_disable;//儲存器位址不遞增

dma_initstruct.dma_peripheralbaseaddr = peripheralbaseaddr;//外設暫存器的基位址(多是資料暫存器)

dma_initstruct.dma_peripheraldatasize = dma_peripheraldatasize_halfword;//外設暫存器傳輸資料寬度16(8,16,32位)

dma_initstruct.dma_peripheralinc = dma_peripheralinc_disable;//外設位址不進行遞增

dma_initstruct.dma_priority = dma_priority_high;//傳輸優先順序:高(四種:最高,高,中,低)

dma_init(dmax_channelx, &dma_initstruct);

}

6.dma_usart初始化

注意此初始化和adc 的dma初始化是不一樣的,具體不一樣處見函式說明, 和呼叫的實參。

//名稱:dma usart初始化

//注;傳入位址位數32位

void dmax_usartx_init(dma_channel_typedef* dmax_channelx ,u32 dma_dir_peripheral*** , u32 memorybaseaddr, u32 peripheralbaseaddr,u16 dma_buffersize)

if(dma2_channel1 <= dmax_channelx && dma2_channel5 >= dmax_channelx)

dma_deinit(dmax_channelx);

dma_initstruct.dma_buffersize = dma_buffersize;//dma傳輸的資料量

dma_initstruct.dma_m2m = dma_m2m_disable; //儲存器到儲存器傳輸失能

dma_initstruct.dma_memorybaseaddr = memorybaseaddr;//儲存器基位址(可為sram或flash,程式變數一般位於sram)

dma_initstruct.dma_memorydatasize =dma_memorydatasize_byte;儲存器傳輸資料寬度8位(8,16,32位)

dma_initstruct.dma_peripheralbaseaddr = peripheralbaseaddr;//外設暫存器的基位址(多是資料暫存器)

dma_initstruct.dma_peripheraldatasize = dma_peripheraldatasize_byte;// dma_peripheraldatasize_halfword;//外設暫存器傳輸資料寬度8位(8,16,32位)

dma_initstruct.dma_peripheralinc = dma_peripheralinc_disable;//外設位址不進行遞增

dma_initstruct.dma_priority = dma_priority_high;//傳輸優先順序:高(四種:最高,高,中,低)

dma_init(dmax_channelx, &dma_initstruct);

}

7.dma啟動傳輸(用於每次傳輸開啟)

//dma啟動傳輸

//傳入引數:通道  資料量

void dmax_enable(dma_channel_typedef* dmax_channelx ,u16 dma_buffersize)

8.中斷配置函式

void nvic_config()

9.rcc時鐘配置

void rccinit()

下面是上位機顯示傳輸的資料:

對於串列埠,一次只能輸出8位(一位元組數),即使傳進去16位數,也被擷取前半段 adc採集為10為精度,資料儲存寬度要大於8位 所以:dma的adc傳輸需要16位,而usart傳輸只能8位傳輸 該例程的adc為連續轉換模式,若是單次需要每次對通道重新配置一次 *dma為迴圈模式只需要使能一次,否則非迴圈下需要重新使能 來啟動傳輸 每個dma通道對應不同外設見手冊 dma中斷配置必須放在dma引數配置後面才能用 注意:等待判滿前,不能清除標誌;注意:清除後,不能去等待判滿,否則死迴圈。

hadoop遷移資料應用例項詳解

專案開發中hadoop一直裝在虛擬機器上,最近要遷移到伺服器上。記錄下遷移過程。一 為虛擬機器新增一塊新的硬碟 虛擬機器的初始硬碟只有30g,容不開要匯出的資料。兩種方式,一是給虛擬機器擴容 二是為虛擬機器新增一塊新的硬碟。這裡採取第二種方式。1 新增虛擬硬碟 至此,新增硬碟成功。2 將硬碟分割槽 ...

Kernel下的DMA 位址對映詳解

在網上檢視了各路大牛的dma資料,但一直未解決我的問題和疑問 dma的抽象層,沒有講到具體,比如這個dma map single這個函式。這個 phys addr到底是從 來的,是如何受到保護的,以及這個對映關係和dma unmap single 取消對映之間,是否涉及到phys addr的關聯。x...

1 15 DMA的原理和應用

詳細的實驗 請參看 一 dma原理分析 1.dma direct memory access 直接記憶體儲存,用於記憶體到記憶體,或者記憶體到外設 介面 晶元暫存器等 2.dma控制器 2440為4通道 6410為四控制器,每個控制器8通道 210分為dma mem dma0以及dma1 二 基於s...