基于STM32 + DMA介紹,應用和步驟詳解(ADC多通道)

前言

????????本篇博客主要學習了解DMA的工作原理和部分寄存器解析,針對ADC多通道來對代碼部分,應用部分作詳細講解,掌握代碼編程原理。本篇博客大部分是自己收集和整理,如有侵權請聯系我刪除。

本次博客開發板使用的是正點原子精英版,芯片是STM32F103ZET6,需要資料可以@我拿取。

交流群:717237739

本博客內容原創,創作不易,轉載請注明
————————————————

一 . DMA的基本介紹

  • DMA(Direct Memory Access)直接存儲器存取
  • DMA可以提供外設和存儲器或者存儲器和存儲器之間的高速數據傳輸,無須CPU干預,節省了CPU的資源
  • DMA傳輸將數據從一個地址空間復制到另一個地址空間。當CPU初始化這個傳輸動作,傳輸動作本身是由DMA控制器來實現和完成的。
  • DMA傳輸方式無需CPU直接控制傳輸,也沒有中斷處理方式那樣保留現場和恢復現場過程,通過硬件為RAM和IO設備開辟一條直接傳輸數據的通道,使得CPU的效率大大提高。

作用:為CPU減負。

因此:轉移數據(尤其是轉移大量數據)是可以不需要CPU參與。比如希望外設A的數據拷貝到外設B,只要給兩種外設提供一條數據通路,直接讓數據由A拷貝到B 不經過CPU的處理

二 . DMA的特性

  • 12個獨立的可配置的通道(請求)DMA17個通道,DMA25個通道
  • 每個通道都直接連接專用的硬件DMA請求,每個通道都同樣支持軟件觸發。這些功能通過軟件來配置。
  • 在同一個DMA模塊上,多個請求間的優先權可以通過軟件編程設置(共有四級:很高、高、中等和低),優先權設置相等時由硬件決定(請求0優先于請求1,依此類推)

? ? ? ? 在相等的優先級下,DMA1通道2的優先級是 大于 DMA1通道4,通道越低優先級越高。

  • 獨立數據源和目標數據區的?傳輸寬度(字節、半字、全字)?,模擬打包和拆包的過程。源和目標地址必須按數據傳輸寬度對齊。
  • 支持循環的緩沖器管理
  • 每個通道都有3個事件標志(DMA半傳輸、DMA傳輸完成和DMA傳輸出錯),這3個事件標志
  • 邏輯或成為一個單獨的中斷請求。
  • 存儲器和存儲器間的傳輸
  • 外設和存儲器、存儲器和外設之間的傳輸
  • 閃存、SRAM、外設的SRAM、APB1、APB2和AHB外設均可作為訪問的源和目標
  • 可編程的數據傳輸數目:最大為65535

三. 存儲器映像

四 . DMA功能框圖?

1.功能描述

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

1DMA2僅存在于大容量產品和互聯型產品。
2SPI/I2S3UART4TIM5TIM6TIM7DACDMA請求僅存在于大容量產品和互聯型產品。
3ADC3SDIOTIM8DMA請求僅存在于大容量產品。

?2.DMA仲裁器

3.DMA通道?

1.DMA1 控制器?

從外設 (TIMx[x=1 2 3 4] ADC1 SPI1 SPI/I2S2 I2Cx[x=1 2] USARTx[x=1 2 3])
產生的 7 個請求,通過邏輯或輸入到 DMA1 控制器,這意味著同時只能有一個請求有效。
外設的 DMA 請求,可以通過設置相應外設寄存器中的控制位,被獨立地開啟或關閉。

2.DMA 1 各通道一覽:

3.DMA 2 控制器

從外設 (TIMx[5 6 7 8] ADC3 SPI/I2S3 UART4 DAC 通道 1 2 SDIO) 產生的 5 個請
求,經邏輯或輸入到 DMA2 控制器,這意味著同時只能有一個請求有效。

