找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 7914|回復(fù): 1
打印 上一主題 下一主題
收起左側(cè)

[零基礎(chǔ)學(xué)習(xí)STM32]第十一講:DMA實(shí)驗(yàn)—存儲(chǔ)器到存儲(chǔ)器的傳輸

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:278743 發(fā)表于 2018-4-3 15:21 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
本帖最后由 kkhkbb 于 2018-4-3 21:21 編輯

一、概述:
1、DMA簡(jiǎn)介
     DMA的英文拼寫(xiě)是"Direct Memory Access",漢語(yǔ)的意思就是直接內(nèi)存訪問(wèn),是一種不經(jīng)過(guò)CPU而直接從內(nèi)存存取數(shù)據(jù)的數(shù)據(jù)交換模式。在DMA模式下,CPU只須向DMA控制器下達(dá)指令,讓DMA控制器來(lái)處理數(shù)據(jù)的傳送,數(shù)據(jù)傳送完畢再把信息反饋給CPU,這樣就很大程度上減輕了CPU資源占有率,可以大大節(jié)省系統(tǒng)資源。DMA模式又可以分為Single-Word DMA(單字節(jié)DMA)Multi-Word DMA(多字節(jié)DMA)兩種。
2、DMA工作原理
     DMA 允許不同速度的硬件裝置來(lái)溝通,而不需要依于 CPU 的大量中斷負(fù)載。否則,CPU 需要從來(lái)源把每一片段的資料復(fù)制到暫存器,然后把他們?cè)俅螌?xiě)回到新的地方。在這個(gè)時(shí)間中,CPU 對(duì)于其他的工作來(lái)說(shuō)就無(wú)法使用。
     DMA 傳輸主要地將一個(gè)內(nèi)存區(qū)從一個(gè)裝置復(fù)制到另外一個(gè)。當(dāng) CPU 初始化這個(gè)傳輸動(dòng)作,傳輸動(dòng)作本身是由 DMA 控制器來(lái)實(shí)行和完成。典型的例子就是移動(dòng)一個(gè)外部?jī)?nèi)存的區(qū)塊到芯片內(nèi)部更快的內(nèi)存去。像是這樣的操作并沒(méi)有讓處理器工作拖延,反而可以被重新排程去處理其他的工作。所以,DMA傳輸對(duì)于高效能嵌入式系統(tǒng)算法和網(wǎng)絡(luò)是很重要的。
3、DMA類(lèi)別
     按鍵主要有兩種類(lèi)型:?jiǎn)巫止?jié)DMA、多字節(jié)DMA。
       單字節(jié)DMA:一次傳送一個(gè)字節(jié),效率較低,但它會(huì)保證在兩次DMA傳送之間,CPU有機(jī)會(huì)獲得總線控制權(quán),執(zhí)行一次CPU總線周期。
      多字節(jié)DMA:一次請(qǐng)求傳送一個(gè)數(shù)據(jù)塊,效率高,但在整個(gè)DMA傳送期間,CPU長(zhǎng)時(shí)間無(wú)法控制總線(無(wú)法響應(yīng)其他DMA請(qǐng)求,無(wú)法處理其他中斷等)。
二、實(shí)驗(yàn)原理:
      DMA(直接存儲(chǔ)器訪問(wèn))傳輸不需要占用CPU,可以在存儲(chǔ)器至實(shí)現(xiàn)高速的數(shù)據(jù)傳輸。本實(shí)驗(yàn)采用DMA2控制器的數(shù)據(jù)流0,選用通道0進(jìn)行數(shù)據(jù)傳輸。通過(guò)LED的顏色來(lái)判斷傳輸是否成功。
