tft每日頭條

 > 生活

 > stm32的dma數組格式

stm32的dma數組格式

生活 更新时间:2024-10-14 18:11:58
11.1 DMA控制器簡介

在上一章節有用到DMA控制器,在這邊文章進行一個說明,看完這章可以回頭看看10 玩轉STM32之通用同步異步收發器(USART)将會有一定的了解。什麼是DMA,DMA的作用又是什麼以及控制方式是什麼,本章将會對這方面進行講解。

1、什麼是DMA

DMA就是 直接存儲器訪問,英文的全名是Direct Memory Access。

2、DMA的作用

他的作用就是為MCU減輕負擔的。

這裡說一下具體是怎麼樣的。1- DMA傳輸将數據從一個地址空間複制到另一個地址空間。當CPU初始化這個傳輸動作,傳輸動作本身是由DMA控制器來實現和完成的。2-DMA傳輸方式無需CPU直接控制傳輸,也沒有中斷處理方式那樣保留現場和恢複現場過程,通過硬件為RAM和IO設備開辟一條直接傳輸數據的通道,使得CPU的效率大大提高。根據下圖可以直觀的知道DMA的控制方式。DMA有三種控制方式,圖1是一個總的控制,圖二是三種不同的控制。

stm32的dma數組格式(11-玩轉STM32之直接存儲器訪問)1

圖21-外設-->存儲器

stm32的dma數組格式(11-玩轉STM32之直接存儲器訪問)2

2-存儲器-->外設

stm32的dma數組格式(11-玩轉STM32之直接存儲器訪問)3

3-存儲器-->存儲器

stm32的dma數組格式(11-玩轉STM32之直接存儲器訪問)4

3、對于STM32F429來說:

① STM32F429最多有2個DMA控制器(DMA1和DMA2 );② 2個DMA控制器總共有16個數據流(每個控制器8個);③每個DMA控制器都用于管理一個或者多個外設的存儲器訪問請求;④每個數據流總共可以有多達8個通道(或請求),每個通道都有一個仲裁器,用于處理DMA請求間的優先級。

DMA的主要特性

stm32的dma數組格式(11-玩轉STM32之直接存儲器訪問)5

11.1.1 結構

STM32F4全系列的DMA結構如下圖所示:

stm32的dma數組格式(11-玩轉STM32之直接存儲器訪問)6

從圖中可以看出,每個DMA有兩個AHB主總線,一個是用來訪問存儲器,一個是用來進行外設訪問的。這裡說下主要的,要想實現存儲器到存儲器之間的傳輸,AHB外設也必須支持訪問存儲器,所以在這裡隻有DMA2可以實現

11.2 DMA控制器功能11.2.1 DMA 事務

DMA 事務由給定數目的數據傳輸序列組成。要傳輸的數據項的數目及其寬度(8 位、16 位 或 32 位)可用軟件編程。每個 DMA 傳輸包含三項操作:

①數據源:通過 DMA_SxPAR 或 DMA_SxM0AR 寄存器尋址,從外設數據寄存器或存儲器單元中加載數據。②輸出目的地:通過DMA_SxPAR 或 DMA_SxM0AR 寄存器尋址,将加載的數據存儲到外設數據寄存器或存儲器單元③數據量:DMA_SxNDTR 計數器在數據存儲結束後遞減,該計數器中包含仍需執行的事務數

1.傳輸模式

源傳輸和目标傳輸在整個4GB區域(地址在0X00000000和0XFFFFFFFF之間)都可以尋址外設和存儲器。傳輸方向使用DMA_SxCR中的DIR[1:0]位進行配置,有3種可能的傳輸方向:存儲器到外設、外設到存儲器或存儲器到存儲器。DMA傳輸模式如下所示。

stm32的dma數組格式(11-玩轉STM32之直接存儲器訪問)7

stm32的dma數組格式(11-玩轉STM32之直接存儲器訪問)8

内部結構體:

stm32的dma數組格式(11-玩轉STM32之直接存儲器訪問)9

2.可編程的數據量

