直接存儲器讀取
DMA簡介
直接存儲器存取(DMA)用來提供在外設(shè)和存儲器之間或者存儲器和存儲器之間的高速數(shù)據(jù)傳輸睛藻。無須CPU干預(yù),數(shù)據(jù)可以通過DMA快速地移動冈在,這就節(jié)省了CPU的資源來做其他操作按摘。
由圖可見,DMA 一共有 DMA1 和 DMA2 兩個控制器炫贤。DMA1 有7個通道,DMA2 有5個通道侍郭。
在存儲器和存儲器之間傳輸數(shù)據(jù)時俩垃,可任選通道進(jìn)行傳輸汰寓;但在外設(shè)和存儲器之間傳輸數(shù)據(jù)時,需要用到專用的通道跃闹。
DMA寄存器
-
中斷狀態(tài)寄存器 --- ISR(interrupt status register):存放DMA中斷的標(biāo)志位望艺;
- 注意:若為DMA2肌访,只有低19位有效找默;
- 作用---傳輸錯誤(TE)標(biāo)志位:位3,7,11,15,19,23,27惩激,發(fā)生傳輸錯誤時置1;
- 作用---半傳輸(HT)標(biāo)志位:位2,6,10,14,18,22,26顷蟀,傳輸了一半數(shù)據(jù)并產(chǎn)生對應(yīng)事件時置1骡技;
- 作用---傳輸完成(TC)標(biāo)志位:位1,5,9,13,17,21,25,傳輸完成并產(chǎn)生了對應(yīng)事件時置1囤萤;
- 作用---全局中斷(GI)標(biāo)志位:位0,4,8,12,16,20,24是趴,上述3個寄存器任一寄存器置1,該寄存器置1右遭;
- 復(fù)位值:0x0000 0000
-
中斷標(biāo)志清除寄存器 --- IFCR(interrupt flag clear register):清除ISR中DMA中斷的標(biāo)志位;
- 注意:若為DMA2吹榴,只有低19位有效滚婉;
- 作用---清除傳輸錯誤(TE)標(biāo)志位:位3,7,11,15,19,23,27,置1時將 TE 置0远剩;
- 作用---清除半傳輸(HT)標(biāo)志位:位2,6,10,14,18,22,26骇窍,置1時將 HT 置0;
- 作用---清除傳輸完成(TC)標(biāo)志位:位1,5,9,13,17,21,25腹纳,置1時將 TC 置0;
- 作用---清除全局中斷(GI)標(biāo)志位:位0,4,8,12,16,20,24足画,置1時將 TE佃牛、HT、TC寄存器均置0象缀;
- 復(fù)位值:0x0000 0000
-
通道x配置寄存器 --- CCRx(channel x configuration register):設(shè)置通道x的各項配置;
- 注意:若為DMA1娃胆,該寄存器有7組(即x可為 0~7)等曼;DMA2 就只有5組;
- 作用---開啟通道:位0 置1時通道開啟禁谦,置0時關(guān)閉;
- 作用---允許傳輸完成(TC)中斷:位1丧蘸,置1時允許產(chǎn)生傳輸完成中斷(可檢測TC標(biāo)志位查看是否產(chǎn)生) 遥皂;
- 作用---允許半傳輸(HT)中斷:位2,置1時允許產(chǎn)生半傳輸中斷弟孟;
- 作用---允許傳輸錯誤(TE)中斷:位3样悟,置1時允許產(chǎn)生傳輸錯誤中斷;
- 作用---設(shè)置數(shù)據(jù)來源:位4陈症,置0時表示從外設(shè)讀取數(shù)據(jù)震糖,置1時表示從存儲器讀取數(shù)據(jù);
- 注意:若是存儲器到存儲器嘁信,則一般把發(fā)送存儲器當(dāng)作外設(shè)來進(jìn)行設(shè)置疏叨,位14 再置1即可穿剖;
- 作用---設(shè)置是否循環(huán)操作:位5,置0時表示只讀取1次數(shù)據(jù)秀又,置1時表示循環(huán)讀取該數(shù)據(jù);
- 作用---設(shè)置外設(shè)地址增量模式:位6吐辙,置0時傳輸數(shù)據(jù)時外設(shè)地址不增加,置1則為增加尊沸;
- 作用---設(shè)置存儲器地址增量模式:位7贤惯,置0時傳輸數(shù)據(jù)時存儲器地址不增加,置1則為增加屁商;
- 作用---設(shè)置外設(shè)數(shù)據(jù)寬度:位9:8颈墅;00為8位,01為16位帽哑,10為32位叹俏,11為保留;
- 作用---設(shè)置存儲器數(shù)據(jù)寬度:位11:10粘驰;00為8位蝌数,01為16位,10為32位顶伞,11為保留;
- 作用---設(shè)置通道的優(yōu)先級:位13:12滑潘,00為低锨咙,01為中,10為高粹舵,11為最高;
- 注意:當(dāng)通道優(yōu)先級相同時巴席,DMA1通道比DMA2通道優(yōu)先級高诅需,DMAx比DMAy通道優(yōu)先級高(x<y);
- 作用---設(shè)置存儲器和存儲器之間傳輸:位14毡证,置0表示是外設(shè)和存儲器之間傳輸蔫仙,置1表示是存儲器和存儲器之間傳輸;
- 復(fù)位值:0x0000 0000
-
通道x傳輸數(shù)量寄存器 --- CNDTRx(channel x number of data register):設(shè)置通道x需要傳輸?shù)臄?shù)據(jù)個數(shù)恤煞;
- 注意:若為DMA1施籍,該寄存器有7組(即x可為 0~7);DMA2 就只有5組丑慎;
- 作用---設(shè)置需要傳輸?shù)臄?shù)據(jù)的個數(shù):位15:0竿裂,表示需要傳輸?shù)臄?shù)據(jù)的個數(shù)(易知一次最多只能傳輸65335個數(shù)據(jù));
-
DMA通道x外設(shè)地址寄存器 --- CPARx(channel x peripheral address register):存儲在外設(shè)中需要傳輸?shù)臄?shù)據(jù)的地址腻异;
- 注意:若為DMA1悔常,該寄存器有7組(即x可為 0~7);DMA2 就只有5組机打;
- 作用---存儲地址:位31:0姐帚,存儲在外設(shè)中需要傳輸?shù)臄?shù)據(jù)的地址障涯;
-
DMA通道x存儲器地址寄存器 --- CMARx(channel x memory address register):存儲在存儲器中需要傳輸?shù)臄?shù)據(jù)的地址膳汪;
- 注意:若為DMA1九秀,該寄存器有7組(即x可為 0~7);DMA2 就只有5組痹换;
- 作用---存儲地址:位31:0都弹,存儲在存儲器中需要傳輸?shù)臄?shù)據(jù)的地址;
常用DMA固件庫函數(shù) (stm32f10x_dma.h)
USART初始化函數(shù) --- USART_Init
void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct);
- DMAy_Channelx:選擇通道端口冯痢,y可為 1~2 框杜,y=1時x可為 1~7 ,y=2時x可為 1~5 振劳;
-
DMA_InitStruct:DMA_InitTypeDef 結(jié)構(gòu)體
- DMA_MemoryBaseAddr:存儲器(發(fā)送或?qū)⒁邮盏模?shù)據(jù)地址油狂;
- DMA_PeripheralBaseAddr:外設(shè)(發(fā)送或?qū)⒁邮盏模?shù)據(jù)地址;
- DMA_DIR:數(shù)據(jù)傳輸方向夹供,可選 外設(shè)為源(PeripheralSRC)仁堪、外設(shè)為目標(biāo)(PeripheralDST);
- DMA_BufferSize:傳輸?shù)臄?shù)據(jù)的個數(shù)鸟辅,最大為65335莺葫;
- DMA_PeripheralInc:外設(shè)是否啟動增量模式( Enable 或 Disable);
- DMA_PeripheralDataSize:外設(shè)數(shù)據(jù)的字長再层;
- DMA_MemoryInc:存儲器是否啟動增量模式( Enable 或 Disable);
- DMA_MemoryDataSize:存儲器數(shù)據(jù)的字長蒿秦;
- DMA_Mode:是否循環(huán)傳輸數(shù)據(jù)蛋济,( Normal 或 Circular );
- DMA_Priority:該通道優(yōu)先級渡处,可為 低(Low)祟辟、中(Medium)、高(High)旧困、超高(VeryHigh)叮喳;
- DMA_M2M:是否是存儲器和存儲器之間的傳輸,是(Enable) 或 不是(Disable)馍悟;
- 示例:
// DMA_M2M 初始化
//定義DMA初始化結(jié)構(gòu)體
DMA_InitTypeDef DMA_InitStructure;
//打開DMA1時鐘
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
//配置DMA
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)aSRC_Const_Buffer; //源數(shù)據(jù)地址
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)aDST_Buffer; //目標(biāo)數(shù)據(jù)地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //設(shè)置外設(shè)(Flash)為源
DMA_InitStructure.DMA_BufferSize = 8; //配置傳輸數(shù)據(jù)的個數(shù)為8
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable; //外設(shè)(源)設(shè)置為增量模式
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; //外設(shè)數(shù)據(jù)字長設(shè)置為32位
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //存儲(SRAM)設(shè)置為增量模式
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; //存儲數(shù)據(jù)字長設(shè)置為32位
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //只發(fā)送一次數(shù)據(jù)(非循環(huán)發(fā)送)
DMA_InitStructure.DMA_Priority = DMA_Priority_High; //設(shè)置為高優(yōu)先級
DMA_InitStructure.DMA_M2M = DMA_M2M_Enable; //打開 M2M
//初始化DMA通道
DMA_Init(DMA1_Channel6, &DMA_InitStructure);
DMA清除標(biāo)志位函數(shù) --- DMA_ClearFlag
void DMA_ClearFlag(uint32_t DMAy_FLAG);
-
DMAy_FLAG:對應(yīng)的標(biāo)志位侵状,y可以為 1~2 毅整;
DMA1的標(biāo)志位
DMA通道使能函數(shù) --- DMA_Cmd
DMA_Cmd(DMA_Channel_TypeDef* DMAy_Channelx, FunctionalState NewState);
- DMAy_Channelx:選擇通道端口悼嫉,y可為 1~2 ,y=1時x可為 1~7 戏蔑,y=2時x可為 1~5 ;
- NewState:使能或關(guān)閉鳍寂,ENABLE情龄、DISABLE捍壤;
- 示例:
//使能DMA1的通道6
DMA_Cmd(DMA1_Channel6, ENABLE);
DMA獲取標(biāo)志位函數(shù) --- DMA_GetFlagStatus
FlagStatus DMA_GetFlagStatus(uint32_t DMAy_FLAG);
- DMAy_FLAG:對應(yīng)的標(biāo)志位鹃觉,y可以為 1~2硬霍;