www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當前位置:首頁 > 單片機 > 單片機
[導讀]DMA部分我用到的相對簡單,當然,可能這是新東西,我暫時還用不到它的復雜功能吧。下面用問答的形式表達我的思路。DMA有什么用? 直接存儲器存取用來提供在外設和存儲器之間或者存儲器和存儲器之間的高速數(shù)據(jù)傳輸。無

DMA部分我用到的相對簡單,當然,可能這是新東西,我暫時還用不到它的復雜功能吧。下面用問答的形式表達我的思路。

DMA有什么用?

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

有多少個DMA資源?

有兩個DMA控制器,DMA1有7個通道,DMA2有5個通道。

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

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

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

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

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

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

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

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

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

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

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

在發(fā)生一個事件后,外設發(fā)送一個請求信號到DMA控制器。DMA控制器根據(jù)通道的優(yōu)先權處理請求。當DMA控制器開始訪問外設的時候,DMA控制器立即發(fā)送給外設一個應答信號。當從DMA控制器得到應答信號時,外設立即釋放它的請求。一旦外設釋放了這個請求,DMA控制器同時撤銷應答信號。如果發(fā)生更多的請求時,外設可以啟動下次處理。

總之,每個DMA傳送由3個操作組成:

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

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

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

仲裁器根據(jù)通道請求的優(yōu)先級來啟動外設/存儲器的訪問。優(yōu)先級分為兩個等級:軟件(4個等級:最高、高、中等、低)、硬件(有較低編號的通道比擁有較高編號的通道有較高的優(yōu)先權)。

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

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

進行DMA配置前,不要忘了在RCC設置中使能DMA時鐘。STM32的DMA控制器掛在AHB總線上。

DMA總共有7個通道,各個通道的DMA映射關系如下:

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

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

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

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

1、 下面代碼是一個標準DMA設置,當然實際應用中可根據(jù)實際情況進行裁減:

DMA_DeInit(DMA_Channel1);

上面這句是給DMA配置通道,根據(jù)ST提供的資料,STM3210Fx中DMA包含7個通道(CH1~CH7),也就是說可以為外設或memory提供7座“橋梁”(請允許我使用橋梁一詞,我覺得更容易理解,哈哈,別“拍磚”呀?。?;

DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;

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

DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_ConvertedValue;

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

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

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

DMA_InitStructure.DMA_BufferSize = 2;

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

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

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

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

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

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;

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

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;

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

DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;

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

DMA_InitStructure.DMA_Priority = DMA_Priority_High;

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

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

上面的這句是設置DMA的2個memory中的變量互相訪問的

DMA_Init(DMA_Channel1,&DMA_InitStructure);

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

/*DMA Enable*/

DMA_Cmd(DMA_Channel1,ENABLE);

哈哈哈!這一句我想我就不羅嗦了,大家一看就明白。

至此,整個DMA總算設置好了,但是,DMA通道又是怎樣與外設聯(lián)系在一起的呢?哈哈,這也是我當初最想知道的一個事情,別急!容我想喝口茶~~~~~~哈哈哈!

要使DMA與外設建立有效連接,這不是DMA自身的事情,是各個外設的事情,每個外設都有 一個xxx_DMACmd(XXXx,Enable )函數(shù),如果使DMA與ADC建立有效聯(lián)系,就使用ADC_DMACmd(ADC1,Enable); (這里我啟用了ADC中的ADC1模塊)。

一個簡單的例子 transfer a word data buffer from FLASH memory to embedded SRAM memory.
在V3.1.2庫的位置
STM32F10x_StdPeriph_Lib_V3.1.2ProjectSTM32F10x_StdPeriph_ExamplesDMAFLASH_RAM

/* DMA1 channel6 configuration */
DMA_DeInit(DMA1_Channel6);
//peripheral base address
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SRC_Const_Buffer;
//memory base address
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)DST_Buffer;
//數(shù)據(jù)傳輸方向 Peripheral is source
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
//緩沖區(qū)大小 Number of data to be transferred (0 up to 65535).數(shù)據(jù)傳輸數(shù)目
DMA_InitStructure.DMA_BufferSize = BufferSize;
// the Peripheral address register is incremented
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;
//the memory address register is incremented
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
//the Peripheral data width
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
//the DMAy Channelx will be used in memory-to-memory transfer
//DMA通道的操作可以在沒有外設請求的情況下進行,這種操作就是存儲器到存儲器模式。
DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;
DMA_Init(DMA1_Channel6, &DMA_InitStructure);

/* Enable DMA1 Channel6 Transfer Complete interrupt */
DMA_ITConfig(DMA1_Channel6, DMA_IT_TC, ENABLE);


/* Enable DMA1 Channel6 transfer */
DMA_Cmd(DMA1_Channel6, ENABLE);
=======================================================================

外設的DMA請求映像


要使DMA與外設建立有效連接,這不是DMA自身的事情,是各個外設的事情,每個外設都有 一個

xxx_DMACmd(XXXx,Enable )函數(shù),如果使DMA與ADC建立有效聯(lián)系,就使用 ADC_DMACmd

(ADC1,Enable); (這里我啟用了ADC中的ADC1模塊)。

/* DMA1 channel1 configuration ----------------------------------------------*/
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&AD_Value;
//u16 AD_Value[2]; 不加&應該也可以 數(shù)組名 代表地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 2; //############## 改了
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //############## 改了
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);

/* Enable DMA1 channel 1 */
DMA_Cmd(DMA1_Channel1, ENABLE);