源和目标數據的數據寬度可以通過DMA_SxCR的PSIZE和MSIZE位(可以是8位,16位、32位)編程。

3.指針增量

通過設置DMA_SxCR中的PINC和MINC标志位,外設和存儲器的指針在每次傳輸後可以有選擇地完成自動增量。通過單個寄存器訪問外設源或目标數據時,一般需要禁止通增模式。當設置為增量模式時,下一個要傳輸的地址将是前一個地址加上增量值,增量值取決于所選的數據寬度(1、2或4)。第一個傳輸的地址是存放在DMA SxMOAR和DMA SxPAR中的地址。在傳輸過程中,這些寄存器保持它們初始的數值,軟件不能改變和讀出當前正在傳輸的地址。當通道配置為非循環模式時,傳輸結束後(即傳輸計數變為0)将不再産生DMA操作。要開始新的DMA傳輸,需要在關閉DMA通道的情況下,在DMA SxNDTR中重新寫入傳輸數目。在循環模式下,最後一次傳輸結束時,DMA_SxNDTR的内容會自動地被重新加載為其初始數值,内部的當前存儲器和外設地址寄存器也被重新加載為DMA_SxMOAR和DMA_SxPAR設定的初始基地址。

11.2.2 數據流

stm32的dma數組格式(11-玩轉STM32之直接存儲器訪問)10

11.2.3 通道

stm32的dma數組格式(11-玩轉STM32之直接存儲器訪問)11

DMA映射關系:

stm32的dma數組格式(11-玩轉STM32之直接存儲器訪問)12

stm32的dma數組格式(11-玩轉STM32之直接存儲器訪問)13

11.2.4 仲裁

仲裁器為兩個AHB主端口(存儲器和外設端口)提供基于請求優先級的8 個DMA數據流請求管理,并啟動外設/存儲器訪問序列。優先級管理分為兩個階段: ①軟件:每個數據流優先級都可以在 DMA_SxCR 寄存器中配置。分為四個級别: — 非常高優先級 — 高優先級 — 中優先級 — 低優先級 ②硬件:如果兩個請求具有相同的軟件優先級,則編号低的數據流優先于編号高的數據流。例如,數據流 2 的優先級高于數據流 4。

stm32的dma數組格式(11-玩轉STM32之直接存儲器訪問)14

11.2.5 循環模式

循環模式可用于處理循環緩沖區和連續數據流(例如 ADC 掃描模式)。可以使用 DMA_SxCR寄存器中的 CIRC 位使能此特性。

當激活循環模式時,要傳輸的數據項的數目在數據流配置階段自動用設置的初始值進行加載,并繼續響應 DMA 請求。

stm32的dma數組格式(11-玩轉STM32之直接存儲器訪問)15

11.2.6 單次和突發模式

DMA控制器可以産生單次傳輸或4個、8個和16個節拍(8位、16位或32位,由PSIZE和MSIZE決定)的突發傳輸。

例如,如果将PSIZE和MSIZE都設置為01(将數據傳輸的寬度設置為16位),那麼啟動一次4個節拍的突發傳輸,DMA控制器會再突發傳輸4×16位(8字節)的數據,而且在這一突發傳輸過程(4個半字傳輸過程)中,不釋放對總線的控制權。

11.2.7 FIFO

①FIFO 用于在源數據傳輸到目标之前臨時存儲這些數據。②FIFO的大小是4*4字節,傳輸的過程為:源地址→AHB主端口x→FIFO→AHB主端口y→目的地址。是否使用FIFO門限,可以區别FIFO模式和Direct模式。③FIFO常用于DMA控制器和Memories之間的緩沖。Memory-to-Memory,是必須使用FIFO模式的。④FIFO模式和Direct模式的區别:FIFO模式——從源地址來的數據先放在FIFO中,達到門限後,再根據目的地址的數據寬度送出;Direct模式——數據放在FIFO,有DMA請求就送走,和門限值無關。不可突發傳輸

11.2.8 DMA中斷

對于每個 DMA 數據流,可在發生以下事件時産生中斷: ①達到半傳輸 ②傳輸完成 ③傳輸錯誤④FIFO 錯誤(上溢、下溢或 FIFO 級别錯誤) ⑤直接模式錯誤

