STM32 如何使用DMA和獲取ADC

目錄

背景

?搖桿的原理

程序

端口配置

ADC 配置

DMA配置


背景

DMA是一種計算機技術,允許某些硬件子系統直接訪問系統內存,而不需要中央處理器(CPU)的介入,從而減輕CPU的負擔。我們可以通過DMA來從外設(ADC、UART等)讀取數據之后,搬運到指定的內存。

ADC是根據用戶動作或者環境變化會造成傳感器等設備的電壓值發生變化,再通過STM32的ADC塊實現采樣、保持、量化、編碼將模擬量轉換成數據量。

本篇文章會介紹目前無人機常用的搖桿操作(左右、上下、按下等),變為電壓值變化,以及STM32 如何實現DMA定期讀取遙感ADC值。

?搖桿的原理

JS_X:作為X軸方向的模擬信號輸入口

JS_Y:作為Y軸方向的模擬信號輸入口

JS_D:揮動開關的狀態的檢測端口

通過原理圖可以通過X軸方向滑動可以改變接觸點在電阻的位置,從而影響讀取到的電壓值。Y軸方向亦是同理。因此只需將JS_X和JS_Y的端口設置位模擬量輸入端,然后由STM32單片機的ADC塊處理。

而按下的操作顯然是普通的Port Key, 因此只用將JS_D設置位上拉輸入,然后通過讀取該端口的狀態,來判斷是否搖桿被按下。

?STM32的DMA通道?:STM32系列最多有12個獨立可配置的通道,包括DMA1(7個通道)和DMA2(5個通道)。每個通道可以分別設置源地址與目的地址,實現獨立工作?

程序

端口配置


#define ADC1_DR_Address    ((uint32_t)0x4001244C) //ADC1這個外設的地址(查參考手冊得出)#define ADCPORT		GPIOA	//定義ADC接口
#define ADC_CH4		GPIO_Pin_4	//定義ADC接口 電壓電位器
#define ADC_CH5		GPIO_Pin_5	//定義ADC接口 光敏電阻
#define ADC_CH6		GPIO_Pin_6	//定義ADC接口 搖桿X軸
#define ADC_CH7		GPIO_Pin_7	//定義ADC接口 搖桿Y軸#define JoyStickPORT	GPIOB	//定義IO接口組
#define JoyStick_KEY	GPIO_Pin_2	//定義IO接口void ADC_GPIO_Init(void){ //GPIO初始化設置GPIO_InitTypeDef  GPIO_InitStructure; 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC,ENABLE);       RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//使能DMA時鐘(用于ADC的數據傳送)RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);//使能ADC1時鐘GPIO_InitStructure.GPIO_Pin = ADC_CH6 | ADC_CH7; //!!!選擇端口                        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //選擇IO接口工作方式       GPIO_Init(ADCPORT, &GPIO_InitStructure);		
}void JoyStick_Init(void){ //搖桿的揮動開關的接口初始化GPIO_InitTypeDef  GPIO_InitStructure; //定義GPIO的初始化枚舉結構	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC,ENABLE);       GPIO_InitStructure.GPIO_Pin = JoyStick_KEY; //選擇端口號(0~15或all)                        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //選擇IO接口工作方式 //上拉電阻       GPIO_Init(JoyStickPORT,&GPIO_InitStructure);			
}

1)GPIOA組、GPIOB組、DMA1的外設時鐘使能起來(GPIOC組功能用于其他,我們可以忽略它)

2) X軸和Y軸的輸入端要設置為模擬量輸入端口

3)Port Key 要設置位上拉電阻輸入口,因為在沒有被按下時,要能讀入高電平!

3)初始化端口

ADC 配置

