標題: [零基礎學習STM32]第十一講:DMA實驗—存儲器到存儲器的傳輸 [打印本頁]
作者: kkhkbb 時間: 2018-4-3 15:21
標題: [零基礎學習STM32]第十一講:DMA實驗—存儲器到存儲器的傳輸
本帖最后由 kkhkbb 于 2018-4-3 21:21 編輯
一、概述:
1、DMA簡介
DMA的英文拼寫是"Direct Memory Access",漢語的意思就是直接內存訪問,是一種不經過CPU而直接從內存存取數據的數據交換模式。在DMA模式下,CPU只須向DMA控制器下達指令,讓DMA控制器來處理數據的傳送,數據傳送完畢再把信息反饋給CPU,這樣就很大程度上減輕了CPU資源占有率,可以大大節省系統資源。DMA模式又可以分為Single-Word DMA(單字節DMA)和Multi-Word DMA(多字節DMA)兩種。
2、DMA工作原理
DMA 允許不同速度的硬件裝置來溝通,而不需要依于 CPU 的大量中斷負載。否則,CPU 需要從來源把每一片段的資料復制到暫存器,然后把他們再次寫回到新的地方。在這個時間中,CPU 對于其他的工作來說就無法使用。
DMA 傳輸主要地將一個內存區從一個裝置復制到另外一個。當 CPU 初始化這個傳輸動作,傳輸動作本身是由 DMA 控制器來實行和完成。典型的例子就是移動一個外部內存的區塊到芯片內部更快的內存去。像是這樣的操作并沒有讓處理器工作拖延,反而可以被重新排程去處理其他的工作。所以,DMA傳輸對于高效能嵌入式系統算法和網絡是很重要的。
3、DMA類別
按鍵主要有兩種類型:單字節DMA、多字節DMA。
單字節DMA:一次傳送一個字節,效率較低,但它會保證在兩次DMA傳送之間,CPU有機會獲得總線控制權,執行一次CPU總線周期。
多字節DMA:一次請求傳送一個數據塊,效率高,但在整個DMA傳送期間,CPU長時間無法控制總線(無法響應其他DMA請求,無法處理其他中斷等)。
二、實驗原理:
DMA(直接存儲器訪問)傳輸不需要占用CPU,可以在存儲器至實現高速的數據傳輸。本實驗采用DMA2控制器的數據流0,選用通道0進行數據傳輸。通過LED的顏色來判斷傳輸是否成功。
三、源代碼:
1.主函數及DMA設置
- /*
- * Name : main
- * Description : ---
- * Author : ysloveivy.
- *
- * History
- * --------------------
- * Rev : 0.00
- * Date : 11/21/2015
- *
- * create.
- * --------------------
- */
- int main(void)
- {
- int i,k;
- DMA_InitTypeDef DMA_InitStructure;
- led.initialize();
- dma.initialize();
- //測試DMA,測試成功藍燈閃爍,測試失敗,紅燈閃爍
- DMA_InitStructure.DMA_Channel = DMA_Channel_0; //選擇通道0
- DMA_InitStructure.DMA_PeripheralBaseAddr = (unsigned long int)src_buffer; //DMA外設基地址
- DMA_InitStructure.DMA_Memory0BaseAddr = (unsigned long int)dst_buffer; //DMA存儲器地址
- DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToMemory; //方向為存儲器到存儲器
- DMA_InitStructure.DMA_BufferSize = (unsigned long int)BUFFER_SIZE; //數據傳輸量
- DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable; //外設增量模式
- DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //存儲器增量模式
- DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; //設置外設數據寬度
- DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; //設置存儲器數據寬度
- DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //運行模式為普通模式
- DMA_InitStructure.DMA_Priority = DMA_Priority_High; //優先級級別為高
- DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; //FIFO模式禁止
- DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; //FIFO閾值
- DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; //存儲器突發單次傳輸
- DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; //外設突發單次傳輸
- DMA_Init(DMA2_Stream0, &DMA_InitStructure);
- DMA_Cmd(DMA2_Stream0, ENABLE); //使能DMA2_Stream0
- while(DMA_GetCmdStatus(DMA2_Stream0) != DISABLE);
- for(i = 0;i < BUFFER_SIZE;i++){
- if(dst_buffer[i] != src_buffer[i]){
- //測試失敗
- while(1){
- for(k = 0;k < 10000000;k++);
- LED_RED_ON;
- for(k = 0;k < 10000000;k++);
- LED_RED_OFF;
- }
- }
- }
- //測試成功
- while(1){
- for(k = 0;k < 10000000;k++);
- LED_BLUE_ON;
- for(k = 0;k < 10000000;k++);
- LED_BLUE_OFF;
- }
- }
復制代碼2.DMA初始化函數
- /*
- * Name : initialize
- * Description : ---
- * Author : ysloveivy.
- *
- * History
- * --------------------
- * Rev : 0.00
- * Date : 11/29/2015
- *
- * create.
- * --------------------
- */
- static int initialize(void)
- {
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); //使能DMA2時鐘
- DMA_DeInit(DMA2_Stream0); //配置DMA2
- while (DMA_GetCmdStatus(DMA2_Stream0) != DISABLE) //等待DMA可配置
- {
- }
- return 0;
- }
復制代碼3、小知識
在DMA的設置中我們遇到了關于DMA設置的結構體,我們通過配置其相關參數,以實現我們想要的功能,其解釋如下:
- typedef struct
- {
- uint32_t DMA_Channel; //選擇通道
- uint32_t DMA_PeripheralBaseAddr; //DMA外設基地址
- uint32_t DMA_Memory0BaseAddr; //DMA存儲器地址
- uint32_t DMA_DIR; //DMA傳輸方向
- uint32_t DMA_BufferSize; //數據傳輸量
- uint32_t DMA_PeripheralInc; //外設增量模式選擇
- uint32_t DMA_MemoryInc; //存儲器增量模式
- uint32_t DMA_PeripheralDataSize; //設置外設數據寬度
- uint32_t DMA_MemoryDataSize; //設置存儲器數據寬度
- uint32_t DMA_Mode; //運行模式選擇
- uint32_t DMA_Priority; //優先級選擇
- uint32_t DMA_FIFOMode; //FIFO模式選擇
- uint32_t DMA_FIFOThreshold; //FIFO閥值
- uint32_t DMA_MemoryBurst; //存儲器突發單次傳輸
- uint32_t DMA_PeripheralBurst; //外設突發單次傳輸
- }DMA_InitTypeDef;
復制代碼四、實驗現象:
試驗成功藍色LED燈閃爍,試驗反敗紅色LED燈閃爍。
五、代碼包下載連接:
網盤:http://pan.baidu.com/s/1bcY5JK
作者: frog108 時間: 2021-10-10 19:49
這個不是stm32f1吧
歡迎光臨 (http://www.raoushi.com/bbs/) |
Powered by Discuz! X3.1 |