stm32的dma數組格式(11-玩轉STM32之直接存儲器訪問)16

11.2.9 DMA數據流配置過程

(1)複位數據流使能位EN,并檢測是否設置成功。(2)設置外設端寄存器地址(3)設置存儲器地址(4)設置DMA傳輸數據量(5)選擇數據流使用的通道(6)設置數據流優先級(7)配置FIFO的使用情況(8)配置數據傳輸方向、外設和存儲器增量/固定模式、單獨/突發事務、外設和存儲器數據寬度、循 環模式、雙緩沖區模式、傳輸完成一半/全部完成,和/或DMA_SxCR中錯誤的中斷。(9)通過将DMA_SxCR中的EN位置1激活數據流。如果使用到了外設的話,還需要使能相應外設的DMA請求功能。

11.3 DMA典型應用步驟及常用庫函數11.3.1 DMA典型應用步驟

以配置串口1的發送為DMA方式為例

> /**************先将串口功能配置好!****************/ > ① 使能DMA時鐘 RCC_AHB1PeriphClockCmd(); ② 複位DMA配置,并檢測何時EN位變為0,可以對其進行初始化 DMA_DeInit(); ③ 初始化DMA通道參數 DMA_Init(); ④ 使能DMA流 DMA_Cmd(); ⑤ 查詢DMA的EN位,确保數據流就緒,可以配置 DMA_GetCmdStatus(); ⑥ 使能串口DMA發送,串口DMA使能函數 USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);

DMA配置涉及到的一下參數:優先級數據傳輸方向存儲器/外設 數據寬度存儲器/外設 地址是否增量循環模式數據傳輸量

10.3.2 常用庫函數1、通用函數

/*stm32f4xx_dma.c stm32f4xx_dma.h*/ ①/*初始化DMA工作方式 */ void DMA_Init(DMA_Stream_TypeDef* DMAy_Streamx, DMA_InitTypeDef* DMA_InitStruct); ②/*使能或禁止DMA數據流 */ void DMA_Cmd(DMA_Stream_TypeDef* DMAy_Streamx, FunctionalState NewState); ③/*設置DMA傳輸數據量 */ void DMA_SetCurrDataCounter(DMA_Stream_TypeDef* DMAy_Streamx, uint16_t Counter); ④/*獲取當前DMA數據量 */ uint16_t DMA_GetCurrDataCounter(DMA_Stream_TypeDef* DMAy_Streamx); ⑤/*獲取DMA數據流是否能用 */ FunctionalState DMA_GetCmdStatus(DMA_Stream_TypeDef* DMAy_Streamx); ⑥/*清除DMA數據流相應标志位 */ void DMA_ClearFlag(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_FLAG); ⑦/*設置DMA數據流中斷 */ void DMA_ITConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT, FunctionalState NewState); ⑧/*獲取DMA數據流中斷标志 */ ITStatus DMA_GetITStatus(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT); ⑨/*清除DMA數據流中斷标志 */ void DMA_ClearITPendingBit(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT);

stm32的dma數組格式(11-玩轉STM32之直接存儲器訪問)17

2、常用的外設DMA使能庫函數

①void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq,FunctionalState NewState); ②void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState); ③void DAC_DMACmd(uint32_t DAC_Channel, FunctionalState NewState); ④void I2C_DMACmd(I2C_TypeDef* I2Cx, FunctionalState NewState); ⑤void SDIO_DMACmd(FunctionalState NewState); ⑥void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState); ⑦void TIM_DMAConfig(TIM_TypeDef* TIMx, uint16_t TIM_DMABase,uint16_t TIM_DMABurstLength) void TIM_DMACmd(TIM_TypeDef* TIMx, uint16_t TIM_DMASource,FunctionalState NewState);

11.4應用

使用DMA實現兩塊存儲器之間數據搬移。

要想實現存儲器與存儲器之間的數據DMA傳輸,隻能使用DMA2控制器的數據流0(DMA2_Stream0)。

