【STM32】DMA基本原理、寄存器、庫(kù)函數(shù)
1DMA的基本定義
DMA,全稱Direct Memory Access,即直接存儲(chǔ)器訪問(wèn)。
DMA傳輸將數(shù)據(jù)從一個(gè)地址空間復(fù)制到另一個(gè)地址空間,提供在外設(shè)和存儲(chǔ)器之間或者存儲(chǔ)器和存儲(chǔ)器之間的高速數(shù)據(jù)傳輸。當(dāng)CPU初始化這個(gè)傳輸動(dòng)作,傳輸動(dòng)作本身是由DMA控制器來(lái)實(shí)現(xiàn)和完成的。DMA傳輸方式無(wú)需CPU直接控制傳輸,也沒(méi)有中斷處理方式那樣保留現(xiàn)場(chǎng)和恢復(fù)現(xiàn)場(chǎng)過(guò)程,通過(guò)硬件為RAM和IO設(shè)備開(kāi)辟一條直接傳輸數(shù)據(jù)的通道,使得CPU的效率大大提高。
2DMA的主要特征
- 每個(gè)通道都直接連接專用的硬件DMA請(qǐng)求,每個(gè)通道都同樣支持軟件觸發(fā)。這些功能通過(guò)軟件來(lái)配置;
- 在同一個(gè)DMA模塊上,多個(gè)請(qǐng)求間的優(yōu)先權(quán)可以通過(guò)軟件編程設(shè)置(共有四級(jí):很高、高、中等和低),優(yōu)先權(quán)設(shè)置相等時(shí)由硬件決定(請(qǐng)求0優(yōu)先于請(qǐng)求1,依此類推);
- 獨(dú)立數(shù)據(jù)源和目標(biāo)數(shù)據(jù)區(qū)的傳輸寬度(字節(jié)、半字、全字),模擬打包和拆包的過(guò)程。源和目標(biāo)地址必須按數(shù)據(jù)傳輸寬度對(duì)齊;
- 支持循環(huán)的緩沖器管理;
- 每個(gè)通道都有3個(gè)事件標(biāo)志(DMA半傳輸、DMA傳輸完成和DMA傳輸出錯(cuò)),這3個(gè)事件標(biāo)志邏輯或成為一個(gè)單獨(dú)的中斷請(qǐng)求;
- 存儲(chǔ)器和存儲(chǔ)器間的傳輸、外設(shè)和存儲(chǔ)器、存儲(chǔ)器和外設(shè)之間的傳輸;
- 閃存、SRAM、外設(shè)的SRAM、APB1、APB2和AHB外設(shè)均可作為訪問(wèn)的源和目標(biāo);
- 可編程的數(shù)據(jù)傳輸數(shù)目:最大為65535。
3STM33F10x系列芯片DMA控制器
STM32F10x系列芯片最多有2個(gè)DMA控制器(DMA2僅存在大容量產(chǎn)品中),DMA1有7個(gè)通道。DMA2有5個(gè)通道。每個(gè)通道專門用來(lái)管理來(lái)自于一個(gè)或多個(gè)外設(shè)對(duì)存儲(chǔ)器訪問(wèn)的請(qǐng)求。還有一個(gè)仲裁起來(lái)協(xié)調(diào)各個(gè)DMA請(qǐng)求的優(yōu)先權(quán)。
從外設(shè)(TIMx[x=1、2、3、4]、ADC1、SPI1、SPI/I2S2、I2Cx[x=1、2]和USARTx[x=1、2、3])產(chǎn)生的7個(gè)請(qǐng)求,通過(guò)邏輯或輸入到DMA1控制器,這意味著同時(shí)只能有一個(gè)請(qǐng)求有效。各個(gè)通道的DMA1請(qǐng)求一覽見(jiàn)下圖:
從外設(shè)(TIMx[5、6、7、8]、ADC3、SPI/I2S3、UART4、DAC通道1、2和SDIO)產(chǎn)生的5個(gè)請(qǐng)求,經(jīng)邏輯或輸入到DMA2控制器,這意味著同時(shí)只能有一個(gè)請(qǐng)求有效。各個(gè)通道的DMA2請(qǐng)求一覽見(jiàn)下圖:
DMA的基本原理
DMA控制器和Cortex?-M3核心共享系統(tǒng)數(shù)據(jù)總線,執(zhí)行直接存儲(chǔ)器數(shù)據(jù)傳輸。當(dāng)CPU和DMA同時(shí)訪問(wèn)相同的目標(biāo)(RAM或外設(shè))時(shí),DMA請(qǐng)求會(huì)暫停CPU訪問(wèn)系統(tǒng)總線達(dá)若干個(gè)周期,總線仲裁器執(zhí)行循環(huán)調(diào)度,以保證CPU至少可以得到一半的系統(tǒng)總線(存儲(chǔ)器或外設(shè))帶寬。
0DMA的工作框圖
DMA模塊的框圖看起來(lái)比較復(fù)雜,接下來(lái)會(huì)一點(diǎn)一點(diǎn)地對(duì)它進(jìn)行分析。
1DMA處理
在發(fā)生一個(gè)事件后,外設(shè)向DMA控制器發(fā)送一個(gè)請(qǐng)求信號(hào)。DMA控制器根據(jù)通道的優(yōu)先權(quán)處理請(qǐng)求。當(dāng)DMA控制器開(kāi)始訪問(wèn)發(fā)出請(qǐng)求的外設(shè)時(shí),DMA控制器立即發(fā)送給它一個(gè)應(yīng)答信號(hào)。當(dāng)從DMA控制器得到應(yīng)答信號(hào)時(shí),外設(shè)立即釋放它的請(qǐng)求。一旦外設(shè)釋放了這個(gè)請(qǐng)求,DMA控制器同時(shí)撤銷應(yīng)答信號(hào)。如果有更多的請(qǐng)求時(shí),外設(shè)可以啟動(dòng)下一個(gè)周期。
總之,每次DMA傳送由3個(gè)操作組成:
- 從外設(shè)數(shù)據(jù)寄存器或者從當(dāng)前外設(shè)/存儲(chǔ)器地址寄存器指示的存儲(chǔ)器地址取數(shù)據(jù),第一次傳輸時(shí)的開(kāi)始地址是DMA_CPARx或DMA_CMARx寄存器指定的外設(shè)基地址或存儲(chǔ)器單元;
- 存數(shù)據(jù)到外設(shè)數(shù)據(jù)寄存器或者當(dāng)前外設(shè)/存儲(chǔ)器地址寄存器指示的存儲(chǔ)器地址,第一次傳輸時(shí)的開(kāi)始地址是DMA_CPARx或DMA_CMARx寄存器指定的外設(shè)基地址或存儲(chǔ)器單元;
- 執(zhí)行一次DMA_CNDTRx寄存器的遞減操作,該寄存器包含未完成的操作數(shù)目。
2仲裁器
仲裁器根據(jù)通道請(qǐng)求的優(yōu)先級(jí)來(lái)啟動(dòng)外設(shè)/存儲(chǔ)器的訪問(wèn)。
優(yōu)先權(quán)管理分2個(gè)階段:
- 軟件:每個(gè)通道的優(yōu)先權(quán)可以在DMA_CCRx寄存器中設(shè)置,有4個(gè)等級(jí):最高優(yōu)先級(jí)、高優(yōu)先級(jí)、中等優(yōu)先級(jí)、低優(yōu)先級(jí);
- 硬件:如果2個(gè)請(qǐng)求有相同的軟件優(yōu)先級(jí),則較低編號(hào)的通道比較高編號(hào)的通道有較高的優(yōu)先權(quán)。比如:如果軟件優(yōu)先級(jí)相同,通道2優(yōu)先于通道4。?
注意:在大容量產(chǎn)品和互聯(lián)型產(chǎn)品中,DMA1控制器擁有高于DMA2控制器的優(yōu)先級(jí)。
3DMA通道
每個(gè)通道都可以在有固定地址的外設(shè)寄存器和存儲(chǔ)器地址之間執(zhí)行DMA傳輸。DMA傳輸?shù)臄?shù)據(jù)量是可編程的,最大達(dá)到65535。包含要傳輸?shù)臄?shù)據(jù)項(xiàng)數(shù)量的寄存器,在每次傳輸后遞減。
4可編程的數(shù)據(jù)量
外設(shè)和存儲(chǔ)器的傳輸數(shù)據(jù)量可以通過(guò)DMA_CCRx寄存器中的PSIZE和MSIZE位編程。
6指針增量
通過(guò)設(shè)置DMA_CCRx寄存器中的PINC和MINC標(biāo)志位,外設(shè)和存儲(chǔ)器的指針在每次傳輸后可以有選擇地完成自動(dòng)增量。當(dāng)設(shè)置為增量模式時(shí),下一個(gè)要傳輸?shù)牡刂穼⑹乔耙粋€(gè)地址加上增量值,增量值取決于所選的數(shù)據(jù)寬度為1、2或4。
第一個(gè)傳輸?shù)牡刂肥谴娣旁贒MA_CPARx /DMA_CMARx寄存器中的值。在傳輸過(guò)程中,這些寄存器保持它們初始的數(shù)值,軟件不能改變和讀出當(dāng)前正在傳輸?shù)牡刂罚ㄋ趦?nèi)部的當(dāng)前外設(shè)/存儲(chǔ)器地址寄存器中)。
當(dāng)通道配置為非循環(huán)模式時(shí),傳輸結(jié)束后(即傳輸計(jì)數(shù)變?yōu)?)將不再產(chǎn)生DMA操作。要開(kāi)始新的DMA傳輸,需要在關(guān)閉DMA通道的情況下,在DMA_CNDTRx寄存器中重新寫(xiě)入傳輸數(shù)目。在循環(huán)模式下,最后一次傳輸結(jié)束時(shí),DMA_CNDTRx寄存器的內(nèi)容會(huì)自動(dòng)地被重新加載為其初始數(shù)值,內(nèi)部的當(dāng)前外設(shè)/存儲(chǔ)器地址寄存器也被重新加載為DMA_CPARx/DMA_CMARx寄存器設(shè)定的初始基地址。
6循環(huán)模式
循環(huán)模式用于處理循環(huán)緩沖區(qū)和連續(xù)的數(shù)據(jù)傳輸(如ADC的掃描模式)。
在DMA_CCRx寄存器中的CIRC位用于開(kāi)啟這一功能。當(dāng)啟動(dòng)了循環(huán)模式,數(shù)據(jù)傳輸?shù)臄?shù)目變?yōu)?時(shí),將會(huì)自動(dòng)地被恢復(fù)成配置通道時(shí)設(shè)置的初值,DMA操作將會(huì)繼續(xù)進(jìn)行。
7存儲(chǔ)器到存儲(chǔ)器模式
DMA通道的操作可以在沒(méi)有外設(shè)請(qǐng)求的情況下進(jìn)行,這種操作就是存儲(chǔ)器到存儲(chǔ)器模式。
當(dāng)設(shè)置了DMA_CCRx寄存器中的MEM2MEM位之后,在軟件設(shè)置了DMA_CCRx寄存器中的EN位啟動(dòng)DMA通道時(shí),DMA傳輸將馬上開(kāi)始。當(dāng)DMA_CNDTRx寄存器變?yōu)?時(shí),DMA傳輸結(jié)束。存儲(chǔ)器到存儲(chǔ)器模式不能與循環(huán)模式同時(shí)使用。
8可編程的數(shù)據(jù)傳輸寬度、對(duì)齊方式和數(shù)據(jù)大小端
當(dāng)PSIZE和MSIZE不相同時(shí),DMA模塊按照下圖進(jìn)行數(shù)據(jù)對(duì)齊。
9中斷
每個(gè)DMA通道都可以在DMA傳輸過(guò)半、傳輸完成和傳輸錯(cuò)誤時(shí)產(chǎn)生中斷。為應(yīng)用的靈活性考慮,通過(guò)設(shè)置寄存器的不同位來(lái)打開(kāi)這些中斷。
注意:在大容量產(chǎn)品中,DMA2通道4和DMA2通道5的中斷被映射在同一個(gè)中斷向量上。在互聯(lián)型產(chǎn)品中,DMA2通道4和DMA2通道5的中斷分別有獨(dú)立的中斷向量。所有其他的DMA通道都有自己的中斷向量。
DMA相關(guān)配置寄存器
DMA配置參數(shù)包括:通道地址、優(yōu)先級(jí)、數(shù)據(jù)傳輸方向、存儲(chǔ)器/外設(shè)數(shù)據(jù)寬度、存儲(chǔ)器/外設(shè)地址是否增量、循環(huán)模式、數(shù)據(jù)傳輸量。
1DMA通道x配置寄存器(DMA_CCRx)
作用:配置DMA通道模式、優(yōu)先級(jí)、數(shù)據(jù)寬度、是否增量、傳輸方向、是否增量參數(shù)。
2DMA通道x傳輸數(shù)量寄存器(DMA_CNDTRx)
作用:配置DMA通道的數(shù)據(jù)傳輸數(shù)量,范圍為0-65535。
主要注意:該寄存器的值會(huì)隨著傳輸?shù)倪M(jìn)行而減少,當(dāng)該寄存器的值為0的時(shí)候,就代表著此次傳輸已經(jīng)全部結(jié)束了。也就是說(shuō),當(dāng)DMA通道開(kāi)啟傳輸了之后,該寄存器變成只讀,指示的是數(shù)據(jù)傳輸數(shù)量中剩余待傳輸?shù)淖止?jié)數(shù)目。
3DMA通道x外設(shè)地址寄存器(DMA_CPARx)
作用:配置DMA通道的外設(shè)地址。比如使用串口1的數(shù)據(jù)引腳,則該寄存器必須寫(xiě)上0x40013804(其實(shí)就是串口數(shù)據(jù)寄存器的地址,