DMA

開發平臺

  • 野火開發板F429
  • 標準庫

DMA(直接存儲區訪問)

  • DMA可以數據的高效傳輸,數據移動過程無需經過任何CPU的操作和控制。
  • F4支持:存儲器到存儲器、存儲器到外設、外設到存儲器
  • F4有兩個DMA控制器:DMA1和DMA2,只有DMA2才支持存儲器到存儲器

DMA架構

在這裏插入圖片描述

  • 1、外設通道選擇(每個數據流的每個通道有對應的外設,不過有一些是沒有的)
  • 2、數據流的選擇
  • 3、仲裁器,當有個多個外設同時請求一個DMA控制器時,這時就要分先後了,仲裁器的作用就在這裏了。所以要設置優先級(較高優先級、高優先級、中優先級、低優先級),若優先級相等時,就看數據流序號,序號越小優先級越高
  • 4、FIFO:DMA傳輸分爲直接模式(當DMA使能後直接傳輸數據)、FIFO模式(當閾值滿後,才一次過傳輸)就有了突發傳輸
  • 存儲器端口
  • 外設端口

寄存器

看手冊
在這裏插入圖片描述

  • 前面四個就是中斷標誌位以及清除中斷標誌位
  • 數據流配置寄存器(SxCR),配置通道、優先級、存儲器數據寬度、外設數據寬度等等
  • 外設地址寄存器(SxPAR),外設的數據地址或者存儲器的目標地址
  • 存儲器0地址寄存器/存儲器1地址寄存器,存儲器源地址,存儲器1地址寄存器只用於雙緩衝區模式
  • FIFO控制寄存器:使能失能直接模式、設置FIFO閾值
  • 數據項數寄存器(SxNDTR),可以讀取該寄存器,得知數據傳輸到哪
    在這裏插入圖片描述
    在這裏插入圖片描述

存儲器到外設

1.配置DMA參數即可

  • DMA_GetCmdStatus(),只有當數據傳輸完成後纔會被有效禁用,表示數據傳輸完成

代碼如下:

void DMA_MTP_Config(void)
{
    
    DMA_InitTypeDef DMA_InitStruct;
    /*打開時鐘*/
    RCC_AHB1PeriphClockCmd(DMA2_CLOCK,ENABLE);
    /*復位初始化DMA數據流*/
    DMA_DeInit(DMA_USART_STREAM);

    while(DMA_GetCmdStatus(DMA_USART_STREAM)==ENABLE);

    /*
    **通道7
    **方向 寄存器到外設
    **DMA寄存器數據寬度:字節(8位)
    **DMA外設寬度:字節(8位)
    **fifo模式不開
    **寄存器地址:發送數據的首地址
    **外設地址:數據寄存器地址
    **寄存器:單次傳輸
    **外設:單次傳輸
    **寄存器地址自動遞增
    **外設地址:不需要
    **循環模式
    **優先級爲高
    */
    DMA_InitStruct.DMA_Channel=DMA_USART_CHANNLE;
    DMA_InitStruct.DMA_DIR=DMA_DIR_MemoryToPeripheral;
    DMA_InitStruct.DMA_MemoryDataSize=DMA_MemoryDataSize_Byte;
    DMA_InitStruct.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte;
    DMA_InitStruct.DMA_BufferSize=BUFFER_SIZE;
    DMA_InitStruct.DMA_FIFOMode=DMA_FIFOMode_Disable;
    DMA_InitStruct.DMA_FIFOThreshold=DMA_FIFOThreshold_Full;
    DMA_InitStruct.DMA_Memory0BaseAddr=(u32)senddata;
    DMA_InitStruct.DMA_PeripheralBaseAddr=USART_DR_BASE;
    DMA_InitStruct.DMA_MemoryBurst=DMA_MemoryBurst_Single;
    DMA_InitStruct.DMA_PeripheralBurst=DMA_PeripheralBurst_Single;
    DMA_InitStruct.DMA_MemoryInc=DMA_MemoryInc_Enable;
    DMA_InitStruct.DMA_PeripheralInc=DMA_PeripheralInc_Disable;
    DMA_InitStruct.DMA_Mode=DMA_Mode_Circular;
    DMA_InitStruct.DMA_Priority=DMA_Priority_High;
    DMA_Init(DMA_USART_STREAM,&DMA_InitStruct);

    DMA_Cmd(DMA_USART_STREAM,ENABLE);

    while(DMA_GetCmdStatus(DMA_USART_STREAM)==DISABLE);
}
發佈了17 篇原創文章 · 獲贊 20 · 訪問量 5214
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章