《STM32从零开始学习历程》——DMA直接存储区访问理论知识
《STM32從零開始學(xué)習(xí)歷程》@EnzoReventon
DMA—直接存儲(chǔ)區(qū)訪問理論知識(shí)
本文主要介紹STM32F4 DMA直接存儲(chǔ)區(qū)的理論知識(shí)部分,本文主要參考手冊(cè)為:
[野火EmbedFire]《STM32庫開發(fā)實(shí)戰(zhàn)指南——基于野火霸天虎開發(fā)板》
[正點(diǎn)原子]STM32F4開發(fā)指南-庫函數(shù)版本_V1.2
[ST]《STM32F4xx中文參考手冊(cè)》
在學(xué)習(xí)野火教程第22章的基礎(chǔ)上進(jìn)行理解、解讀與拓展,爭(zhēng)取以一種比較好理解的簡(jiǎn)述方式向大家介紹這一內(nèi)容。
1. DMA簡(jiǎn)介
DMA(Direct Memory Access, 直接存儲(chǔ)區(qū)訪問)是一種獨(dú)立于CPU的控制器。它的主要功能是實(shí)現(xiàn)數(shù)據(jù)在“外設(shè)寄存器與存儲(chǔ)器之間”、“存儲(chǔ)器與存儲(chǔ)器之間”獨(dú)立于CPU的高速傳輸。
在這里,外設(shè)一般指外設(shè)的數(shù)據(jù)寄存器(如ADC,SPI,I2C,DCMI等外設(shè)的數(shù)據(jù)寄存器);存儲(chǔ)器一般是指片內(nèi)SRAM、外部存儲(chǔ)器、片內(nèi)FLASH等。
① 外設(shè)寄存器到存儲(chǔ)器傳輸:就是把外設(shè)數(shù)據(jù)寄存器內(nèi)容轉(zhuǎn)移到指定的內(nèi)存空間中。
② 存儲(chǔ)器到外設(shè)寄存器傳輸:就是把特定存儲(chǔ)區(qū)域的內(nèi)容轉(zhuǎn)移到外設(shè)寄存器中。
③ 存儲(chǔ)器到存儲(chǔ)器傳輸:就是把一個(gè)指定存儲(chǔ)區(qū)內(nèi)容拷貝到另一個(gè)指定的存儲(chǔ)區(qū)中。
注意: DMA1 僅支持① ② ,不支持③。,DMA2支持① ② ③。
=============================================================================================
解釋一下為什么DMA1不支持存儲(chǔ)器到存儲(chǔ)器的傳輸:
如上圖所示,DMA2控制器ANB接口都與中間的總線矩陣相連接了,存儲(chǔ)器RAM與總線矩陣相連接,因此DMA2可以實(shí)現(xiàn)存儲(chǔ)器與存儲(chǔ)器之間的數(shù)據(jù)傳輸。
而DMA1,其中一個(gè)AHB接口沒有與總線矩陣相連接,固然也就無法實(shí)現(xiàn)存儲(chǔ)器與存儲(chǔ)器之間的數(shù)據(jù)傳輸了。
作為一個(gè)固定的知識(shí)點(diǎn)記住就好。
2. DMA的主要特點(diǎn)(針對(duì)STM32F4)
3. 功能框圖分析
STM32F4其中一個(gè)的DMA控制器框圖如上圖所示,下面我們來詳細(xì)講解一下這個(gè)框圖。(STM32一共有兩個(gè)DMA控制器)
=============================================================================================
在上圖中,左邊的叫做通道,右邊的叫做流。
好了,那么問題來了,什么是“通道”?什么是“流”?
首先,“流”是數(shù)據(jù)傳輸?shù)囊粭l鏈路,“通道”:emmm不知道怎么解釋,只可意會(huì)不可言傳,不同的通道對(duì)印著不同的DMA請(qǐng)求。
緊接著,從上圖看到,對(duì)于一個(gè)DMA控制器共有8路“流”,每一“流”,又有8個(gè)“通道”!也就是說,對(duì)于一個(gè)DMA控制共有8 x 8 = 64 路通道可以用來獨(dú)立的傳輸數(shù)據(jù)。
好了又有問題來了,那么這么多通道怎么用?是不是可以隨便用?
答案是否定的!
每一個(gè)通道有著不同的傳輸請(qǐng)求映射!如下表所示:
DMA1:
| 通道 0 | SPI3_RX | SPI3_RX | SPI2_RX | SPI2_TX | SPI3_TX | SPI3_TX | ||
| 通道 1 | I2C1_RX | TIM7_UP | TIM7_UP | I2C1_RX | I2C1_TX | I2C1_TX | ||
| 通道 2 | TIM4_CH1 | I2S3_EXT_RX | TIM4_CH2 | CH2 I2S2_EXT_TX | I2S3_EXT_TX | TIM4_UP | TIM4_CH3 | |
| 通道 3 | I2S3_EXT_RX | TIM2_UP TIM2_CH3 | I2C3_RX | I2S2_EXT_RX | I2C3_TX | TIM2_CH1 | TIM2_CH2 TIM2_CH4 | TIM2_UP TIM2_CH4 |
| 通道 4 | UART5_RX | USART3_RX | UART4_RX | USART3_TX | UART4_TX | USART2_RX | USART2_TX | UART5_TX |
| 通道 5 | UART8_TX | UART7_TX | TIM3_CH4 TIM3_UP | UART7_RX | TIM3_CH1 TIM3_TRIG | TIM3_CH2 | UART8_RX | TIM3_CH3 |
| 通道 6 | TIM5_CH3 TIM5_UP | TIM5_CH4 TIM5_TRIG | TIM5_CH1 | TIM5_CH4 TIM5_TRIG | TIM5_CH2 | TIM5_UP | ||
| 通道 7 | TIM6_UP | I2C2_RX | I2C2_RX | USART3_TX | DAC1 | DAC2 | I2C2_TX |
DMA2:
| 通道 0 | ADC1 | TIM8_CH1 TIM8_CH2 TIM8_CH3 | ADC1 | TIM1_CH1 TIM1_CH2 TIM1_CH3 | ||||
| 通道 1 | DCMI | ADC2 | ADC2 | SPI6_TX | SPI6_RX | DCMI | ||
| 通道 2 | ADC3 | ADC3 | SPI5_RX | SPI5_TX | CRYP_OUT | CRYP_IN | HASH_IN | |
| 通道 3 | SPI1_RX | SPI1_RX | SPI1_TX | SPI1_TX | ||||
| 通道 4 | SPI4_RX | SPI4_TX | USART1_RX | SDIO | SART1_RX | SDIO | USART1_TX | |
| 通道 5 | USART6_RX | USART6_RX | SPI4_RX | SPI4_TX | USART6_TX | USART6_TX | ||
| 通道 6 | TIM1_TRIG | TIM1_CH1 | TIM1_CH2 | TIM1_CH1 | TIM1_CH4 TIM1_TRIG TIM1_COM | TIM1_UP | TIM1_CH3 | |
| 通道 7 | TIM8_UP | TIM8_CH1 | TIM8_CH2 | TIM8_CH3 | SPI5_RX | SPI5_TX | TIM8_CH4 TIM8_TRIG TIM8_COM |
每個(gè)外設(shè)請(qǐng)求都會(huì)占用一個(gè)數(shù)據(jù)流通道,相同外設(shè)請(qǐng)求可以占用不同的數(shù)據(jù)流通道。
例如:DMA1的數(shù)據(jù)流0,我選擇使用通道2 I2C1_RX,那么其他7路通道就不可以使用了。
再例如:DMA1的數(shù)據(jù)流2,通道1,TIM7_UP與DMA1的數(shù)據(jù)流4,通道1,TIM7_UP是可以同時(shí)使用的。也就是說只要不是同一個(gè)數(shù)據(jù)流就可以了。
好了,通道 和 流 的基本信息就已經(jīng)介紹完了,總結(jié)一下:
① STM32F4共有2個(gè)DMA控制器
② DMA1不支持存儲(chǔ)器到存儲(chǔ)器傳輸
③ 每一個(gè)DMA有8路數(shù)據(jù)流
④ 每一路流有8個(gè)通道
⑤ 每一個(gè)通道有特定的功能映射,需要查閱上文的表格進(jìn)行選擇使用
⑥ 每一路流的只能有一個(gè)通道使用,一路流有一個(gè)以上通道使用是不允許的
⑦ 相同功能不同流的通道可以同時(shí)使用
=============================================================================================
顧名思義,仲裁器是用來仲裁、評(píng)判的,一個(gè)DMA控制器有8個(gè)數(shù)據(jù)流,如果在某一時(shí)刻,我們使用同一個(gè)DMA控制器中的多個(gè)數(shù)據(jù)流進(jìn)行傳輸數(shù)據(jù),那么必然會(huì)導(dǎo)致有多個(gè)數(shù)據(jù)流,如果沒有仲裁器,就像是十字路口沒有紅綠燈,會(huì)造成擁堵甚至事故,對(duì)于數(shù)據(jù)也是如此,因此需要一個(gè)仲裁器來設(shè)定數(shù)據(jù)流的優(yōu)先傳輸?shù)臋?quán)力。
通過仲裁器來設(shè)定流的優(yōu)先級(jí)時(shí)分為兩個(gè)階段,第一階段為軟件階段,第二階段為硬件階段。
軟件階段: 用戶可以通過配置優(yōu)先級(jí)寄存器,將數(shù)據(jù)流優(yōu)先級(jí)設(shè)定為:非常高,高,中和低四個(gè)級(jí)別。
硬件階段: 如果兩個(gè)或以上數(shù)據(jù)流的優(yōu)先級(jí)一樣,則仲裁器優(yōu)先級(jí)設(shè)定轉(zhuǎn)為硬件層面,他們的優(yōu)先級(jí)取決于數(shù)據(jù)流的編號(hào),編號(hào)越低則優(yōu)先級(jí)越高,例如,在軟件層面優(yōu)先級(jí)相同的情況下,數(shù)據(jù)流1的優(yōu)先級(jí)高于數(shù)據(jù)流5的優(yōu)先級(jí)。
=============================================================================================
我們要重點(diǎn)的來講一下什么是FIFO,First In First Out。
首先,FIFO叫做先進(jìn)先出存儲(chǔ)緩沖區(qū),它介于源與目標(biāo)之間,是一個(gè)數(shù)據(jù)的中轉(zhuǎn)站。
每一個(gè)數(shù)據(jù)流都有4字大小的FIFO。1字 = 4字節(jié) = 32位,4字 = 16字節(jié)。
對(duì)于這個(gè)緩沖區(qū),存在有兩種數(shù)據(jù)傳輸模式:第一種為直接模式,第二種為FIFO模式。
模式的選擇由 DMA_SxFCR寄存器的DMDIS位控制,0為使能直接模式,1為禁止直接模式、開啟FIFO模式。
直接模式: 數(shù)據(jù)經(jīng)過FIFO,不在FIFO中停留,直接將數(shù)據(jù)傳送到目標(biāo)地址中。
FIFO模式: 數(shù)據(jù)經(jīng)過FIFO,在FIFO中停留,根據(jù)設(shè)置的閾值,等到數(shù)據(jù)量達(dá)到了設(shè)定的閾值然后再發(fā)送到目標(biāo)地址中。閾值可以設(shè)定為1/4,1/2,3/4,1。例如,閾值設(shè)定為1/4時(shí),FIFO中的數(shù)據(jù)量達(dá)到16*(1/4)= 4 字節(jié)時(shí)將數(shù)據(jù)打包發(fā)送到目標(biāo)地址中。
對(duì)于在FIFO中的數(shù)據(jù),是以什么方式進(jìn)行傳輸?shù)哪?#xff1f;例如,閾值設(shè)定為1/4時(shí),FIFO中也存滿了4字節(jié)的數(shù)據(jù),這4字節(jié)的數(shù)據(jù)怎么打包發(fā)送呢?它是4字節(jié)全部打包發(fā)送還是4字節(jié)分四次打包發(fā)送呢?這就需要另外一個(gè)寄存器進(jìn)行選擇配置了:DMA_SxCR中的MBURST(存儲(chǔ)器突發(fā)傳輸配置)以及PBURST(外設(shè)突發(fā)傳輸配置),突發(fā)模式!
下一章節(jié)將詳細(xì)的講解何為突發(fā)模式!
4. DMA數(shù)據(jù)配置
1. 突發(fā)&節(jié)拍的配置
位 24:23 MBURST:存儲(chǔ)器突發(fā)傳輸配置 (Memory burst transfer configuration)
這些位將由軟件置 1 和清零。
00:單次傳輸
01:INCR4(4 個(gè)節(jié)拍的增量突發(fā)傳輸)
10:INCR8(8 個(gè)節(jié)拍的增量突發(fā)傳輸)
11:INCR16(16 個(gè)節(jié)拍的增量突發(fā)傳輸)
這些位受到保護(hù),只有 EN 為“0”時(shí)才可以寫入 在直接模式中,當(dāng)位EN=“1”時(shí),這些位由硬件強(qiáng)制置為 0x0。
位 22:21 PBURST[1:0]:外設(shè)突發(fā)傳輸配置 (Peripheral burst transfer configuration)
這些位將由軟件置 1 和清零。
00:單次傳輸
01:INCR4(4 個(gè)節(jié)拍的增量突發(fā)傳輸)
10:INCR8(8 個(gè)節(jié)拍的增量突發(fā)傳輸)
11:INCR16(16 個(gè)節(jié)拍的增量突發(fā)傳輸)
這些位受到保護(hù),只有 EN為“0”時(shí)才可以寫入 在直接模式下,這些位由硬件強(qiáng)制置為 0x0。
這里又來了一個(gè)“節(jié)拍”的概念,我們來詳細(xì)的講一下這是什么。
| 字節(jié) | 1/4 | 4個(gè)節(jié)拍1次突發(fā) | – | – |
| 字節(jié) | 1/2 | 4個(gè)節(jié)拍2次突發(fā) | 8個(gè)節(jié)拍1次突發(fā) | – |
| 字節(jié) | 3/4 | 4個(gè)節(jié)拍3次突發(fā) | – | – |
| 字節(jié) | 1 | 4個(gè)節(jié)拍4次突發(fā) | 8個(gè)節(jié)拍2次突發(fā) | 16個(gè)節(jié)拍1次突發(fā) |
| 半字 | 1/4 | – | – | – |
| 半字 | 1/2 | 4個(gè)節(jié)拍1次突發(fā) | – | – |
| 半字 | 3/4 | – | – | – |
| 半字 | 1 | 4個(gè)節(jié)拍2次突發(fā) | 8個(gè)節(jié)拍1次突發(fā) | – |
| 字 | 1/4 | – | – | – |
| 字 | 1/2 | – | – | – |
| 字 | 3/4 | – | – | – |
| 字 | 1 | 4個(gè)節(jié)拍1次突發(fā) | – | – |
首先,FIFO大小為4個(gè)字,FIFO閾值 = FIFO級(jí)別 x FIFO大小。
例如:
FIFO級(jí)別為1/4時(shí),FIFO閾值大小為 4 x(1/4) = 1字 = 4字節(jié)。
FIFO級(jí)別為3/4時(shí),FIFO閾值大小為 4 x(3/4) = 3字 = 12字節(jié)。
=============================================================================================
當(dāng)目標(biāo)地址存儲(chǔ)單元為字節(jié)時(shí):
FIFO級(jí)別為1/4時(shí):
當(dāng)FIFO中存滿4 x(1/4) = 1字 = 4字節(jié)時(shí),完成1次突發(fā),4字節(jié)數(shù)據(jù)一次性打包發(fā)送給目標(biāo)地址,每次發(fā)送4個(gè)字節(jié)。
FIFO級(jí)別為1/2時(shí):
當(dāng)FIFO中存滿4 x(1/2) = 2字 = 8字節(jié)時(shí),完成2次突發(fā),8字節(jié)數(shù)據(jù)分兩次發(fā)送給目標(biāo)地址,每次發(fā)送4個(gè)字節(jié);
或者8字節(jié)數(shù)據(jù)一次性發(fā)送給目標(biāo)地址,每次發(fā)送8個(gè)字節(jié)。
FIFO級(jí)別為3/4時(shí):
當(dāng)FIFO中存滿4 x(3/4) = 3字 = 12字節(jié)時(shí),完成3次突發(fā),12字節(jié)數(shù)據(jù)分三次發(fā)送給目標(biāo)地址,每次發(fā)送4個(gè)字節(jié)。
FIFO級(jí)別為1時(shí):
當(dāng)FIFO中存滿4 x 1 = 4字 = 16字節(jié)時(shí),可以以4次突發(fā),16字節(jié)數(shù)據(jù)分四次發(fā)送給目標(biāo)地址,每次發(fā)送4個(gè)字節(jié);
可以以2次突發(fā),16字節(jié)數(shù)據(jù)分兩次發(fā)送給目標(biāo)地址,每次發(fā)送8個(gè)字節(jié);
也可以以1次突發(fā),16字節(jié)數(shù)據(jù)一次性傳輸給目標(biāo)地址,每次發(fā)送16個(gè)字節(jié)。
=============================================================================================
為什么FIFO級(jí)別為1/4時(shí)不能以8個(gè)節(jié)拍進(jìn)行發(fā)送呢?
因?yàn)?#xff0c;FIFO的級(jí)別為1/4,其閾值為1個(gè)字,4個(gè)字節(jié),此時(shí)FIFO存滿也就4個(gè)字節(jié)的數(shù)據(jù),固然無法實(shí)現(xiàn)8個(gè)節(jié)拍進(jìn)行發(fā)送。
為什么MSIZE為半字時(shí),無法實(shí)現(xiàn)FIFO的級(jí)別為1/4以4個(gè)字節(jié)發(fā)送?
因?yàn)?#xff0c;FIFO的級(jí)別為1/4,其閾值為1個(gè)字,4個(gè)字節(jié);如果是4個(gè)節(jié)拍發(fā)送的話,就是4個(gè)半字=8個(gè)字節(jié)發(fā)送,此時(shí)FIFO最大也就只有4個(gè)字節(jié)的數(shù)據(jù),也便無法實(shí)現(xiàn)發(fā)送。
為什么MSIZE為字時(shí),無法實(shí)現(xiàn)FIFO的級(jí)別為3/4以3個(gè)字節(jié)發(fā)送?
因?yàn)?#xff0c;FIFO的級(jí)別為3/4,其閾值為3個(gè)字,12個(gè)字節(jié);如果實(shí)現(xiàn)4個(gè)節(jié)拍發(fā)送的畫,就是4個(gè)字=16個(gè)字節(jié)發(fā)送,此時(shí)FIFO最大也就12個(gè)字節(jié)的數(shù)據(jù),無法實(shí)現(xiàn)發(fā)送。
下面再來解釋下為什么為什么MSIZE為半字時(shí),可以實(shí)現(xiàn)FIFO的級(jí)別為1/2以8個(gè)字節(jié)發(fā)送?
因?yàn)?#xff0c;FIFO的級(jí)別為1/2,其閾值為2個(gè)字,8個(gè)字節(jié);以4個(gè)節(jié)拍也就是4個(gè)半字=8個(gè)字節(jié)發(fā)送,正好等于FIFO閾值的數(shù)據(jù)大小(8個(gè)字節(jié)),所以可以成功發(fā)送。
以此類推!
=============================================================================================
PS: 在這里為了更好的理解FIFO閾值配置表格,可以將節(jié)拍理解為MSIZE,例如:MSIZE為字節(jié)時(shí),FIFO級(jí)別為1/4(1個(gè)字,4個(gè)字節(jié)),4個(gè)節(jié)拍1次突發(fā)可以理解為4個(gè)字節(jié)一次突發(fā);MSIZE為半字時(shí),8個(gè)節(jié)拍一次突發(fā)可以理解為8個(gè)半字(4個(gè)字,16個(gè)字節(jié)),FIFO級(jí)別為1時(shí)(4個(gè)字,16個(gè)字節(jié)),可以實(shí)現(xiàn)一次突發(fā)。
也就是說:
節(jié)拍數(shù)(MSIZE數(shù))x 突發(fā)數(shù) = FIFO級(jí)別 x FIFO大小 (FIFO大小固定為4字)
例如:MSIZE = 半字;FIFO級(jí)別為 = 1/2;MBURST = 4個(gè)節(jié)拍1次突發(fā)
節(jié)拍數(shù)(MISIZE數(shù))= 半字
突發(fā)數(shù) = 4節(jié)拍 x 1次突發(fā) = 4 半字 = 2 字 = 8字節(jié)
那么:節(jié)拍數(shù)(MSIZE數(shù))x 突發(fā)數(shù) = 8 字節(jié)
FIFO閾值 = 1/2 x 4 字 = 2 字 = 8字節(jié)
由此可見 FIFO閾值 = 節(jié)拍數(shù)(MSIZE數(shù))x 突發(fā)數(shù)。
2. 循環(huán)模式
循環(huán)模式相對(duì)應(yīng)于一次模式。一次模式就是傳輸一次就停止傳輸,下一次傳輸需要手動(dòng)控制,而循環(huán)模式在傳輸一次后會(huì)自動(dòng)按照相同配置重新傳輸,周而復(fù)始直至被控制停止或傳輸發(fā)生錯(cuò)誤。
可以通過DMA_SxCR 寄存器的CIRC 位可以使能循環(huán)模式。
3. 雙緩沖模式
設(shè)置DMA_SxCR 寄存器的DBM 位為1 可啟動(dòng)雙緩沖傳輸模式,并自動(dòng)激活循環(huán)模式。
雙緩沖不應(yīng)用與存儲(chǔ)器到存儲(chǔ)器的傳輸。雙緩沖模式下,兩個(gè)存儲(chǔ)器地址指針都有效,即DMA_SxM1AR寄存器將被激活使用。開始傳輸使用DMA_SxM0AR 寄存器的地址指針?biāo)鶎?duì)應(yīng)的存儲(chǔ)區(qū),當(dāng)這個(gè)存儲(chǔ)區(qū)數(shù)據(jù)傳輸完DMA 控制器會(huì)自動(dòng)切換至DMA_SxM1AR 寄存器的地址指針?biāo)鶎?duì)應(yīng)的另一塊存儲(chǔ)區(qū),如果這一塊也傳輸完成就再切換至DMA_SxM0AR 寄存器的地址指針?biāo)鶎?duì)應(yīng)的存儲(chǔ)區(qū),這樣循環(huán)調(diào)用。
4. DMA中斷
每個(gè)DMA 數(shù)據(jù)流可以在發(fā)送以下事件時(shí)產(chǎn)生中斷:
5. 初始化結(jié)構(gòu)體庫函數(shù)
typedef struct {uint32_t DMA_Channel; //通道選擇uint32_t DMA_PeripheralBaseAddr; //外設(shè)地址uint32_t DMA_Memory0BaseAddr; //存儲(chǔ)器0 地址uint32_t DMA_DIR; //傳輸方向uint32_t DMA_BufferSize; //數(shù)據(jù)數(shù)目uint32_t DMA_PeripheralInc; //外設(shè)遞增uint32_t DMA_MemoryInc; //存儲(chǔ)器遞增uint32_t DMA_PeripheralDataSize; //外設(shè)數(shù)據(jù)寬度uint32_t DMA_MemoryDataSize; //存儲(chǔ)器數(shù)據(jù)寬度uint32_t DMA_Mode; //模式選擇uint32_t DMA_Priority; //優(yōu)先級(jí)uint32_t DMA_FIFOMode; //FIFO 模式uint32_t DMA_FIFOThreshold; //FIFO 閾值uint32_t DMA_MemoryBurst; //存儲(chǔ)器突發(fā)傳輸uint32_t DMA_PeripheralBurst; //外設(shè)突發(fā)傳輸}1) DMA_Channel:
DMA 請(qǐng)求通道選擇,可選通道0 至通道7,每個(gè)外設(shè)對(duì)應(yīng)固定的通道,具體設(shè)置值需要查表DMA1 各個(gè)通道的請(qǐng)求映像和表DMA2 各個(gè)通道的請(qǐng)求映像。
2) DMA_PeripheralBaseAddr:
外設(shè)地址,設(shè)定DMA_SxPAR 寄存器的值;一般設(shè)置為外設(shè)的數(shù)據(jù)寄存器地址,如果是存儲(chǔ)器到存儲(chǔ)器模式則設(shè)置為其中一個(gè)存儲(chǔ)區(qū)地址。
ADC3 的數(shù)據(jù)寄存器ADC_DR 地址為((uint32_t)ADC3+0x4C)。
3) DMA_Memory0BaseAddr:
存儲(chǔ)器0 地址,設(shè)定DMA_SxM0AR 寄存器值;一般設(shè)置為我們自義存儲(chǔ)區(qū)的首地址。我們程序先自定義一個(gè)16 位無符號(hào)整形數(shù)組ADC_ConvertedValue[4]用來存放每個(gè)通道的ADC 值, 所以把數(shù)組首地址(直接使用數(shù)組名即可) 賦值給DMA_Memory0BaseAddr。
4) DMA_DIR:
傳輸方向選擇,可選外設(shè)到存儲(chǔ)器、存儲(chǔ)器到外設(shè)以及存儲(chǔ)器到存儲(chǔ)器。它設(shè)定DMA_SxCR 寄存器的DIR[1:0] 位的值。ADC 采集顯然使用外設(shè)到存儲(chǔ)器模式。
5) DMA_BufferSize:
設(shè)定待傳輸數(shù)據(jù)數(shù)目,初始化設(shè)定DMA_SxNDTR 寄存器的值。這里ADC是采集4 個(gè)通道數(shù)據(jù),所以待傳輸數(shù)目也就是4。
6) DMA_PeripheralInc:
如果配置為DMA_PeripheralInc_Enable,使能外設(shè)地址自動(dòng)遞增功能,它設(shè)定DMA_SxCR 寄存器的PINC 位的值;一般外設(shè)都是只有一個(gè)數(shù)據(jù)寄存器,所以一般不會(huì)使能該位。ADC3 的數(shù)據(jù)寄存器地址是固定并且只有一個(gè)所以不使能外設(shè)地址遞增。
7) DMA_MemoryInc:
如果配置為DMA_MemoryInc_Enable,使能存儲(chǔ)器地址自動(dòng)遞增功能,它設(shè)定DMA_SxCR 寄存器的MINC 位的值;我們自定義的存儲(chǔ)區(qū)一般都是存放多個(gè)數(shù)據(jù)的,所以使能存儲(chǔ)器地址自動(dòng)遞增功能。我們之前已經(jīng)定義了一個(gè)包含4 個(gè)元素的數(shù)字用來存放數(shù)據(jù),使能存儲(chǔ)區(qū)地址遞增功能,自動(dòng)把每個(gè)通道數(shù)據(jù)存放到對(duì)應(yīng)數(shù)組元素內(nèi)。
8) DMA_PeripheralDataSize:
外設(shè)數(shù)據(jù)寬度,可選字節(jié)(8 位)、半字(16 位) 和字(32 位),它設(shè)定DMA_SxCR 寄存器的PSIZE[1:0] 位的值。ADC 數(shù)據(jù)寄存器只有低16 位數(shù)據(jù)有效,使用半字?jǐn)?shù)據(jù)寬度。
9) DMA_MemoryDataSize:
存儲(chǔ)器數(shù)據(jù)寬度,可選字節(jié)(8 位)、半字(16 位) 和字(32 位),它設(shè)定DMA_SxCR 寄存器的MSIZE[1:0] 位的值。保存ADC 轉(zhuǎn)換數(shù)據(jù)也要使用半字?jǐn)?shù)據(jù)寬度,這跟我們定義的數(shù)組是相對(duì)應(yīng)的。
10) DMA_Mode:
DMA 傳輸模式選擇,可選一次傳輸或者循環(huán)傳輸,它設(shè)定DMA_SxCR 寄存器的CIRC 位的值。我們希望ADC 采集是持續(xù)循環(huán)進(jìn)行的,所以使用循環(huán)傳輸模式。
11) DMA_Priority:
軟件設(shè)置數(shù)據(jù)流的優(yōu)先級(jí),有4 個(gè)可選優(yōu)先級(jí)分別為非常高、高、中和低,它設(shè)定DMA_SxCR 寄存器的PL[1:0] 位的值。DMA 優(yōu)先級(jí)只有在多個(gè)DMA 數(shù)據(jù)流同時(shí)使用時(shí)才有意義,這里我們?cè)O(shè)置為非常高優(yōu)先級(jí)就可以了。
12) DMA_FIFOMode:
FIFO 模式使能,如果設(shè)置為DMA_FIFOMode_Enable 表示使能FIFO 模式功能;它設(shè)定DMA_SxFCR 寄存器的DMDIS 位。ADC 采集傳輸使用直接傳輸模式即可,不需要使用FIFO 模式。
13) DMA_FIFOThreshold:
FIFO 閾值選擇,可選4 種狀態(tài)分別為FIFO 容量的1/4、1/2、3/4 和滿;它設(shè)定DMA_SxFCR 寄存器的FTH[1:0] 位;DMA_FIFOMode 設(shè)置為DMA_FIFOMode_Disable,那DMA_FIFOThreshold 值無效。ADC 采集傳輸不使用FIFO 模式,設(shè)置改值無效。
14) DMA_MemoryBurst:
存儲(chǔ)器突發(fā)模式選擇,可選單次模式、4 節(jié)拍的增量突發(fā)模式、8 節(jié)拍的增量突發(fā)模式或16 節(jié)拍的增量突發(fā)模式,它設(shè)定DMA_SxCR 寄存器的MBURST[1:0] 位的值。ADC 采集傳輸是直接模式,要求使用單次模式。
15) DMA_PeripheralBurst:
外設(shè)突發(fā)模式選擇,可選單次模式、4 節(jié)拍的增量突發(fā)模式、8 節(jié)拍的增量突發(fā)模式或16 節(jié)拍的增量突發(fā)模式,它設(shè)定DMA_SxCR 寄存器的PBURST[1:0] 位的值。
ADC 采集傳輸是直接模式,要求使用單次模式。
總結(jié)
以上是生活随笔為你收集整理的《STM32从零开始学习历程》——DMA直接存储区访问理论知识的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Mindjet
- 下一篇: 如何使用计算机制作数学公式,利用电脑编程