void ADC_Configuration(void){ //初始化設置ADC_InitTypeDef ADC_InitStructure;//定義ADC初始化結構體變量ADC_GPIO_Init();//GPIO初始化設置ADC_DMA_Init();//DMA初始化設置ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//ADC1和ADC2工作在獨立模式ADC_InitStructure.ADC_ScanConvMode = ENABLE; //使能掃描ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//ADC轉換工作在連續模式ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//有軟件控制轉換ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//轉換數據右對齊ADC_InitStructure.ADC_NbrOfChannel = 2;//!!!順序進行規則轉換的ADC輸入口的數目(根據ADC采集通道數量修改)ADC_Init(ADC1, &ADC_InitStructure); //根據ADC_InitStruct中指定的參數初始化外設ADCx的寄存器//設置指定ADC的規則組通道,設置它們的轉化順序和采樣時間//ADC1,ADC通道x,規則采樣順序值為y,采樣時間為28周期		 ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 1, ADC_SampleTime_28Cycles5);//!!! ADC1選擇信道x,采樣順序y,采樣時間n個周期ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 2, ADC_SampleTime_28Cycles5);//!!! ADC1選擇信道x,采樣順序y,采樣時間n個周期ADC_DMACmd(ADC1, ENABLE);// 開啟ADC的DMA支持(要實現DMA功能,還需獨立配置DMA通道等參數)ADC_Cmd(ADC1, ENABLE);//使能ADC1ADC_ResetCalibration(ADC1); //重置ADC1校準寄存器while(ADC_GetResetCalibrationStatus(ADC1));//等待ADC1校準重置完成ADC_StartCalibration(ADC1);//開始ADC1校準while(ADC_GetCalibrationStatus(ADC1));//等待ADC1校準完成ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能ADC1軟件開始轉換
}
12 位分辨率
● 轉換結束、注入轉換結束和發生模擬看門狗事件時產生中斷
● 單次和連續轉換模式
● 從通道 0 到通道 n 的自動掃描模式
● 自校準
● 帶內嵌數據一致性的數據對齊
● 采樣間隔可以按通道分別編程
● 規則轉換和注入轉換均有外部觸發選項
● 間斷模式
● 雙重模式 ( 2 個或以上 ADC 的器件 )
ADC 轉換時間:
STM32F103xx 增強型產品:時鐘為 56MHz 時為 1 μ s( 時鐘為 72MHz 1.17 μ s)
STM32F101xx 基本型產品:時鐘為 28MHz 時為 1 μ s( 時鐘為 36MHz 1.55 μ s)
STM32F102xxUSB 型產品:時鐘為 48MHz 時為 1.2 μ s
STM32F105xx STM32F107xx 產品:時鐘為 56MHz 時為 1 μ s( 時鐘為 72MHz 1.17 μ s)
ADC 供電要求: 2.4V 3.6V
ADC 輸入范圍: V REF- V IN V REF+
● 規則通道轉換期間有 DMA 請求產生。
STM32F103C8T6由兩個ADC。
ADC框圖:
ADC1和ADC2獨立工作,故配置位獨立模式
因為要ADC1掃描有配置的兩個通道,因此要使能掃描
因為要連續多次采樣,因此要設置位連續模式,而非單次模式
DMA的觸發可以通過軟件觸發(內部觸發)和硬件觸發(外部觸發,硬件觸發見截圖)。
我們采用內部軟件觸發

常見的ADC數據對齊方式

右對齊(默認情況):這是大多數STM32 ADC寄存器的默認行為。例如,如果你使用12位分辨率的ADC,那么只有最低的12位將被用來存儲轉換結果,而最高的4位(在16位寄存器中)將會是0。

左對齊:在某些情況下,你可能需要將數據左對齊,這意味著將最高有效位(MSB)放在寄存器的最高位。這通常通過特定的硬件配置或軟件操作來實現,比如在某些STM32系列中,可以通過配置ADC寄存器來實現數據的左對齊。

輸入通道數配置,X軸通道和Y軸通道總共兩個。

注冊規則組

注冊包含通道信息、采樣順序、采樣時間。ADC通道通過查閱端口定義可知。

STM32F103C8T6


C8:48pin 64K Flash?屬于中容量 SRAM 20K.

查看引腳定義可以知道PA6的ADC通道是6,PA7的通道是7.

使能ADC1的DMA請求

使能ADC1

ADC1自校準

軟件觸發開始ADC1轉換

DMA配置


vu16 ADC_DMA_IN[2]; //ADC數值存放的變量void ADC_DMA_Init(void){ //DMA初始化設置DMA_InitTypeDef DMA_InitStructure;//定義DMA初始化結構體DMA_DeInit(DMA1_Channel1);//復位DMA通道1DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; //定義 DMA通道外設基地址=ADC1_DR_AddressDMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_DMA_IN; //!!!定義DMA通道ADC數據存儲器(其他函數可直接讀此變量即是ADC值)DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//指定外設為源地址DMA_InitStructure.DMA_BufferSize = 2;//!!!定義DMA緩沖區大小(根據ADC采集通道數量修改)DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//當前外設寄存器地址不變DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//!!! 當前存儲器地址:Disable不變,Enable遞增(用于多通道采集)DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//定義外設數據寬度16位DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //定義存儲器數據寬度16位DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//DMA通道操作模式位環形緩沖模式DMA_InitStructure.DMA_Priority = DMA_Priority_High;//DMA通道優先級高DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//禁止DMA通道存儲器到存儲器傳輸DMA_Init(DMA1_Channel1, &DMA_InitStructure);//初始化DMA通道1DMA_Cmd(DMA1_Channel1, ENABLE); //使能DMA通道1
}

