娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

歷史上的今天

今天是:2024年10月21日(星期一)

正在發生

2018年10月21日 | STM32學習之:DMA詳解

發布者:創新思維 來源: eefocus關鍵字:STM32  DMA 手機看文章 掃描二維碼
隨時隨地手機看文章

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

DMA有什么用?

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

有多少個DMA資源?

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

數據從什么地方送到什么地方?

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

       SRAM的兩個區域之間;

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

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

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

DMA可以傳遞多少數據?

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

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

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

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

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

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

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

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

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

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

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

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

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

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

外設的事件連接至相應DMA通道,每個通道均可以通過軟件觸發實現存儲器內部的DMA數據傳輸(M2M模式)

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

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

 

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

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

DMA_DeInit(DMA_Channel1);

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

DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;

上面語句中的DMA_InitStructure是一個DMA結構體,在庫中有聲明了,當然使用時就要先定義 了;DMA_PeripheralBaseAddr是該結構體中一個數據成員,給DMA一個起始地址,好比是一個buffer起始地址,數據流程是:外設 寄存器à DMA_PeripheralBaseAddàmemory中變量空間(或flash中數據空間等),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在傳輸時緩沖區的長度,前面有定義過了buffer的起始地址:ADC1_DR_Address ,為了安全性和可靠性,一般需要給buffer定義一個儲存片區,這個參數的單位有三種類型: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建立了聯系,所以選用DMA_PeripheralInc_Disable

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

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

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;

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

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;

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

DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;

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

DMA_InitStructure.DMA_Priority = DMA_Priority_High;

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

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

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

DMA_Init(DMA_Channel1,&DMA_InitStructure);

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

DMA_Cmd(DMA_Channel1,ENABLE);

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

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

要使DMA與外設建立有效連接,這不是DMA自身的事情,是各個外設的事情,每個外設都有 一個xxx_DMACmd(XXXx,Enable )函數,如果使DMA與ADC建立有效聯系,就使用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.2\Project\STM32F10x_StdPeriph_Examples\DMA\FLASH_RAM


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;
  //數據傳輸方向    Peripheral is source               
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
//緩沖區大小 Number of data to be transferred (0 up to 65535).數據傳輸數目     
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);


DMA_ITConfig(DMA1_Channel6, DMA_IT_TC, ENABLE);



DMA_Cmd(DMA1_Channel6, ENABLE);
=======================================================================

外設的DMA請求映像


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

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

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


DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&AD_Value;   
//u16  AD_Value[2];   不加&應該也可以  數組名 代表地址
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);


DMA_Cmd(DMA1_Channel1, ENABLE);


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);
//內部溫度傳感器  添加這一句 

ADC_TempSensorVrefintCmd(ENABLE);
//##############     改了

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

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


ADC_Cmd(ADC1, ENABLE);

   //使用之前一定要校準
ADC_ResetCalibration(ADC1);

while(ADC_GetResetCalibrationStatus(ADC1));


ADC_StartCalibration(ADC1);

while(ADC_GetCalibrationStatus(ADC1));

 
ADC_SoftwareStartConvCmd(ADC1, ENABLE);


關鍵字:STM32  DMA 引用地址:STM32學習之:DMA詳解

上一篇:STM32學習之:FMC-擴展外部SDRAM
下一篇:STM32學習之:SPI讀寫串行Flash

推薦閱讀

2108年10月16日,賽靈思開發者大會在北京召開,本次大會有近千人參加,為廣大軟硬件、嵌入式開發者提供了一個面對面交流、學習、分享經驗的機會。賽靈思的專家團隊以及華為、阿里巴巴、浪潮等數十家國內外領先企業的專家匯聚一堂,與廣大開發者共同探討行業趨勢,分享設計經驗,展示先進案例。在本次大會上賽靈思產品與技術市場營銷高級總監Kirk Saban與...
(文章來源:中科羅伯特機器人學院) 在第21屆中國國際工業博覽會上新松工業和控制平臺正式進行了發布,新松的這次發布得到了各界領導、行業專家以及社會人士的高度關注和重視。新松這次發布的工業軟件和控制平臺將會是我國工業數字化、網絡化發展的基礎,同時也會為我國的細分領域及企業提供各自發揮優勢的平臺,促進著我國制造業轉型升級和國家智能制...
10月21日消息,浙江國自機器人技術股份有限公司擬赴科創板上市,華泰聯合證券任其輔導機構。浙江國自機器人技術股份有限公司,于2011年11月10日成立。公司專注于移動機器人的開發和推廣,集科研開發、生產制造、市場營銷及工程服務為一體,致力于為市場提供一流的具有國際競爭力的機器人技術、產品和解決方案。據了解,國自機器人的業務已覆蓋智能移動機器...
今天,OPPO在線上就行發布會,帶來了K9S的新品,不過其還有另外一個目的,那就是公布雙十一的優惠策略,旗下一大波產品進行了降價,降幅最高的在千元以上,具體來說如下:  Find X3 11月1日當天,至高立減500元,到手價低至3499元,支持24期免息;  K9 Pro(搭載天璣1200處理器、120Hz高刷屏,支持60W超級閃充)11月1日當天直降200元,8+1...