4.DMA 2 各通道一覽:

5.DMA傳輸方式


????????DMA的作用就是實現數據的直接傳輸,而去掉了傳統數據傳輸需要CPU寄存器參與的環節,主要涉及四種情況的數據傳輸,但本質上是一樣的,都是從內存的某一區域傳輸到內存的另一區域(外設的數據寄存器本質上就是內存的一個存儲單元)。四種情況的數據傳輸如下:

  • 外設到內存

  • 內存到外設

  • 內存到內存

  • 外設到外設

6 .DMA傳輸參數


??我們知道,數據傳輸,首先需要的是

1 數據的源地址

2 數據傳輸位置的目標地址

3 傳遞數據多少的數據傳輸量

4 進行多少次傳輸的傳輸模式 DMA所需要的核心參數

????????當用戶將參數設置好,主要涉及源地址、目標地址、傳輸數據量這三個,DMA控制器就會啟動數據傳輸,當剩余傳輸數據量為0時 達到傳輸終點,結束DMA傳輸 ,當然,DMA 還有循環傳輸模式 當到達傳輸終點時會重新啟動DMA傳輸。
  
也就是說只要剩余傳輸數據量不是0,而且DMA是啟動狀態,那么就會發生數據傳輸。

6.?stm32中DMA的circle和normal模式的區別

?

在STM32系列微控制器上,DMA(Direct Memory Access,直接內存訪問)是一種用于高效數據傳輸的重要功能。DMA的Circle(循環)模式和Normal(普通)模式是兩種常見的DMA傳輸模式,它們在數據傳輸方面有一些區別。

Circle(循環)模式:

  • 在Circle模式下,DMA傳輸可以循環執行,即在完成一次傳輸后會自動重新開始下一次傳輸,形成一個循環。這種模式適用于需要連續、循環傳輸數據的場景。
  • 在循環模式下,DMA傳輸會持續不斷地從源地址讀取數據,并將數據寫入目標地址,直到達到設定的傳輸長度或觸發停止條件。
  • 循環模式下的DMA傳輸通常用于周期性的數據傳輸,如音頻、視頻流等連續數據流的傳輸。

Normal(普通)模式:

  • 在Normal模式下,DMA傳輸只會執行一次,傳輸完畢后就會停止。這種模式適用于單次數據傳輸的場景。
  • 在普通模式下,DMA傳輸會從源地址讀取數據,并將數據寫入目標地址,直到達到設定的傳輸長度或觸發停止條件,然后傳輸停止。
  • 普通模式下的DMA傳輸適用于需要一次性傳輸數據的情況,如初始化數據、配置信息等。

需要注意的是,循環模式和普通模式都可以設置傳輸長度、源地址和目標地址等參數,區別主要在于傳輸的執行方式和傳輸結束后是否重新開始。

在使用DMA時,需要根據具體的應用需求選擇適合的模式。

如果需要連續、循環傳輸數據,可以選擇循環模式;

如果只需進行單次傳輸,可以選擇普通模式。

同時,還需要注意設置適當的傳輸長度和停止條件,以確保傳輸的準確性和可靠性。
?

五 . DMA 的配置和應用

1.DMA運作過程圖解:

下面看有與沒有DMA的情況下,ADC采集的數據是怎樣存放到SRAM中的?

沒有DMA

1.如果沒有DMA,CPU傳輸數據還要以內核作為中轉站,比如要將ADC采集的數據轉移到到SRAM中,這個過程是這樣的:

內核通過DCode經過總線矩陣協調,從獲取AHB存儲的外設ADC采集的數據,

然后內核再通過DCode經過總線矩陣協調把數據存放到內存SRAM中。

?

參考博客鏈接:https://blog.csdn.net/as480133937/article/details/104927922

2.DMA數據流(僅存在于STM32F4 /M4 內核上)了解即可

在設置了DMA的通道之后,還要選擇通道對應外設的數據流

