GD32F407單片機開發入門(十九)DMA詳解及ADC-DMA方式采集含源碼

文章目錄

    • 一.概要
    • 二.GD32F407VET6單片機DMA外設特點
    • 三.GD32單片機DMA內部結構圖
    • 四.DMA各通道請求
    • 五.GD32F407VET6單片機ADC-DMA采集例程
    • 六.工程源代碼下載
    • 七.小結

一.概要

基本概念:
DMA是Direct Memory Access的首字母縮寫,是一種完全由硬件執行數據交換的工作方式。DMA控制器從CPU接管對總線的控制,不經過CPU直接在內存和外設之間進行批量數據交換。DMA控制器向內存發出地址和控制信號,修改地址,對傳送的字的個數計數,并且以中斷方式向CPU報告傳送操作的結束。 DMA方式一般用于高速傳送成組數據。

DMA傳輸的三大要素:
傳輸源:DMA控制器從傳輸源讀出數據;
傳輸目標:DMA控制器將數據傳輸的目標;
觸發信號:用于觸發一次數據傳輸的動作,執行一個單位的傳輸源至傳輸目標的數據傳輸;可以用來控制傳輸的時機。

DMA的主要優點:
由于CPU根本不參加傳送操作,因此就省去了CPU取指令、取數、送數等操作。在數據傳送過程中,沒有保存現場、恢復現場之類的工作。內存地址修改、傳送字個數的計數等等,也不是由軟件實現,而是用硬件線路直接實現的。所以DMA方式能滿足高速I/O設備的要求,也有利于CPU效率的發揮。

二.GD32F407VET6單片機DMA外設特點

兩個AHB主機接口傳輸數據,一個AHB從機接口配置DMA。
16個通道(每個DMA控制器有8個通道),每個通道連接8個特定的外設請求。
存儲器和外設支持單一傳輸,4拍、8拍和16拍增量突發傳輸。
當外設和存儲器傳輸數據時,支持存儲器切換。
支持軟件優先級(低、中、高、超高)和硬件優先級(通道號越低,優先級越高)。
存儲器和外設的數據傳輸寬度可配置:字節,半字,字。
存儲器和外設的數據傳輸支持固定尋址和增量式尋址。
支持循環傳輸模式。
支持三種傳輸方式:
– 存儲器到外設;
– 外設到存儲器;
– 存儲器到存儲器(僅DMA1支持);
DMA和外設均可配置為傳輸控制器: – DMA作為傳輸控制器:可配置數據傳輸長度,最大為65535。 – 外設作為傳輸控制器:數據傳輸的完成取決于外設的最后一個傳輸請求。
支持單數據傳輸和多數據傳輸模式:
– 多數據傳輸模式:在存儲器數據寬度和外設數據寬度不同的時候,自動打包/解包數
據;
– 單數據傳輸模式:當且僅當FIFO空的時候從源地址讀取數據,存進FIFO,然后把
FIFO 的數據寫到目標地址。
每個通道有5種類型的事件標志和獨立的中斷,支持中斷的使能和清除。

三.GD32單片機DMA內部結構圖

在這里插入圖片描述

DMA控制器由4部分組成:

AHB 從接口配置DMA
AHB主接口進行數據傳輸
仲裁器進行DMA請求的優先級管理
數據處理和計數

寄存器DMA_CHxCTL的PWIDTH和MWIDTH位域決定了外設和存儲器的數據傳輸寬度。DMA控制器支持8位,16位和32位的數據寬度。

四.DMA各通道請求

DMA從外設讀數據存儲到存儲器,大致流程如下圖。
在這里插入圖片描述
在這里插入圖片描述

如下圖所示,每個DMA控制器有8個通道,每個通道有多個外設請求。以ADC0為例,可以映射到DMA的Channel0。
在這里插入圖片描述

DMA的傳輸模式:

循環模式:通過寄存器DMA_CHxCTL的CMEN位置1使能,用于處理一個環形的緩沖區,每輪傳輸結束時數據傳輸的配置會自動地更新為初始狀態,DMA傳輸會連續不斷地進行,一般采用循環模式。