史海拾趣

問答坊 | AI 解惑

晶振不起振的常見原因及解決方案

遇到單片機晶振不起振是常見現象,那么引起晶振不起振的原因有哪些呢? 下面我給大家簡單概括一下: (1) PCB板布線錯誤; (2) 單片機質量有問題; (3) 晶振質量有問題; (4) 負載電容或匹配電容與晶振不匹配或者電容質量有問題; (5) PCB板受 ...…

查看全部問答∨

CE下普通應用開發是選擇C還是高級的.NET(Java)合適?

公司有一定數量的普通應用開發,涉及到Socket或其它網絡通信,而不是開發驅動程序,這種情況下的常見方案是否選擇C/C++?…

查看全部問答∨

不同的嵌入式開發板的區別

舉個例子來引出我的問題 MX27 處理器以MX21 為基礎進行設計,基于ARM926EJ-S s3c2410的處理器是ARM920T 請問各位 首先,之間有什么區別,是不是:1、處理器型號?2、寄存器地址不同?等等 大家能不能幫我說個大概? 其次,編程的時候是不是每 ...…

查看全部問答∨

WinCE4.2定制系統時的問題,緊急求助

本人剛開始學習CE,在用pb定制操作系統的時候碰到了一個無法解決的問題 希望有人能解答一下 我使用的系統版本是4.2,在定制完系統后,build通過了,在下載到emulator以后,運行卻出錯了,以下是我整理的出錯信息,跪求高手解答 2008年3月27日 ...…

查看全部問答∨

急!請教

請問:如何在虛擬機下的linux訪問windows資源啊? 謝謝…

查看全部問答∨

初學者,定制OS遇見個小問題

(CoreCon) Failed to connect debug message service! Please check the transport settings.(CoreCon) Transport service failed to connect(CoreCon) Error: A service has failed to connect. Make sure that all services are correctly config ...…

查看全部問答∨

【MSP430共享】 lcd12864基于msp430F149驅動程序

lcd12864基于msp430F149驅動程序  有需要的童鞋可以下過去看看 …

查看全部問答∨

關于2011 年全國大學生電子設計競賽復測事項的通知

本帖最后由 paulhyde 于 2014-9-15 03:48 編輯    …

查看全部問答∨

altera視頻處理選型求助

我現在想做FPGA視頻處理方面的工作,原理一直用xilinx,現在考慮使用altera,但是不太熟悉。 哪位高手指點下,使用什么樣的芯片或開發板可以滿足高性能的視頻處理。謝謝了…

查看全部問答∨

菜鳥真心求助~時鐘問題

我是個剛接觸dsp的菜鳥,求教大蝦:怎么用5410硬件產生一個1秒的延時。求詳細寄存器配置。謝謝!…

查看全部問答∨
小廣播
設計資源 培訓 開發板 精華推薦

最新單片機文章
何立民專欄 單片機及嵌入式寶典

北京航空航天大學教授,20余年來致力于單片機與嵌入式系統推廣工作。

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發圈

 
機器人開發圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 南京市| 丁青县| 通城县| 靖远县| 泰州市| 手机| 浦县| 乌兰察布市| 阳江市| 乌拉特前旗| 革吉县| 东安县| 游戏| 鄂州市| 兰州市| 江西省| 秦安县| 澳门| 军事| 闽清县| 临高县| 渭源县| 吉林市| 郑州市| 巴中市| 高尔夫| 凤城市| 连城县| 十堰市| 古蔺县| 和政县| 山东| 吉林省| 嘉鱼县| 浦县| 德安县| 湖口县| 化德县| 乌拉特中旗| 万源市| 南充市|