3.指針增量

存儲器到存儲器:源和目標的指針都需要設置為增量模式

存儲器到外設 存儲器地址設置為增量模式外設地址設置為非增量模式。

4.通道配置過程:

0 .開DMA時鐘

1. DMA_CPARx寄存器中設置外設寄存器的地址。發生外設數據傳輸請求時,這個地址將
是數據傳輸的源或目標。
2. DMA_CMARx寄存器中設置數據存儲器的地址。發生外設數據傳輸請求時,傳輸的數
據將從這個地址讀出或寫入這個地址。
3. DMA_CNDTRx寄存器中設置要傳輸的數據量。在每個數據傳輸后,這個數值遞減。
4. DMA_CCRx寄存器的PL[1:0]位中設置通道的優先級。
5. DMA_CCRx寄存器中設置數據傳輸的方向、循環模式、外設和存儲器的增量模式、
設和存儲器的數據寬度?---CCRX存器
6. 設置DMA_CCRx寄存器的ENABLE位,啟動該通道。

5 .DMA中斷

?每個DMA通道都可以在DMA傳輸過半、傳輸完成和傳輸錯誤時產生中斷。為應用的靈活性考慮,通過設置寄存器的不同位來打開這些中斷。

?六. DMA配置過程

這個部分我們結合ADC來進行講解使用:

DMA配置參數包括:通道地址、優先級、數據傳輸方向、存儲器/外設數據寬度、存儲器/外設地址是否增量、循環模式、數據傳輸量。

?ADC+DMA多通道框圖:

ADC詳解在另一個博客:ADC 講解

配置初始化代碼:

#include "stm32f10x.h"                  // Device headeruint16_t AD_Value[4];void AD_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);RCC_ADCCLKConfig(RCC_PCLK2_Div6);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);//開啟對應通道ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_55Cycles5);ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_55Cycles5);ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_55Cycles5);ADC_InitTypeDef ADC_InitStructure;			ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;								//ADC工作模式:ADC1和ADC2工作在獨立模式ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;							//數據右對齊ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//轉換由軟件而不是外部觸發啟動ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;									//模數轉換工作在循環轉換模式ADC_InitStructure.ADC_ScanConvMode = ENABLE;												//模數轉換工作在多通道模式ADC_InitStructure.ADC_NbrOfChannel = 4;															//順序進行規則轉換的ADC通道的數目ADC_Init(ADC1, &ADC_InitStructure);										//根據ADC_InitStruct中指定的參數初始化外設ADCx的寄存器   DMA_InitTypeDef DMA_InitStructure;DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;							// ADC- DMA外設基地址DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;	//半字傳輸,數據寬度為16位DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;						//外設地址不自增DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)AD_Value;									//存儲器數據存儲地址  數組DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;					//半字傳輸,數據寬度為16位DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;											//存儲器內存地址寄存器遞增DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;													//數據傳輸方向,從外設讀取發送到存儲器DMA_InitStructure.DMA_BufferSize = 4;																				//掃描通道:4個DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;															//循環模式DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;																//DMA通道x沒有設置為內存到內存傳輸DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;												//DMA通道 x擁有中優先級 DMA_Init(DMA1_Channel1, &DMA_InitStructure);DMA_Cmd(DMA1_Channel1, ENABLE);									//使能DMAADC_DMACmd(ADC1, ENABLE);												//使能ADC_DMA傳輸ADC_Cmd(ADC1, ENABLE);													//使能ADCADC_ResetCalibration(ADC1);													//使能復位校準  while (ADC_GetResetCalibrationStatus(ADC1) == SET);	//等待復位校準結束ADC_StartCalibration(ADC1);													//開啟AD校準while (ADC_GetCalibrationStatus(ADC1) == SET);			//等待校準結束ADC_SoftwareStartConvCmd(ADC1, ENABLE);							//使能指定的ADC1的軟件轉換啟動功能
}