stm32的dma數組格式(11-玩轉STM32之直接存儲器訪問)18

1.編程要點

(1)使能DMA2的工作時鐘。(2)複位DMA2_Stream0,并判斷何時複位成功。配置DMA前,需要先禁止DMA。如果上次DMA操作沒有結束,需要進行判斷等待。(3)根據需求,初始化DMA2_Stream0。(4)使能DMA2_Stream0。(5)判斷DMA2_Stream0是否使能成功

2.主程序

const uint32_t SRC_Buffer[16]= { 0x11111111, 0x22222222, 0x33333333, 0x44444444, 0x55555555, 0x66666666, 0x77777777, 0x88888888, 0x99999999, 0xaaaaaaaa, 0xbbbbbbbb, 0xcccccccc, 0xdddddddd, 0xeeeeeeee, 0xffffffff, 0x5a5a5a5a }; //DMA傳輸源存儲塊 uint32_t DST_Buffer[16]; //DMA傳輸目标存儲塊 int main(void) { DMA_Config(); //DMA初始化,并啟動DMA傳輸 /*等待DMA傳輸完成*/ while(DMA_GetFlagStatus(DMA_STREAM,DMA_FLAG_TCIF0)==DISABLE); /*比對DMA傳輸結束後,源存儲單元和目标存儲單元内容是否一緻*/ if(memcmp(SRC_Buffer, DST_Buffer, 16)==0) //完全一緻,使用memcmp需要包含string.h { //傳輸成功,沒有數據錯誤 } else //傳輸過程中有數據出錯 { //出錯處理 } while (1); }

3 DMA配置

void DMA_Config(void) { DMA_InitTypeDef DMA_InitStructure;  /*-------------------第1步--------------------*/  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE); //使能DMA2時鐘    /*-------------------第2步--------------------*/  DMA_DeInit(DMA2_Stream0); //複位,禁止DMA2_Stream0  while (DMA_GetCmdStatus(DMA2_Stream0)!= DISABLE); //确保DMA數據流禁止成功  /*-------------------第3步--------------------*/  /*開始初始化DMA2_Stream0*/  DMA_InitStructure.DMA_Channel=DMA_Channel_0; //選擇通道  DMA_InitStructure.DMA_PeripheralBaseAddr=(uint32_t) SRC_Buffer; //數據源地址  DMA_InitStructure.DMA_Memory0BaseAddr=(uint32_t)DST_Buffer; //目标地址  DMA_InitStructure.DMA_DIR=DMA_DIR_MemoryToMemory; //存儲器到存儲器模式  DMA_InitStructure.DMA_BufferSize =16;  DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Enable;//使能外設端自動遞增功能  DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable; //使能存儲器端自動遞增功能  DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Word; //32位寬度  DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_Word; //32位寬度  DMA_InitStructure.DMA_Mode=DMA_Mode_Normal; //正常模式,不循環,隻傳輸一次  DMA_InitStructure.DMA_Priority=DMA_Priority_High; //設置DMA2_Stream優先級為高  DMA_InitStructure.DMA_FIFOMode=DMA_FIFOMode_Disable; //禁用FIFO模式  DMA_InitStructure.DMA_FIFOThreshold=DMA_FIFOThreshold_Full; //此時這一參數無用  DMA_InitStructure.DMA_MemoryBurst=DMA_MemoryBurst_Single; //單次模式  DMA_InitStructure.DMA_PeripheralBurst=DMA_MemoryBurst_Single; //單次模式  DMA_Init(DMA2_Stream0, &DMA_InitStructure); //完成DMA2_Stream0配置   /*-------------------第4步--------------------*/ DMA_Cmd(DMA2_Stream0, ENABLE); //使能DMA2_Stream0,啟動DMA數據傳輸 /*-------------------第5步--------------------*/ while(DMA_GetCmdStatus(DMA2_Stream0) != ENABLE) //檢測DMA數據流是否有效 { } }

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关生活资讯推荐

热门生活资讯推荐

网友关注

Copyright 2023-2024 - www.tftnews.com All Rights Reserved