日韩一区二区三区精品,欧美疯狂xxxxbbbb牲交,热99re久久免费视精品频,人妻互换 综合,欧美激情肉欲高潮视频

歷史上的今天

今天是:2025年07月17日(星期四)

2018年07月17日 | STM32之DMA(直接存儲器存儲)

發(fā)布者:溫柔的心情 來源: eefocus關(guān)鍵字:STM32  DMA  直接存儲器存儲 手機(jī)看文章 掃描二維碼
隨時(shí)隨地手機(jī)看文章

DMA簡介: 
在硬件系統(tǒng)中,主要由CPU(內(nèi)核),外設(shè),內(nèi)存(SRAM),總線等結(jié)構(gòu)組成,數(shù)據(jù)就經(jīng)常要在內(nèi)存與外設(shè)之間傳輸轉(zhuǎn)移,或者是從外設(shè)A轉(zhuǎn)移到外設(shè)B. 
DMA(Direct Memory Access)直接存儲器存儲,是一種可以大大減輕CPU工作量的數(shù)據(jù)存儲方式. 
數(shù)據(jù)轉(zhuǎn)移的一般方式: 
例如當(dāng)CPU需要處理由ADC外設(shè)采集回來的數(shù)據(jù)時(shí),CPU首先要把數(shù)據(jù)從ADC外設(shè)的寄存器讀取到內(nèi)存中(變量),然后進(jìn)行運(yùn)算處理. 
(但是,因?yàn)樵谵D(zhuǎn)移數(shù)據(jù)的過程中會占用CPU十分寶貴的資源,所以希望CPU更多地被用在數(shù)據(jù)運(yùn)算或響應(yīng)中斷之中,而數(shù)據(jù)轉(zhuǎn)移的工作交由其它部件完成。) 
DMA的方式: 
DMA可以為CPU分擔(dān)了數(shù)據(jù)轉(zhuǎn)移的工作。因?yàn)镈MA的存在,CPU被解放出來,它可以在DMA轉(zhuǎn)移數(shù)據(jù)的過程中同時(shí)進(jìn)行數(shù)據(jù)運(yùn)算,響應(yīng)中斷,大大提高效率.

DMA的工作: 
在STM32中文手冊可以找到STM32的系統(tǒng)結(jié)構(gòu)圖,可以很清晰的看到STM32內(nèi)核,存儲器,外設(shè)以及DMA的連接 
這里寫圖片描述 
所有這些硬件結(jié)構(gòu)最終都通過各種各樣的線連接到總線矩陣之中,硬件結(jié)構(gòu)之間的數(shù)據(jù)轉(zhuǎn)移都經(jīng)過總線矩陣的協(xié)調(diào),使各個外設(shè)都能夠和諧地使用總線來傳輸數(shù)據(jù).

例如: 
在不使用DMA的情況下,內(nèi)核通過DCode經(jīng)過總線矩陣協(xié)調(diào),使用AHB把外設(shè)ADC采集的數(shù)據(jù)讀取到內(nèi)核,然后內(nèi)核DCode再通過總線矩陣協(xié)調(diào),把數(shù)據(jù)存放到內(nèi)存SRAM中。 
而在使用DMA之后,由DMA控制器的DMA總線與總線矩陣協(xié)調(diào),使用AHB把外設(shè)ADC的數(shù)據(jù)經(jīng)由DMA通道存放到內(nèi)存SRAM。在這個數(shù)據(jù)傳輸?shù)倪^程中,不需要內(nèi)核的全程參與,所以內(nèi)核可以同時(shí)進(jìn)行數(shù)據(jù)運(yùn)算,而且DMA的方式是點(diǎn)到點(diǎn)的數(shù)據(jù)轉(zhuǎn)移,而不使用DMA的方式還要以內(nèi)核來作為中轉(zhuǎn)站,顯然是DMA的傳輸方式的效率更高。(所以”直接“是很強(qiáng)的東西?。。?/p>

DMA的控制參數(shù): 
要使用DMA,需要確定一系列的控制參數(shù): 
如外設(shè)數(shù)據(jù)的地址,內(nèi)存地址,傳輸方向等,在開啟DMA傳輸前還要先發(fā)出DMA請求。

DMA實(shí)例main函數(shù): 
main函數(shù)功能: 
實(shí)際上是利用DMA把數(shù)據(jù)(數(shù)組)從內(nèi)存轉(zhuǎn)移到外設(shè)(串口)。外設(shè)工作的時(shí)候,除了轉(zhuǎn)移數(shù)據(jù),實(shí)質(zhì)是不需要內(nèi)核干預(yù)的,而數(shù)據(jù)轉(zhuǎn)移的工作現(xiàn)在交給了DMA,所以在串口發(fā)送數(shù)據(jù)的時(shí)候,內(nèi)核同時(shí)還可以進(jìn)行其它操作,比如點(diǎn)亮LED燈(類似一個線程動作)。

頭文件忽略……….. 
extern uint8_t SendBuff[SENDBUFF_SIZE]; 
uint16_t i;

int main(void) 

/USART1_Config 115200 8-N-1/ 
USART1_Config(); 
DMA_Config(); 
LED_GPIO_Config();

r(i=0;i

{

SendBuff[i] = 0xff;

}

/*串口向DMA發(fā)出請求 */

USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);//在DMA傳送未完成時(shí),CPU會繼續(xù)執(zhí)行main函數(shù)中的代碼


LED1(ON);//先點(diǎn)亮LED,而同時(shí)DMA在向串口運(yùn)送數(shù)據(jù),當(dāng)DMA發(fā)送完成時(shí),在中斷函數(shù)關(guān)閉LED

while(1);

}