由于是從ADC1外設(ADC1的數據寄存器DR)到內存,因此方向配置如下

DMA設置為循環模式,可以連續多次的從ADC1外設搬運數據到指定內存。

因為ADC1外設(DR)是16位(ADC分辨率是12),所以

DMA1的每個channel用于設置數據源外設和目的地內存地址。因為我們的外設是ADC1。所以我們選擇Channel1.

?

ADC1的外設的地址

DMA優先級設置為HIGH

優先級相同情況下,由內部硬件優先級決定!

由于不是內存搬運到內存,故DMA_M2M要設置為Disable

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

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

相關文章

【ISO 14229-1:2023 UDS診斷全量測試用例清單系列:第十六節】

ISO 14229-1:2023 UDS診斷服務測試用例全解析(LinkControl_0x87服務) 作者:車端域控測試工程師 更新日期:2025年02月14日 關鍵詞:UDS協議、0x87服務、鏈路控制、ISO 14229-1:2023、ECU測試 一、服務功能概述 0x87服務…

DeepSeek與醫院電子病歷的深度融合路徑:本地化和上云差異化分析

一、引言 1.1 研究背景與意義 在醫療信息化快速發展的當下,電子病歷系統已成為醫院信息管理的核心構成。電子病歷(EMR)系統,是指醫務人員在醫療活動過程中,使用醫療機構信息系統生成的文字、符號、圖標、圖形、數據、影像等數字化信息,并能實現存儲、管理、傳輸和重現的…

Django中實現簡單易用的分頁工具

如何在Django中實現簡單易用的分頁工具?📚 嗨,小伙伴們!今天我們來看看如何在 Django 中實現一個超簡單的分頁工具。無論你是在處理博客文章、產品列表,還是用戶評論,當數據量一大時,分頁顯得尤…

【kafka系列】生產者