三、源代碼
1.主函數(shù)及DMA設(shè)置
  1. /*
  2. * Name                : main
  3. * Description         : ---
  4. * Author              : ysloveivy.
  5. *
  6. * History
  7. * --------------------
  8. * Rev                 : 0.00
  9. * Date                : 11/21/2015
  10. *
  11. * create.
  12. * --------------------
  13. */
  14. int main(void)
  15. {
  16.         int i,k;
  17.         DMA_InitTypeDef  DMA_InitStructure;

  18.         led.initialize();
  19.         dma.initialize();

  20.         //測(cè)試DMA,測(cè)試成功藍(lán)燈閃爍,測(cè)試失敗,紅燈閃爍
  21.         DMA_InitStructure.DMA_Channel = DMA_Channel_0;               //選擇通道0
  22.         DMA_InitStructure.DMA_PeripheralBaseAddr = (unsigned long int)src_buffer;  //DMA外設(shè)基地址
  23.         DMA_InitStructure.DMA_Memory0BaseAddr = (unsigned long int)dst_buffer;   //DMA存儲(chǔ)器地址
  24.         DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToMemory;              //方向?yàn)榇鎯?chǔ)器到存儲(chǔ)器
  25.         DMA_InitStructure.DMA_BufferSize = (unsigned long int)BUFFER_SIZE;   //數(shù)據(jù)傳輸量
  26.         DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;    //外設(shè)增量模式
  27.         DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;        //存儲(chǔ)器增量模式
  28.         DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; //設(shè)置外設(shè)數(shù)據(jù)寬度
  29.         DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;    //設(shè)置存儲(chǔ)器數(shù)據(jù)寬度
  30.         DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;            //運(yùn)行模式為普通模式
  31.         DMA_InitStructure.DMA_Priority = DMA_Priority_High;        //優(yōu)先級(jí)級(jí)別為高
  32.         DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;    //FIFO模式禁止
  33.         DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;     //FIFO閾值
  34.         DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;      //存儲(chǔ)器突發(fā)單次傳輸
  35.         DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;   //外設(shè)突發(fā)單次傳輸
  36.         DMA_Init(DMA2_Stream0, &DMA_InitStructure);
  37.         DMA_Cmd(DMA2_Stream0, ENABLE);       //使能DMA2_Stream0                                      

  38.         while(DMA_GetCmdStatus(DMA2_Stream0) != DISABLE);

  39.         for(i = 0;i < BUFFER_SIZE;i++){
  40.                 if(dst_buffer[i] != src_buffer[i]){
  41.                         //測(cè)試失敗
  42.                         while(1){
  43.                                         for(k = 0;k < 10000000;k++);
  44.                                         LED_RED_ON;
  45.                                         for(k = 0;k < 10000000;k++);
  46.                                         LED_RED_OFF;
  47.                         }
  48.                 }
  49. }
  50.         //測(cè)試成功
  51.         while(1){
  52.                 for(k = 0;k < 10000000;k++);
  53.                 LED_BLUE_ON;
  54.                 for(k = 0;k < 10000000;k++);
  55.                 LED_BLUE_OFF;
  56.         }
  57. }
復(fù)制代碼
2DMA初始化函數(shù)
  1. /*
  2. * Name                : initialize
  3. * Description         : ---
  4. * Author              : ysloveivy.
  5. *
  6. * History
  7. * --------------------
  8. * Rev                 : 0.00
  9. * Date                : 11/29/2015
  10. *
  11. * create.
  12. * --------------------
  13. */

  14. static int initialize(void)
  15. {
  16.   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);                             //使能DMA2時(shí)鐘
  17.   DMA_DeInit(DMA2_Stream0);                                                        //配置DMA2
  18.   while (DMA_GetCmdStatus(DMA2_Stream0) != DISABLE)                                //等待DMA可配置
  19.   {
  20.   }

  21.         return 0;
  22. }
復(fù)制代碼
3、小知識(shí)
     在DMA的設(shè)置中我們遇到了關(guān)于DMA設(shè)置的結(jié)構(gòu)體,我們通過(guò)配置其相關(guān)參數(shù),以實(shí)現(xiàn)我們想要的功能,其解釋如下:
  1. typedef struct
  2. {
  3.     uint32_t DMA_Channel;                   //選擇通道
  4.     uint32_t DMA_PeripheralBaseAddr;     //DMA外設(shè)基地址
  5.     uint32_t DMA_Memory0BaseAddr;         //DMA存儲(chǔ)器地址                     
  6.     uint32_t DMA_DIR;                       //DMA傳輸方向
  7.     uint32_t DMA_BufferSize;               //數(shù)據(jù)傳輸量
  8.     uint32_t DMA_PeripheralInc;           //外設(shè)增量模式選擇
  9.     uint32_t DMA_MemoryInc;                //存儲(chǔ)器增量模式
  10.     uint32_t DMA_PeripheralDataSize;     //設(shè)置外設(shè)數(shù)據(jù)寬度
  11.     uint32_t DMA_MemoryDataSize;          //設(shè)置存儲(chǔ)器數(shù)據(jù)寬度
  12.     uint32_t DMA_Mode;                      //運(yùn)行模式選擇
  13.     uint32_t DMA_Priority;                 //優(yōu)先級(jí)選擇
  14.     uint32_t DMA_FIFOMode;                 //FIFO模式選擇
  15.     uint32_t DMA_FIFOThreshold;           //FIFO閥值
  16.     uint32_t DMA_MemoryBurst;             //存儲(chǔ)器突發(fā)單次傳輸
  17.     uint32_t DMA_PeripheralBurst;        //外設(shè)突發(fā)單次傳輸                        
  18. }DMA_InitTypeDef;
復(fù)制代碼
四、實(shí)驗(yàn)現(xiàn)象
      試驗(yàn)成功藍(lán)色LED燈閃爍,試驗(yàn)反敗紅色LED燈閃爍。
五、代碼包下載連接
      網(wǎng)盤(pán):http://pan.baidu.com/s/1bcY5JK



分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:548850 發(fā)表于 2021-10-10 19:49 | 只看該作者
這個(gè)不是stm32f1吧
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表