main函數(shù)里面配置好了串口1,DMA,以及LED外設(shè),使能DMA的發(fā)送請求.其中串口配置以及LEDGPIO的配置這里就不講解了,前面的博客都有說,配置的內(nèi)容都一樣.


DMA的配置: 

void DMA_Config(void) 

DMA_InitTypeDef DMA_InitStructure; 

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//開啟 DMA 時(shí)鐘

NVIC_Config(); //配置 DMA 中斷


/*設(shè)置 DMA 源:內(nèi)存地址&串口數(shù)據(jù)寄存器地址*/

DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base;

/*內(nèi)存地址(要傳輸?shù)淖兞康闹羔?*/

DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff;

/*方向:從內(nèi)存到外設(shè)*/

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;

/*傳輸大小 DMA_BufferSize=SENDBUFF_SIZE*/

DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE;

/*外設(shè)地址不增*/

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

/*內(nèi)存地址自增*/

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

/*外設(shè)數(shù)據(jù)單位*/

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;

/*內(nèi)存數(shù)據(jù)單位 8bit*/

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;

/*DMA 模式:一次傳輸,循環(huán)*/

DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;

/*優(yōu)先級:中*/

DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;

/*禁止內(nèi)存到內(nèi)存的傳輸 */

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

/*配置 DMA1 的 4 通道*/

DMA_Init(DMA1_Channel4, &DMA_InitStructure);

DMA_Cmd (DMA1_Channel4,ENABLE); //使能

DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,ENABLE); //配置 DMA 發(fā)送完之后產(chǎn)生中斷

}

DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base; 
保存外設(shè)數(shù)據(jù)寄存器的基地址,這個地址作為傳輸?shù)脑椿蚰繕?biāo)(DMA具有地址自增的功能,地址自增可以方便地讀取連續(xù)的單元) 
這里面用的USART1_DR_Base宏實(shí)際是#define USART1_DR_Base 0x40013804,從《 STM32 參考手冊》可知,串口外設(shè)會自動地把數(shù)據(jù)寄存器中的數(shù)據(jù),送入它的移位寄存器,然后由硬件按照串口協(xié)議把該數(shù)據(jù)發(fā)送出去。 
在這個實(shí)例中,把數(shù)據(jù)寄存器的地址作為外設(shè)的地址,那么由DMA通道轉(zhuǎn)移過來的內(nèi)存數(shù)據(jù)就會被保護(hù)到這個寄存器中,然后串口就會自動進(jìn)行發(fā)送了.

ps:外設(shè)數(shù)據(jù)寄存器的地址可以在《STM32參考手冊》中找到一個存儲器映射表(部分)(圖截的不是很好看?。。。?nbsp;
這里寫圖片描述 
這里寫圖片描述 
可以看到,USART1(串口1)的外設(shè)基地址為0x40013800,同時(shí)我們在查找《STM32數(shù)據(jù)手冊》手冊可以找到USART的數(shù)據(jù)寄存器,了解到偏移量是0x04,那么USART1的外設(shè)基地址加上數(shù)據(jù)寄存器的地址偏移就是在DMA傳輸中需要的目標(biāo)地址了。 
0x4001 3804 = 0x4001 3800 + 0x04;

DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff; 
保存了內(nèi)存的基地址,這個地址也可以作為傳輸源或目標(biāo).在使用時(shí)通常會給這個成員賦值為某個數(shù)組的基地址,然后利用DMA的地址自增功能把數(shù)組一個個地填滿. 
(在C語言中數(shù)組名就是該數(shù)組的基地址,而數(shù)組(變量)是被保存到內(nèi)存(SRAM)上的,所以我們實(shí)質(zhì)上給.DMA_MemoryBaseAddr 這個結(jié)構(gòu)體成員賦予了一個內(nèi)存地址。)

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; 
DMA數(shù)據(jù)傳輸方向,可以選擇是外設(shè)到內(nèi)存還是內(nèi)存到外設(shè)。DMA_DIR_PeripheralDST是內(nèi)存到外設(shè)

DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE; 
DMA要傳輸?shù)臄?shù)據(jù)總大小, DMA_BufferSize=SENDBUFF_SIZE=5000,這里要傳輸5000個數(shù)據(jù)

DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable; 
外設(shè)地址不增,因?yàn)橛玫氖峭庠O(shè)地址是固定的.

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; 
內(nèi)存地址自增,數(shù)組自增把數(shù)據(jù)一個個都傳到數(shù)據(jù)寄存器.

DMA_InitStructure.DMA_PeripheralDataSize =DMA_PeripheralDataSize_Byte; 
外設(shè)傳輸數(shù)據(jù)單元大小,可以為字節(jié),半字節(jié),字.

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; 
內(nèi)存?zhèn)鬏敂?shù)據(jù)單元大小,可以為字節(jié),半字節(jié),字,這里是8bit.

DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; 
DMA的模式,可以為循環(huán)模式或者正常模式,在循環(huán)模式下傳輸完一輪數(shù)據(jù)之后再重新傳輸,適合ADC不斷采集數(shù)據(jù)等場合,這里是正常模式,也就是一次.

DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; 
配置DMA通道的優(yōu)先級,總線矩陣根據(jù)DMA通道的優(yōu)先級進(jìn)行總線協(xié)調(diào)分配,這里配置為DMA_Priority_Medium(中等優(yōu)先級). 
(在使用1個DMA通道時(shí),配置任何優(yōu)先級都沒有區(qū)別)

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; 
使能內(nèi)存到內(nèi)存的DMA傳輸。DMA傳輸可以在外設(shè)與內(nèi)存,外設(shè)與外設(shè),還可以在內(nèi)存與內(nèi)存之間進(jìn)行傳輸。 
這里用的是內(nèi)存到外設(shè) ,使用DMA_M2M_Disable(禁止內(nèi)存到內(nèi)存的傳輸).

DMA_Init(DMA1_Channel4, &DMA_InitStructure); 
DMA_Cmd (DMA1_Channel4,ENABLE);

填充好結(jié)構(gòu)體后,就使能DMA了,這里用到DMA1_Channel4(DMA1的通道4),這個通道不是隨便選擇的,是根據(jù)DMA的請求映射來選擇的,在《STM32參考手冊》可以找到。 
(DMA請求是指外設(shè)在需要使用DMA前需要向DMA控制器發(fā)送請求信息,DMA在接收到請求后才會根據(jù)DMA配置進(jìn)行數(shù)據(jù)轉(zhuǎn)移。) 
這里寫圖片描述 
PS: 
從圖中可以看到即使同樣是外設(shè)串口1,串口1的發(fā)送數(shù)據(jù) DMA 請求和串口1的接收數(shù)據(jù)DMA請求通道都是不一樣的,分別為DMA1通道4和DMA1的通道5。

DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,ENABLE); 
把DMA配置成DMA_IT_TC(DMA發(fā)送完成標(biāo)志)中斷.DMA_ITConfig是用于外設(shè)中斷的函數(shù).

DMA的中斷: 
中斷配置: 
在DMA_Config()中調(diào)用了NVIC_Config()進(jìn)行DMA中斷配置 
static void NVIC_Config(void) 

NVIC_InitTypeDef NVIC_InitStructure;

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //配置DMA通道的優(yōu)先級組1


NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;//中斷通道

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);


這里的是調(diào)用了NVIC_PriorityGroupConfig()DMA的中斷優(yōu)先級為組1,中斷通道配置為DMA1_Channel4_IRQn.


中斷服務(wù)函數(shù): 

void DMA1_Channel4_IRQHandler(void) 

{


if(DMA_GetFlagStatus(DMA1_FLAG_TC4)==SET)//判斷是否為 DMA 發(fā)送完成中斷

{


LED1(OFF);//LED 關(guān)閉

DMA_ClearFlag(DMA1_FLAG_TC4); //清除DMA中斷標(biāo)志位

}


這個中斷服務(wù)函數(shù)名在啟動文件startup_stm32f10x_hd.s中找到(以前說過,這里再說一次),這里就是檢查中斷標(biāo)志位,關(guān)閉LED燈,清除中斷標(biāo)志位


在main函數(shù)里USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE); 