/* ADC1 configuration------------------------------------------------------*/
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 2; //############## 改了
ADC_Init(ADC1, &ADC_InitStructure);
//內(nèi)部溫度傳感器 添加這一句
/* Enable the temperature sensor and vref internal channel */
ADC_TempSensorVrefintCmd(ENABLE);
//############## 改了

//################ Channel 10(電位器)
ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_13Cycles5);
//###### 內(nèi)部溫度傳感器 Channel 16 ###################
ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 2, ADC_SampleTime_55Cycles5);

/* Enable ADC1 DMA */使能ADC1的DMA請求映像
ADC_DMACmd(ADC1, ENABLE);

/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);

/* Enable ADC1 reset calibaration register */ //使用之前一定要校準
ADC_ResetCalibration(ADC1);
/* Check the end of ADC1 reset calibration register */
while(ADC_GetResetCalibrationStatus(ADC1));

/* Start ADC1 calibaration */
ADC_StartCalibration(ADC1);
/* Check the end of ADC1 calibration */
while(ADC_GetCalibrationStatus(ADC1));

/* Start ADC1 Software Conversion */
ADC_SoftwareStartConvCmd(ADC1, ENABLE);

本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

在嵌入式開發(fā)中,STM32的時鐘系統(tǒng)因其靈活性和復雜性成為開發(fā)者關注的焦點。然而,看似簡單的時鐘配置背后,隱藏著諸多易被忽視的陷阱,輕則導致系統(tǒng)不穩(wěn)定,重則引發(fā)硬件損壞。本文從時鐘源選擇、PLL配置、總線時鐘分配等關鍵環(huán)...

關鍵字: STM32 時鐘系統(tǒng)

在嵌入式系統(tǒng)開發(fā)中,STM32系列微控制器的內(nèi)部溫度傳感器因其低成本、高集成度特性,廣泛應用于設備自檢、環(huán)境監(jiān)測等場景。然而,受芯片工藝差異和電源噪聲影響,其原始數(shù)據(jù)存在±1.5℃的固有誤差。本文從硬件配置、校準算法、軟...

關鍵字: STM32 溫度傳感器

在能源效率與智能化需求雙重驅動下,AC-DC轉換器的數(shù)字控制技術正經(jīng)歷從傳統(tǒng)模擬方案向全數(shù)字架構的深刻變革?;赟TM32微控制器的PFM(脈沖頻率調(diào)制)+PWM(脈沖寬度調(diào)制)混合調(diào)制策略,結合動態(tài)電壓調(diào)整(Dynam...

關鍵字: AC-DC STM32

當前智能家居產(chǎn)品需求不斷增長 ,在這一背景下 ,對現(xiàn)有澆花裝置缺陷進行了改進 ,設計出基于STM32單片機的全 自動家用澆花機器人。該設計主要由機械結構和控制系統(tǒng)構成 ,機械結構通過麥克納姆輪底盤與噴灑裝置的結合實現(xiàn)機器...

關鍵字: STM32 麥克納姆輪 安全可靠 通過性強

用c++編程似乎是讓你的Arduino項目起步的障礙嗎?您想要一種更直觀的微控制器編程方式嗎?那你需要了解一下Visuino!這個圖形化編程平臺將復雜電子項目的創(chuàng)建變成了拖動和連接塊的簡單任務。在本文中,我們將帶您完成使...

關鍵字: Visuino Arduino ESP32 STM32

基于STM32與LoRa技術的無線傳感網(wǎng)絡憑借其低功耗、廣覆蓋、抗干擾等特性,成為環(huán)境監(jiān)測、工業(yè)自動化等場景的核心解決方案。然而,如何在復雜電磁環(huán)境中實現(xiàn)高效休眠調(diào)度與動態(tài)信道優(yōu)化,成為提升網(wǎng)絡能效與可靠性的關鍵挑戰(zhàn)。本...

關鍵字: STM32 LoRa

在實時控制系統(tǒng)、高速通信協(xié)議處理及高精度數(shù)據(jù)采集等對時間敏感的應用場景中,中斷響應延遲的優(yōu)化直接決定了系統(tǒng)的可靠性與性能上限。STM32系列微控制器憑借其靈活的嵌套向量中斷控制器(NVIC)、多通道直接內(nèi)存訪問(DMA)...

關鍵字: STM32 DMA

數(shù)字電源技術向高功率密度、高效率與高動態(tài)響應方向加速演進,STM32微控制器憑借其基于DSP庫的算法加速能力與對LLC諧振變換器的精準控制架構,成為優(yōu)化電源動態(tài)性能的核心平臺。相較于傳統(tǒng)模擬控制或通用型數(shù)字控制器,STM...

關鍵字: STM32 數(shù)字電源

STM32微控制器憑借其針對電機控制場景的深度優(yōu)化,成為高精度、高可靠性驅動系統(tǒng)的核心選擇。相較于通用型MCU,STM32在電機控制領域的核心優(yōu)勢集中體現(xiàn)在FOC(磁場定向控制)算法的硬件加速引擎與PWM死區(qū)時間的動態(tài)補...

關鍵字: STM32 電機控制

無線充電技術加速滲透消費電子與汽車電子領域,基于Qi協(xié)議的無線充電發(fā)射端開發(fā)成為智能設備能量補給的核心課題。傳統(tǒng)模擬控制方案存在響應滯后、參數(shù)調(diào)整困難等問題,而基于STM32的數(shù)字PID控制結合FOD(Foreign O...

關鍵字: STM32 無線充電
關閉