普通模式:在DMA傳輸結束時,DMA通道被自動關閉,進一步的DMA請求將不被滿足。

五.GD32F407VET6單片機ADC-DMA采集例程

STLINK接GD32F407VET6開發板,STLINK接電腦USB口。

在這里插入圖片描述

GD32F407VET6開發板的PA4,PA45引腳上的進行 ADC 電壓采集,杜邦線連接 PA4,PA5 引腳與 VDD(3.3V)或者GND(0V),就能讀到單片機供電的電壓值。

主要代碼:

#include "gd32f4xx.h"
#include "gd32f4xx_libopt.h"
#include "systick.h"uint16_t adc_value[2];//ADC采樣值//ADC配置,DMA配置
void ADC_config(void)
{dma_single_data_parameter_struct  dma_single_data_parameter;rcu_periph_clock_enable(RCU_GPIOA);gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_4);//PA4配置成輸入gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_5);//PA5配置成輸入//ADC相關時鐘配置rcu_periph_clock_enable(RCU_GPIOA);rcu_periph_clock_enable(RCU_DMA1);rcu_periph_clock_enable(RCU_ADC0);adc_clock_config(ADC_ADCCK_PCLK2_DIV6);/* DMA相關配置 DMA1 CH0*/dma_deinit(DMA1, DMA_CH0);dma_single_data_parameter.periph_addr = (uint32_t)(&ADC_RDATA(ADC0));dma_single_data_parameter.periph_inc = DMA_PERIPH_INCREASE_DISABLE;dma_single_data_parameter.memory0_addr = (uint32_t)(&adc_value);dma_single_data_parameter.memory_inc = DMA_MEMORY_INCREASE_ENABLE;                         // 存儲器地址是否為增量模式dma_single_data_parameter.periph_memory_width = DMA_PERIPH_WIDTH_16BIT;dma_single_data_parameter.circular_mode = DMA_CIRCULAR_MODE_ENABLE;                        // 循環模式dma_single_data_parameter.direction = DMA_PERIPH_TO_MEMORY;                                // 外設到存儲器dma_single_data_parameter.number = 2;                                                      // DMA緩存大小dma_single_data_parameter.priority = DMA_PRIORITY_HIGH;dma_single_data_mode_init(DMA1,DMA_CH0,&dma_single_data_parameter);dma_channel_enable(DMA1, DMA_CH0);dma_circulation_enable(DMA1, DMA_CH0);        //ADC相關配置adc_deinit();      // 復位ADCadc_sync_mode_config(ADC_SYNC_MODE_INDEPENDENT);                         //獨立模式adc_special_function_config(ADC0, ADC_SCAN_MODE, ENABLE);               // 掃描模式adc_special_function_config(ADC0, ADC_CONTINUOUS_MODE, ENABLE);         // 連續模式adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);                  // 右對齊adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 2);              //讀取2通道/* ADC regular channel config */adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_4, ADC_SAMPLETIME_144);//ADC0的通道4adc_regular_channel_config(ADC0, 1, ADC_CHANNEL_5, ADC_SAMPLETIME_144);//ADC0的通道5adc_external_trigger_config(ADC0,ADC_REGULAR_CHANNEL,EXTERNAL_TRIGGER_DISABLE);adc_dma_request_after_last_enable(ADC0);adc_dma_mode_enable(ADC0);adc_enable(ADC0);adc_calibration_enable(ADC0);adc_software_trigger_enable(ADC0, ADC_REGULAR_CHANNEL);
}uint16_t Vol_Value1,Vol_Value2;//采集到的電壓值
int main(void)
{systick_config();//配置系統主頻168M,外部8M晶振,配置在#define __SYSTEM_CLOCK_168M_PLL_8M_HXTAL        (uint32_t)(168000000)ADC_config();	//配置ADCwhile(1){Vol_Value1=adc_value[0]*3300/4095;//轉換成電壓值Vol_Value2=adc_value[1]*3300/4095;//轉換成電壓值}
}

