在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            stm32中DMA基本使用

            作者: 時(shí)間:2016-11-19 來源:網(wǎng)絡(luò) 收藏
            DMA有什么用?

            直接存儲(chǔ)器存取用來提供在外設(shè)和存儲(chǔ)器之間或者存儲(chǔ)器和存儲(chǔ)器之間的高速數(shù)據(jù)傳輸。無須CPU的干預(yù),通過DMA數(shù)據(jù)可以快速地移動(dòng)。這就節(jié)省了CPU的資源來做其他操作。

            本文引用地址:http://www.biyoush.com/article/201611/318277.htm

            有多少個(gè)DMA資源?

            有兩個(gè)DMA控制器,DMA1有7個(gè)通道,DMA2有5個(gè)通道。

            數(shù)據(jù)從什么地方送到什么地方?

            外設(shè)到SRAM(I2C/UART等獲取數(shù)據(jù)并送入SRAM);

            SRAM的兩個(gè)區(qū)域之間;

            外設(shè)到外設(shè)(ADC讀取數(shù)據(jù)后送到TIM1控制其產(chǎn)生不同的PWM占空比);

            SRAM到外設(shè)(SRAM中預(yù)先保存的數(shù)據(jù)送入DAC產(chǎn)生各種波形);

            ……還有一些目前還搞不清楚的。

            DMA可以傳遞多少數(shù)據(jù)?

            傳統(tǒng)的DMA的概念是用于大批量數(shù)據(jù)的傳輸,但是我理解,在STM32中,它的概念被擴(kuò)展了,也許更多的時(shí)候快速是其應(yīng)用的重點(diǎn)。數(shù)據(jù)可以從1~65535個(gè)。

            直接存儲(chǔ)器存?。―irect Memory Access,DMA)是計(jì)算機(jī)科學(xué)中的一種內(nèi)存訪問技術(shù)。它允許某些電腦內(nèi)部的硬體子系統(tǒng)(電腦外設(shè)),可以獨(dú)立地直接讀寫系統(tǒng)存儲(chǔ)器,而不需繞道 CPU。在同等程度的CPU負(fù)擔(dān)下,DMA是一種快速的數(shù)據(jù)傳送方式。它允許不同速度的硬件裝置來溝通,而不需要依于 CPU的大量中斷請(qǐng)求。

            現(xiàn)在越來越多的單片機(jī)采用DMA技術(shù),提供外設(shè)和存儲(chǔ)器之間或者存儲(chǔ)器之間的高速數(shù)據(jù)傳輸。當(dāng) CPU 初始化這個(gè)傳輸動(dòng)作,傳輸動(dòng)作本身是由DMA 控制器來實(shí)行和完成。STM32就有一個(gè)DMA控制器,它有7個(gè)通道,每個(gè)通道專門用來管理一個(gè)或多個(gè)外設(shè)對(duì)存儲(chǔ)器訪問的請(qǐng)求,還有一個(gè)仲裁器來協(xié)調(diào)各個(gè)DMA請(qǐng)求的優(yōu)先權(quán)。

            DMA 控制器和Cortex-M3核共享系統(tǒng)數(shù)據(jù)總線執(zhí)行直接存儲(chǔ)器數(shù)據(jù)傳輸。當(dāng)CPU和DMA同時(shí)訪問相同的目標(biāo)(RAM或外設(shè))時(shí),DMA請(qǐng)求可能會(huì)停止 CPU訪問系統(tǒng)總線達(dá)若干個(gè)周期,總線仲裁器執(zhí)行循環(huán)調(diào)度,以保證CPU至少可以得到一半的系統(tǒng)總線(存儲(chǔ)器或外設(shè))帶寬。

            在發(fā)生一個(gè)事件后,外設(shè)發(fā)送一個(gè)請(qǐng)求信號(hào)到DMA控制器。DMA控制器根據(jù)通道的優(yōu)先權(quán)處理請(qǐng)求。當(dāng)DMA控制器開始訪問外設(shè)的時(shí)候,DMA控制器立即發(fā)送給外設(shè)一個(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)。如果發(fā)生更多的請(qǐng)求時(shí),外設(shè)可以啟動(dòng)下次處理。

            總之,每個(gè)DMA傳送由3個(gè)操作組成:

            1. 從外設(shè)數(shù)據(jù)寄存器或者從DMA_CMARx寄存器指定地址的存儲(chǔ)器單元執(zhí)行加載操作。

            2. 存數(shù)據(jù)到外設(shè)數(shù)據(jù)寄存器或者存數(shù)據(jù)到DMA_CMARx寄存器指定地址的存儲(chǔ)器單元。

            3. 執(zhí)行一次DMA_CNDTRx寄存器的遞減操作。該寄存器包含未完成的操作數(shù)目。

            仲裁器根據(jù)通道請(qǐng)求的優(yōu)先級(jí)來啟動(dòng)外設(shè)/存儲(chǔ)器的訪問。優(yōu)先級(jí)分為兩個(gè)等級(jí):軟件(4個(gè)等級(jí):最高、高、中等、低)、硬件(有較低編號(hào)的通道比擁有較高編號(hào)的通道有較高的優(yōu)先權(quán))。

            可以在DMA傳輸過半、傳輸完成和傳輸錯(cuò)誤時(shí)產(chǎn)生中斷。

            STM32中DMA的不同中斷(傳輸完成、半傳輸、傳輸完成)通過“線或”方式連接至NVIC,需要在中斷例程中進(jìn)行判斷。

            進(jìn)行DMA配置前,不要忘了在RCC設(shè)置中使能DMA時(shí)鐘。STM32的DMA控制器掛在AHB總線上。

            DMA總共有7個(gè)通道,各個(gè)通道的DMA映射關(guān)系如下:

            外設(shè)的事件連接至相應(yīng)DMA通道,每個(gè)通道均可以通過軟件觸發(fā)實(shí)現(xiàn)存儲(chǔ)器內(nèi)部的DMA數(shù)據(jù)傳輸(M2M模式)

            Tips:庫2.0中函數(shù)RCC_AHBPeriphClockCmd的參數(shù)由“RCC_AHBPeriph_DMA”改成“RCC_AHBPeriph_DMA1”(如果是DMA1控制器的話)。

            DMA的傳輸標(biāo)志位(CHTIFx、CTCIFx、CGIFx)由硬件設(shè)置為“1”,但需要軟件清零,在中斷服務(wù)程序中清除。當(dāng)CGIFx(全局中斷標(biāo)志位)清零后,CHTIFx 和 CTCIFx均清零。

            過程:怎樣啟用DMA?首先,眾所周知的是初始化,任何設(shè)備啟用前都要對(duì)其進(jìn)行初始化,要對(duì)模塊初始化,還要先了解該模塊相應(yīng)的結(jié)構(gòu)及其函數(shù),以便正確的設(shè)置;由于DMA較為復(fù)雜,我就只談?wù)凞MA的基本結(jié)構(gòu)和和常用函數(shù),這些都是ST公司提供在庫函數(shù)中的。

            1、 下面代碼是一個(gè)標(biāo)準(zhǔn)DMA設(shè)置,當(dāng)然實(shí)際應(yīng)用中可根據(jù)實(shí)際情況進(jìn)行裁減:

            DMA_DeInit(DMA_Channel1);

            上面這句是給DMA配置通道,根據(jù)ST提供的資料,STM3210Fx中DMA包含7個(gè)通道(CH1~CH7),也就是說可以為外設(shè)或memory提供7座“橋梁”(請(qǐng)?jiān)试S我使用橋梁一詞,我覺得更容易理解,,別“拍磚”呀?。?/p>

            DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;

            上面語句中的DMA_InitStructure是一個(gè)DMA結(jié)構(gòu)體,在庫中有聲明了,當(dāng)然使用時(shí)就要先定義了;DMA_PeripheralBaseAddr是該結(jié)構(gòu)體中一個(gè)數(shù)據(jù)成員,給DMA一個(gè)起始地址,好比是一個(gè)buffer起始地址,數(shù)據(jù)流程是:外設(shè)寄存器à DMA_PeripheralBaseAddàmemory中變量空間(或flash中數(shù)據(jù)空間等),ADC1_DR_Address是我定義的一個(gè)地址變量;

            DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_ConvertedValue;

            上面這句很顯然是DMA要連接在Memory中變量的地址,ADC_ConvertedValue是我自己在memory中定義的一個(gè)變量;

            DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

            上面的這句是設(shè)置DMA的傳輸方向,就如前面我所說的,DMA可以雙向傳輸,也可以單向傳輸,這里設(shè)置的是單向傳輸,如果需要雙向傳輸:把DMA_DIR_PeripheralSRC改成DMA_DIR_PeripheralDST即可。

            DMA_InitStructure.DMA_BufferSize = 2;

            上面的這句是設(shè)置DMA在傳輸時(shí)緩沖區(qū)的長度,前面有定義過了buffer的起始地址:ADC1_DR_Address ,為了安全性和可靠性,一般需要給buffer定義一個(gè)儲(chǔ)存片區(qū),這個(gè)參數(shù)的單位有三種類型:Byte、HalfWord、word,我設(shè)置的2個(gè)half-word(見下面的設(shè)置);32位的MCU中1個(gè)half-word占16 bits。

            DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

            上面的這句是設(shè)置DMA的外設(shè)遞增模式,如果DMA選用的通道(CHx)有多個(gè)外設(shè)連接,需要使用外設(shè)遞增模式:DMA_PeripheralInc_Enable;我的例子里DMA只與ADC1建立了聯(lián)系,所以選用DMA_PeripheralInc_Disable

            DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

            上面的這句是設(shè)置DMA的內(nèi)存遞增模式,DMA訪問多個(gè)內(nèi)存參數(shù)時(shí),需要使用DMA_MemoryInc_Enable,當(dāng)DMA只訪問一個(gè)內(nèi)存參數(shù)時(shí),可設(shè)置成:DMA_MemoryInc_Disable。

            DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;

            上面的這句是設(shè)置DMA在訪問時(shí)每次操作的數(shù)據(jù)長度。有三種數(shù)據(jù)長度類型,前面已經(jīng)講過了,這里不在敘述。

            DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;

            與上面雷同。在此不再說明。

            DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;

            上面的這句是設(shè)置DMA的傳輸模式:連續(xù)不斷的循環(huán)模式,若只想訪問一次后就不要訪問了(或按指令操作來反問,也就是想要它訪問的時(shí)候就訪問,不要它訪問的時(shí)候就停止),可以設(shè)置成通用模式:DMA_Mode_Normal

            DMA_InitStructure.DMA_Priority = DMA_Priority_High;

            上面的這句是設(shè)置DMA的優(yōu)先級(jí)別:可以分為4級(jí):VeryHigh,High,Medium,Low.

            DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

            上面的這句是設(shè)置DMA的2個(gè)memory中的變量互相訪問的

            DMA_Init(DMA_Channel1,&DMA_InitStructure);

            前面那些都是對(duì)DMA結(jié)構(gòu)體成員的設(shè)置,在次再統(tǒng)一對(duì)DMA整個(gè)模塊做一次初始化,使得DMA各成員與上面的參數(shù)一致。

            /*DMA Enable*/

            DMA_Cmd(DMA_Channel1,ENABLE);

            stm32使用DMA的相關(guān)操作:
            1、DMA的配置
            要配置的有DMA傳輸通道選擇,傳輸?shù)某蓡T和方向、普通模式還是循環(huán)模式等等。
            void DMA_Configuration(void)
            {
            DMA_InitTypeDef DMA_InitStructure;
            //DMA設(shè)置:
            //設(shè)置DMA源:內(nèi)存地址&串口數(shù)據(jù)寄存器地址
            //方向:內(nèi)存-->外設(shè)
            //每次傳輸位:8bit
            //傳輸大小DMA_BufferSize=SENDBUFF_SIZE
            //地址自增模式:外設(shè)地址不增,內(nèi)存地址自增1
            //DMA模式:一次傳輸,非循環(huán)
            //優(yōu)先級(jí):中
            DMA_DeInit(DMA1_Channel4);//串口1的DMA傳輸通道是通道4
            DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base;
            DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff;
            DMA_InitStructure.DMA_DIR =DMA_DIR_PeripheralDST;//外設(shè)作為DMA的目的端
            DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE;//傳輸大小
            DMA_InitStructure.DMA_PeripheralInc =DMA_PeripheralInc_Disable;//外設(shè)地址不增加
            DMA_InitStructure.DMA_MemoryInc =DMA_MemoryInc_Enable;//內(nèi)存地址自增1
            DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
            DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
            DMA_InitStructure.DMA_Mode =DMA_Mode_Circular;
            //DMA_Mode_Normal(只傳送一次),DMA_Mode_Circular (不停地傳送)
            DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;//(DMA傳送優(yōu)先級(jí)為中等)
            DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
            DMA_Init(DMA1_Channel4, &DMA_InitStructure);
            }
            注:
            1、傳輸通道:通過查表,串口1的發(fā)送對(duì)應(yīng)的是DMA的通道4,所以此處選擇通道4.
            2、DMA傳輸方式:
            (1) DMA_Mode_Normal,正常模式,當(dāng)一次DMA數(shù)據(jù)傳輸完后,停止DMA傳送,對(duì)于上例而言,就是DMA_PeripheralDataSize_Byte個(gè)字節(jié)的傳送完成后,就停止傳送。
            (2)DMA_Mode_Circular
            循環(huán)模式,當(dāng)傳輸完一次后,重新接著傳送,永不停息。
            2、外設(shè)的DMA方式設(shè)置
            將串口1設(shè)置成DMA模式:
            USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
            3、待傳輸數(shù)據(jù)的定義和初始化
            #define SENDBUFF_SIZE 10240
            vu8 SendBuff[SENDBUFF_SIZE];
            for(i=0;i {
            SendBuff[i] = i%10+0;
            }
            4、開始DMA傳輸(使能對(duì)應(yīng)的DMA通道)
            DMA_Cmd(DMA1_Channel4, ENABLE);
            5、DMA傳輸?shù)耐瓿?/div>
            while(DMA_GetFlagStatus(DMA1_FLAG_TC4) == RESET)
            {
            LED_1_REV; //LED翻轉(zhuǎn)
            Delay(); //浪費(fèi)時(shí)間
            }
            當(dāng)傳輸完成后,就會(huì)跳出上面的死循環(huán)。


            關(guān)鍵詞: stm32DMA基本使

            評(píng)論


            技術(shù)專區(qū)

            關(guān)閉