?庫函數講解,摘自群友的筆記:

?

總結:


? ? ? DMA的使用并不復雜,搞清楚數據的方向,還是是否自增就行了,多使用多實踐,大家如果對我的博客有疑問或者錯誤,可以@我修改,大家相互交流。

交流群:717237739

如果覺得有用點贊關注收藏三連,多謝支持

? 點贊收藏關注博主,不定期分享單片機知識,互相學習交流。
————————————————

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/209443.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/209443.shtml
英文地址,請注明出處:http://en.pswp.cn/news/209443.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

23種策略模式之策略模式

文章目錄 前言優缺點使用場景角色定義UML模擬示例小結 前言 在軟件開發中,設計模式是為了解決常見問題而提供的一套可重用的解決方案。策略模式(Strategy Pattern)是其中一種常見的設計模式,它屬于行為型模式。該模式的核心思想是…

Java程序設計實驗6 | 集合類

*本文是博主對Java各種實驗的再整理與詳解,除了代碼部分和解析部分,一些題目還增加了拓展部分(?)。拓展部分不是實驗報告中原有的內容,而是博主本人自己的補充,以方便大家額外學習、參考。 (解…

基于ssm的大型商場會員管理系統論文

摘 要 進入信息時代以來,很多數據都需要配套軟件協助處理,這樣可以解決傳統方式帶來的管理困擾。比如耗時長,成本高,維護數據困難,數據易丟失等缺點。本次使用數據庫工具MySQL和編程框架SSM開發的大型商場會員管理系統…

【漏洞復現】FLIR AX8紅外線熱成像儀命令執行漏洞

漏洞描述 eledyne FLIR 設計、開發、制造以及強大的傳感和意識技術。自透射熱圖像、可見光圖像、可見頻率分析、來自測量和診斷的先進威脅測量系統以及日常生活的創新解決方案。 Teledyne FLIR 提供多種產品用于政府、國防、工業和商業市場。我們的產品,緊急救援人員,軍事人…

插入排序與希爾排序(C語言實現)

1.插入排序 由上面的動圖可以知道插入排序的邏輯就是從第一個元素開始往后遍歷,如果找到比前一個元素小的(或者大的)就往前排,所以插入排序的每一次遍歷都會保證前面的數據是有序的,接下類用代碼進行講解。 我們這里傳…

bash中通過變量中的內容獲取對應的關聯數組

bash中通過變量中的內容獲取對應的關聯數組 Bash declare 手冊: https://phoenixnap.com/kb/bash-declare 實際問題: 在 bash 中創建了多個關聯數組,需要根據輸入的值,獲取不同的關聯數組。 可以使用 if 進行多次判斷&#xff…

智能優化算法應用:基于浣熊算法無線傳感器網絡(WSN)覆蓋優化 - 附代碼

智能優化算法應用:基于浣熊算法無線傳感器網絡(WSN)覆蓋優化 - 附代碼 文章目錄 智能優化算法應用:基于浣熊算法無線傳感器網絡(WSN)覆蓋優化 - 附代碼1.無線傳感網絡節點模型2.覆蓋數學模型及分析3.浣熊算法4.實驗參數設定5.算法結果6.參考文獻7.MATLAB…

解決HTTP錯誤500.19 - internal server error -內部服務器錯誤的終極指南

在開發和維護網絡應用程序時,難免會遇到各種HTTP錯誤代碼。其中,HTTP錯誤500.19 - 內部服務器錯誤可謂是最令人頭痛的問題之一。當你的應用程序遇到這個錯誤時,它似乎就像一道墻壁,擋住了你前進的道路。但別擔心,本篇技…

Git全局設置命令---設置提交人姓名

介紹 使用git命令設置提交人姓名 命令 git config --global user.name "超音速"

react-photo-view 的介紹、安裝、使用。

目錄 基本介紹 安裝 使用 基本介紹 react-photo-view 是一個基于 React 的圖片查看器組件,用于在網頁上展示和瀏覽圖片。該組件提供了用戶友好的界面和交互,可以輕松地在應用程序中集成并使用。 支持觸摸手勢,拖動/平移/物理效果滑動…

修改移遠提供的GobiNet、quectel-CM源碼,使其支持有方N720 4G模塊

最近在研究imx6ull linux下4G模塊驅動的移植,參考的移遠ec20的移植方法,添加了GobiNet驅動,編譯了quectel-CM工具,并且可以正常撥號,分配到ip,如下: ping外網也沒有壓力,如下…

軟件工程 考試重點

結構化分析 考慮數據和處理的需求分析方法,稱為結構分析方法(SA) 結構化分析基于 分解、抽象 的基本思想 分解:對于復雜的系統,為將復雜度降低到可以掌握的程度,可以把大問題分解為若干個小問題&#xf…

【go-zero】go-zero使用ent框架 如何使用源生sql完成查詢

背景 本篇教程我們采用的是go-zero的快速腳手架工具 simple-admin 框架的開發 github地址:https://github.com/suyuan32/simple-admin-core 因為框架推薦使用Ent 這篇教程我們則對Ent的基本使用的幾種形式進行一個總結 一、開啟ent的源生sql 1、simple-admin生成rpc 【go-…

QT 中 線程池 (備查)

QRunnable類 API 1)在Qt中使用線程池需要先創建任務,添加到線程池中的每一個任務都需要是一個 QRunnable 類型,因此在程序中需要創建子類繼承 QRunnable 這個類。 2)然后重寫 run() 方法,在這個函數中編寫要在線程池中…