實驗結果:
PA4接GND,PA5接3.3V,用Keil運行程序,全速運行,查看Keil調試Watch界面,如下圖,PA4,PA5引腳的采樣值adc_value[0]
為0,adc_value[1]為0xfff,對應的電壓值為0mV與3300mV,所以ADC DMA采樣成功。
在這里插入圖片描述

六.工程源代碼下載

源碼下載鏈接如下:
CSDN

七.小結

使用DMA進行數據收發能夠提高數據傳輸的效率和可靠性。其次,使用DMA進行串口數據收發可以減輕CPU的負擔。

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

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

相關文章

vue報錯:Error: Cannot find module ‘is-stream‘

此錯誤提示 Cannot find module ‘is-stream’ 表明 Node.js 無法找到 is-stream 模塊。一般而言,這是由于項目中未安裝該模塊所導致的。 解決方案: //npm npm install is-stream //yarn yarn add is-stream安裝后檢查 安裝完成之后,你可以再次運行項目…

全局事件總線EventBus的用法

全局事件總線 EventBus 在前端開發中是一種用于實現組件間通信的機制,適用于兄弟組件或跨層級組件間的數據傳遞。 1. 創建全局 EventBus 實例 在前端項目中,先創建一個全局的 EventBus 實例。在 Vue 中,可以通過創建一個新的 Vue 實例來實現…

SpringBoot 設置HTTP代理訪問

SpringBoot 設置HTTP代理訪問 遇到這樣的一個場景,代碼部署到私有服務器上去之后,這臺私有服務器a無法直接訪問公網,需要通過代理轉發到另外一臺專門訪問公網的服務器b, 讓服務器b去請求對應的公網ip,于是就需要設置Http代理。 …

在C# WebApi 中使用 Nacos01:基礎安裝教程和啟動運行

一、JDK的安裝 Nacos需要依賴JAVA環境運行,所以需要先安裝JDK 1.檢查是否安裝 可用命令行檢查是否安裝JDK 直接win+r,cmd: java -version 出現這個說明安裝成功 2.下載JDK 訪問官網點擊下載:

cURL 入門:10 分鐘學會用命令行發 HTTP 請求

curl初識 curl 通過 URL 傳輸數據的命令行工具和庫是一個非常強大的命令行工具,用于在網絡上傳輸數據。它支持眾多的協議,像 dict file ftp ftps gopher gophers http https imap imaps ipfs ipns ldap ldaps mqtt pop3 pop3s rtsp smb smbs smtp smtps…

Redis應用場景實戰:穿透/雪崩/擊穿解決方案與分布式鎖深度剖析

一、緩存異常場景全解與工業級解決方案 1.1 緩存穿透:穿透防御的三重門 典型場景 惡意爬蟲持續掃描不存在的用戶ID 參數注入攻擊(如SQL注入式查詢) 業務設計缺陷導致無效查詢泛濫 解決方案進化論 第一層防護:布隆過濾器&am…

C# 高效操作excel文件

C#高效操作Excel文件指南 一、主流Excel處理方案對比 方案類型特點適用場景??EPPlus??第三方庫功能全面,性能好,支持.xlsx復雜Excel操作,大數據量??NPOI??第三方庫支持.xls和.xlsx,功能全面兼容舊版Excel文件??Closed…

Rust 學習筆記:結構體(struct)

Rust 學習筆記:結構體(struct) Rust 學習筆記:結構體(struct)結構體的定義和實例化使用字段初始化簡寫用 Struct Update 語法從其他實例創建實例使用沒有命名字段的元組結構來創建不同的類型沒有任何字段的…

Dify Agent節點的信息收集策略示例

Dify Agent節點的信息收集策略示例 0. 安裝"對話 Agent"插件1. 創建一個 Chatflow2. 創建一個 Agent 節點3. 創建一個條件分支節點4. 在IF分支創建一個LLM節點5. 創建一個直接回復節點6. 在ELSE分支創建一個直接回復節點7. 分布并預覽 0. 安裝"對話 Agent"…