目錄 發送流程 1. 流程邏輯分析 階段一:主線程處理 階段二:Sender 線程異步發送 核心設計思想 2. 流程 關鍵點總結 重要參數 一、核心必填參數 二、可靠性相關參數 三、性能優化參數 四、高級配置 五、安全性配置(可選&#xff0…

Docker 入門與實戰:從安裝到容器管理的完整指南

🚀 Docker 入門與實戰:從安裝到容器管理的完整指南 🌟 📖 簡介 在現代軟件開發中,容器化技術已經成為不可或缺的一部分。而 Docker 作為容器化領域的領頭羊,以其輕量級、高效和跨平臺的特性,深…

MySQL 插入替換語句(replace into statement)

我們日常使用 insert into 語句向表中插入數據時,一定遇到過主鍵或唯一索引沖突的情況,MySQL的反應是報錯并停止執行后續的語句,而replace into語句可以實現強制插入。 文章目錄 一、replace into 語句簡介1.1 基本用法1.2 使用set語句 二、注…

基于SpringBoot+Vue的智慧校園管理系統設計和實現(源碼+文檔+部署講解)

🎬 秋野醬:《個人主頁》 🔥 個人專欄:《Java專欄》《Python專欄》 ??心若有所向往,何懼道阻且長 文章目錄 .🚀 技術架構技術棧全景 🎯 功能模塊功能矩陣表📊 數據庫設計核心ER關系圖 💻 核心…

【Three.js】JS 3D library(一個月進化史)

#春節過完了,該繼續投入學習了~ 作為一個平面開發者,想要增進更多的技能,掌握web3D開發# Day 1 了解熟悉Three.js,著重基礎理論 學習資源: 前端可視化從0-1 Day 2 寫一個簡易demo 搭建環境-->安裝包-->創建…

moveable 一個可實現前端海報編輯器的 js 庫

目錄 緣由-胡扯本文實驗環境通用流程1.基礎移動1.1 基礎代碼1.1.1 data-* 解釋 1.2 操作元素創建1.3 css 修飾1.4 cdn 引入1.5 js 實現元素可移動1.6 圖片拖拽2.縮放3.旋轉4.裁剪 懶得改文案了,海報編輯器換方案了,如果后面用別的再更。 緣由-胡扯 導火…

Apollo 9.0 速度動態規劃決策算法 – path time heuristic optimizer

文章目錄 1. 動態規劃2. 采樣3. 代價函數3.1 障礙物代價3.2 距離終點代價3.3 速度代價3.4 加速度代價3.5 jerk代價 4. 回溯 這一章將來講解速度決策算法,也就是SPEED_HEURISTIC_OPTIMIZER task里面的內容。Apollo 9.0使用動態規劃算法進行速度決策,從類名…

【Day41 LeetCode】單調棧問題

一、單調棧問題 單調棧問題通常是在一維數組中尋找任一個元素的右邊或者左邊第一個比自己大或者小的元素的位置。 1、每日溫度 739 這題的目的是對于當天,找到未來溫度升高的那一天,也就是當前元素的右邊第一個比自己大的元素。所以我們需要維護一個單…

Cherno C++ P55 宏

這篇文章我們講一下C當中的宏。其實接觸過大型項目的朋友可能都被詭異的宏折磨過。 宏是在預處理當中,通過文本替換的方式來實現一些操作,這樣可以不用反復的輸入代碼,幫助我們實現自動化。至于預處理的過程,其實就是文本編輯&am…

web第三次作業

彈窗案例 1.首頁代碼 <!DOCTYPE html><html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>綜合案例</title><st…

深入解析LVS命令參數及DR模式下的ARP抑制原理

深入解析LVS命令參數及DR模式下的ARP抑制原理 一、LVS簡介 Linux Virtual Server (LVS) 是基于Linux內核的高性能負載均衡解決方案&#xff0c;支持NAT、DR&#xff08;Direct Routing&#xff09;和TUN&#xff08;IP Tunneling&#xff09;三種模式。其中&#xff0c;ipvsad…

阿里云一鍵部署DeepSeek-V3、DeepSeek-R1模型

目錄 支持的模型列表 模型部署 模型調用 WebUI使用 在線調試 API調用 關于成本 FAQ 點擊部署后服務長時間等待 服務部署成功后&#xff0c;調用API返回404 請求太長導致EAS網關超時 部署完成后&#xff0c;如何在EAS的在線調試頁面調試 模型部署之后沒有“聯網搜索…

Win10環境借助DockerDesktop部署大數據時序數據庫Apache Druid

Win10環境借助DockerDesktop部署最新版大數據時序數據庫Apache Druid32.0.0 前言 大數據分析中&#xff0c;有一種常見的場景&#xff0c;那就是時序數據&#xff0c;簡言之&#xff0c;數據一旦產生絕對不會修改&#xff0c;隨著時間流逝&#xff0c;每個時間點都會有個新的…

【第13章:自監督學習與少樣本學習—13.1 自監督學習最新進展與實現方法】

凌晨三點的實驗室,博士生小王盯著屏幕里正在"自娛自樂"的神經網絡——這個沒有吃過一張標注圖片的模型,正在通過旋轉、拼圖、填色等游戲任務,悄悄掌握著理解世界的秘訣。這種魔法般的修煉方式,正是當今AI領域最炙手可熱的技術:自監督學習。 一、打破數據枷鎖:自…

數據庫報錯1045-Access denied for user ‘root‘@‘localhost‘ (using password: YES)解決方式

MySQL 報錯 1045 表示用戶root從localhost連接時被拒絕訪問&#xff0c;通常是因為密碼錯誤、權限問題或配置問題。以下是解決該問題的常見方法&#xff1a; 方法一&#xff1a;檢查用戶名和密碼 ? 確認用戶名和密碼是否正確&#xff1a; 確保輸入的用戶名和密碼完全正確&am…

八大排序——簡單選擇排序

目錄 1.1基本操作&#xff1a; 1.2動態圖&#xff1a; 1.3代碼&#xff1a; 代碼解釋 1. main 方法 2. selectSort 方法 示例運行過程 初始數組 每輪排序后的數組 最終排序結果 代碼總結 1.1基本操作&#xff1a; 選擇排序&#xff08;select sorting&#xff09;也…

與傳統光伏相比 城電科技的光伏太陽花有什么優勢?

相比于傳統光伏&#xff0c;城電科技的光伏太陽花有以下優勢&#xff1a; 一、發電效率方面 智能追蹤技術&#xff1a;光伏太陽花通過內置的智能追蹤系統&#xff0c;采用全球定位跟蹤算法&#xff0c;能夠實時調整花瓣&#xff08;即光伏板&#xff09;的角度&#xff0c;確…