RabbitMQ使用指南

介紹主要特點常用插件使用RabbitMQ的插件常用插件列表 應用場景Kafka與RabbitMq的區別主要優缺點安裝步驟插件安裝步驟 使用RabbitMqJava代碼示例拓展 介紹 RabbitMQ是由Erlang語言開發的,基于AMQP(高級消息隊列協議)協議實現的開源消息代理…

元宇宙紅色展廳VR虛擬展館提高受訓者的參與感

生活在和平年代的新一代青少年,可能對革命先烈英勇事跡難以有很深的體會,無法切實感受到中國共產黨無畏犧牲、誓死保家衛國的紅色精神,因此借助VR虛擬現實制作技術,讓參觀者們走近革命先烈中,感受老一輩無產階級革命家…

搜索引擎和網絡瀏覽器之間的區別

術語“搜索引擎”和“網絡瀏覽器”與互聯網有關。搜索引擎基本上是用于通過 Internet 搜索信息的工具,而 Web 瀏覽器是用于加載網頁等 HTML 文件的應用軟件。 閱讀本文以了解有關搜索引擎和網絡瀏覽器以及它們之間的區別的更多信息。 什么是搜索引擎? …

TrustZone之SMC異常

作為支持兩個安全狀態的一部分,該架構包括了Secure Monitor Call(SMC)指令。執行SMC會引發Secure Monitor Call異常,該異常目標是EL3。 通常,SMC用于請求服務,可以是來自駐留在EL3中的固件,也可…

微信小程序適配方案:rpx(responsive pixel響應式像素單位)

小程序適配單位:rpx 規定任何屏幕下寬度為750rpx 小程序會根據屏幕的寬度自動計算rpx值的大小 Iphone6下:1rpx 1物理像素 0.5css 小程序編譯后,rpx會做一次px換算,換算是以375個物理像素為基準,也就是在一個寬度…

迭代器失效及解決辦法

當使用迭代器遍歷容器并刪除元素時&#xff0c;迭代器可能會失效。 對于vector來說&#xff0c;如果使用普通迭代器&#xff08;例如std::vector<int>::iterator&#xff09;進行遍歷和刪除操作&#xff0c;當你刪除一個元素后&#xff0c;后面的元素會向前移動填補空缺…