Qt/C++開發監控GB28181系統/獲取設備信息/設備配置參數/通道信息/設備狀態

一、前言 設備注冊成功后,接下來要做的就是獲取設備的信息,尤其是通道信息,根據國標協議,永遠只有兩個層級,一個是設備,然后就是設備下面多個通道,設備編碼在整個系統中唯一,通道編…

金融風控的“天眼”:遙感技術的創新應用

在金融市場的復雜博弈中,風險管控一直是金融機構的核心競爭力。然而,傳統的風控手段在應對現代金融市場的快速變化時,往往顯得捉襟見肘。 如今,遙感技術的創新應用為金融風控帶來了全新的視角和手段。星圖云開放平臺的遙感金融立體…

HFI筆記

高頻分量: 載波頻率的一半 選擇alfabeta軸進行計算的原因 最終結果: 觀測器方程 采樣加減分離法-(高低頻分離) 高頻信號的評論高頻載波 轉子極性辨識

halcon關閉圖形窗口

1、dev_close_window () 調用一次這個函數關閉一個圖形窗口,并且先關閉最后打開的那個圖形窗口,如果一共打開了N個圖形窗口,那么就需要調用dev_close_window N次。

每日算法-250430

每日算法 - 2025年4月30日 記錄下今天解決的兩道題目。 870. 優勢洗牌 (Advantage Shuffle) 題目描述 解題思路與方法 核心思想:貪心策略 (田忌賽馬) 這道題的目標是對于 nums1 中的每個元素,找到 nums2 中一個比它小的元素進行配對(如果…

【MySQL】增刪改查(CRUD)

目錄 一. CRUD是什么 二. Create(新增數據) 2.1 單行數據全列插入 2.2 單行數據指定列插入 2.3 多行數據指定列插入 三. Retrieve (檢索/查詢) 3.1 全列查詢 3.2 指定列查詢 3.3 查詢字段為表達式 3.4 為查詢結果指定別名 3…

電商平臺 API 開發實戰:京東商品詳情數據實時獲取接口對接教程

在電商行業競爭日益激烈的當下,實時獲取商品詳情數據對于市場分析、競品監控、商品推薦等業務場景至關重要。京東作為國內領先的電商平臺,提供了強大的 API 接口,允許開發者獲取豐富的商品信息。本文將詳細介紹京東商品詳情數據實時獲取接口的…

YOLO視覺模型可視化訓練與推理測試工具

推薦一款YOLO可視化訓練測試工具: 對于yolo的訓練,新手小白往往無從下手,本章推薦的這款工具可以非常輕易的幫您從模型訓練到測試到部署。 下載地址http://www.voouer.com/yolo 可以點擊此處跳轉。 下載成功后打開這款工具,將會出現圖形化界面,類似于下圖所示: 當前頁是可視…

微調 LLaMA 2:定制大型語言模型的分步指南

微調 LLaMA 2:定制大型語言模型的分步指南 深入了解如何運用新技術在 Google Colab 平臺上對 Llama-2 進行微調操作,從而有效克服內存與計算方面的限制,讓開源大型語言模型變得更加易于獲取和使用。自從 Meta 發布了 LLaMA 的首個版本后&…

探秘明遠智睿SSD2351開發板在HMI領域的獨特魅力

人機界面(HMI)是人與機器進行交互的重要橋梁,其性能和用戶體驗直接影響到整個系統的使用效果。明遠智睿的SSD2351開發板憑借其出色的性能和豐富的功能,在HMI領域展現出了獨特的魅力。 SSD2351開發板的四核1.4GHz處理器具備強大的圖…

Keysight萬用表使用指南及基于Python采集數據生成Excel文件

文章目錄 說明使用的庫openpyxlpyvisa 代碼說明效果展示參考代碼 說明 本文介紹了 Keysight 34465A 的基本使用和 SCPI 指令設置,演示了使用 Python 的 PyVISA 庫控制兩臺 34465A 同時采集數據的完整流程,包括設置采樣參數、觸發測量、讀取數據、使用 O…