使能或者關(guān)閉串口的DMA接口,這里配置的是串口1的USART_DMAReq_Tx(串口發(fā)送請求),也可以是USART_DMAReq_Rx(串口接收請求). 

調(diào)用這個庫函數(shù)允許串口外設(shè)向 DMA 發(fā)出請求,請求DMA傳輸數(shù)據(jù)。調(diào)用了這個函數(shù)之后,DMA開始響應(yīng)串口的請求,根據(jù)DMA配置,把數(shù)組中的數(shù)據(jù)一個個地轉(zhuǎn)移到串口數(shù)據(jù)寄存器,并由串口向外發(fā)送這些數(shù)據(jù)。在調(diào)用了USART_DMACmd()函數(shù)之后,接下來在main函數(shù)就把LED點(diǎn)亮了.


PS: 

實(shí)際上,在DMA還沒傳輸完成數(shù)據(jù)的時(shí)候,因?yàn)閮?nèi)核并不參與DMA數(shù)據(jù)傳輸?shù)娜^程,所以內(nèi)核在這個時(shí)候執(zhí)行了點(diǎn)亮LED1的代碼。而當(dāng)DMA傳輸完成時(shí),進(jìn)入了中斷,再把LED1關(guān)閉.


關(guān)鍵字:STM32  DMA  直接存儲器存儲 引用地址:STM32之DMA(直接存儲器存儲)

上一篇:STM32之SPI_FLASH
下一篇:STM32之USART(串口通信)

推薦閱讀

針對近來廣受關(guān)注的比亞迪廣告門事件,比亞迪集團(tuán)高級副總裁兼比亞迪北美分公司總裁李柯向路由社獨(dú)家回應(yīng):?“此事實(shí)在讓我憤怒,遠(yuǎn)在美國矜矜(兢兢)業(yè)業(yè)埋頭苦干時(shí),竟然莫名其妙的被騙子陷害了!警方一定要把什么陳振宇,宋博,李娟以及背后有貓膩的廣告公司一并抓出來,狠狠嚴(yán)懲這樣的欺騙行為!否則天理難容!”??但是,對于路由社進(jìn)一步追問是否...
近日,從網(wǎng)絡(luò)端獲悉,有關(guān)日本政府宣布限制三種日產(chǎn)半導(dǎo)體材料對韓出口的消息鋪天蓋地,相關(guān)業(yè)內(nèi)人士認(rèn)為,此舉動與日方對韓國“強(qiáng)征勞工”案有關(guān)。 斷供材料是用于制造智能手機(jī)與電視機(jī)中OLED顯示器部件使用的“氟聚酰亞胺”、半導(dǎo)體制造過程中必須使用的“光刻膠”和“高純度氟化氫”等半導(dǎo)體的三種材料,由于韓國半導(dǎo)體產(chǎn)業(yè)有關(guān)材料方面對日有很強(qiáng)的依...
C51單片機(jī)中的三種方法解決數(shù)碼管的動態(tài)顯示,使數(shù)碼管顯示1-8數(shù)字。三種方法的代碼如下,此時(shí)讀者需要十分注意你代碼中引腳的先后順序,否則可能達(dá)不到預(yù)期的效果. #include<reg51.h>#define uchar unsigned char#define uint unsigned intuchar code seg1[]={0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80}; //使用的是共陽極數(shù)碼管void delayms...
(文/程文智)7月15日,在第七屆中國機(jī)器人峰會暨智能經(jīng)濟(jì)人才峰會上,中國工程院院士、國家農(nóng)業(yè)信息化工程技術(shù)研究趙春江分享了《農(nóng)業(yè)機(jī)器人展望》的報(bào)告。他在分享中提到,2020年農(nóng)業(yè)機(jī)器人市場的規(guī)模大概為74億美元,預(yù)計(jì)2025年達(dá)到206億美元。他同時(shí)提到了目前農(nóng)業(yè)機(jī)器人遇到的瓶頸問題,以及目前我國在農(nóng)業(yè)機(jī)器人方面的一些實(shí)踐案例。圖:中國工程院...

史海拾趣

小廣播
設(shè)計(jì)資源 培訓(xùn) 開發(fā)板 精華推薦

最新單片機(jī)文章

 
EEWorld訂閱號

 
EEWorld服務(wù)號

 
汽車開發(fā)圈

 
機(jī)器人開發(fā)圈

電子工程世界版權(quán)所有 京ICP證060456號 京ICP備10001474號-1 電信業(yè)務(wù)審批[2006]字第258號函 京公網(wǎng)安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved