当前位置: 首页 > article >正文

STM32 ADC+高速DMA 采集原理与实战

一、核心概念1. 什么是 ADCADC 是模数转换器作用是把模拟电压转换成数字值。STM32F103 的 ADC 是 12 位的输出范围0~4095对应电压范围0~3.3V换算公式电压 ADC值 × 3.3V / 4096。2. 什么是 DMADMA 是直接存储器访问控制器可以在不占用 CPU 的情况下直接把外设比如 ADC、SPI、串口的数据搬运到内存数组里。相当于一个 “硬件快递员”外设是 “发货点”内存数组是 “收货点”搬运过程完全自动CPU 可以去干别的事。二、为什么要用 ADCDMA先说说痛点普通 ADC 采集CPU 要主动读取寄存器会被频繁打断采集效率低还会拖慢主程序。用了 DMA 之后数据由硬件自动搬运CPU 全程不参与采集又快又稳还不影响其他任务。简单说就是ADC 负责 “读”DMA 负责 “搬”CPU 只负责 “用”三者互不打扰效率拉满三、ADCDMA 是怎么配合工作的用一个流程讲清楚配置阶段CPU 只干一次1.给 ADC 和 DMA 上电。2.设置 ADC 为连续扫描模式让它一直采数据。3.设置 DMA从 ADC 寄存器读数据写到内存数组里一次搬 N 个数据循环搬运。工作阶段全程硬件自动完成1.ADC 完成一次采样把结果放到 ADC-DR 寄存器。2.DMA 立刻把 DR 里的数据搬到你定义的数组里。3.搬完一次ADC 自动开始下一次采样DMA 自动搬运下一个数据。4.数据会自动填满你的数组循环模式下会自动覆盖旧数据。5.CPU 不需要做任何事想读数据的时候直接访问数组就行。四、关键细节踩坑点1. DMA 数据位宽必须和外设、数组匹配ADC 是 12 位输出数据会扩展成 16 位存放在DR寄存器里所以DMA 外设数据位宽必须设置为HalfWord16 位。内存数据位宽也必须设置为HalfWord。你的数组必须定义为uint16_t类型。不匹配的后果数据截断、数值异常、采集完全错误。2. DMA 搬运长度和数组大小要对应代码里的DMA_BufferSize就是 DMA 一次搬运的次数必须和你数组的大小一致。比如你定义了uint16_t adc_buf[64];就必须设置DMA_BufferSize 64。3. 循环模式 vs 正常模式循环模式DMA_Mode_Circular搬完一次自动从头开始搬运数组里永远是最新的数据适合持续采集的场景正常模式DMA_Mode_Normal搬完一次就停止适合单次采集4. ADC 连续转换模式必须开启要让 ADC 一直采样必须设置ADC_ContinuousConvMode ENABLE否则采一次就停了DMA 也会停止搬运。五、完整采集代码// ADC1 DMA1 初始化 void Adc_Init(void) { // 开启 ADC1 和 GPIOA 时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE); // 开启 DMA1 时钟AHB 总线 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); // 配置 PA0 为模拟输入模式 GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Pin GPIO_Pin_0; GPIO_InitStruct.GPIO_Mode GPIO_Mode_AIN; GPIO_Init(GPIOA, GPIO_InitStruct); // 设置 ADC 时钟分频72M / 6 12MHzADC 最大允许 14MHz RCC_ADCCLKConfig(RCC_PCLK2_Div6); // ADC 基础配置 ADC_InitTypeDef ADC_InitStruct; ADC_InitStruct.ADC_ContinuousConvMode ENABLE; // 开启连续转换模式采集完自动开始下一次 ADC_InitStruct.ADC_DataAlign ADC_DataAlign_Right; // 数据右对齐12 位 ADC 低 12 位有效 ADC_InitStruct.ADC_Mode ADC_Mode_Independent; // 独立模式单 ADC 工作 ADC_InitStruct.ADC_NbrOfChannel 1; // 转换通道数量1 个 ADC_InitStruct.ADC_ExternalTrigConv ADC_ExternalTrigConv_None; // 禁止外部触发软件启动 ADC_InitStruct.ADC_ScanConvMode DISABLE; // 关闭扫描模式单通道无需扫描 ADC_Init(ADC1, ADC_InitStruct); // 配置规则组通道ADC1 通道 0采样时间 239.5 周期最长采样最稳定 ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_239Cycles5); // DMA 通道 1 配置DMA1 通道 1 固定绑定 ADC1 DMA_InitTypeDef DMA_InitStruct; DMA_DeInit(DMA1_Channel1); // 复位 DMA 通道 1 DMA_InitStruct.DMA_BufferSize 64; // 一次传输的总数据量64 个 DMA_InitStruct.DMA_DIR DMA_DIR_PeripheralSRC; // 传输方向从外设ADC到内存 DMA_InitStruct.DMA_M2M DMA_M2M_Disable; // 关闭内存到内存模式 DMA_InitStruct.DMA_MemoryBaseAddr (uint32_t)buf; // 内存目标地址数据缓冲区 buf DMA_InitStruct.DMA_MemoryDataSize DMA_MemoryDataSize_HalfWord; // 内存数据位宽16 位 DMA_InitStruct.DMA_MemoryInc DMA_MemoryInc_Enable; // 开启内存地址自增自动填数组 DMA_InitStruct.DMA_Mode DMA_Mode_Circular; // 循环模式传完 64 个自动从头开始 DMA_InitStruct.DMA_PeripheralBaseAddr (uint32_t)ADC1-DR;// 外设源地址ADC 数据寄存器 DR DMA_InitStruct.DMA_PeripheralDataSize DMA_PeripheralDataSize_HalfWord; // 外设数据位宽16 位 DMA_InitStruct.DMA_PeripheralInc DMA_PeripheralInc_Disable;// 外设地址不自增固定读 DR DMA_InitStruct.DMA_Priority DMA_Priority_High; // DMA 优先级高 DMA_Init(DMA1_Channel1, DMA_InitStruct); DMA_Cmd(DMA1_Channel1, ENABLE); // 使能 DMA1 通道 1 ADC_DMACmd(ADC1, ENABLE); // 使能 ADC 的 DMA 请求转换完自动触发 DMA ADC_Cmd(ADC1, ENABLE); // 使能 ADC1 // ADC 校准提高精度必须执行 ADC_ResetCalibration(ADC1); // 复位校准 while (ADC_GetResetCalibrationStatus(ADC1)); // 等待复位完成 ADC_StartCalibration(ADC1); // 开始校准 while (ADC_GetCalibrationStatus(ADC1)); // 等待校准完成 ADC_SoftwareStartConvCmd(ADC1, ENABLE); // 软件启动 ADC 连续转换 }采集到的数组数据如图所示主要代码解析DMA_MemoryBaseAddr告诉 DMA 数据要搬到哪里也就是你的数组地址。DMA_PeripheralBaseAddr告诉 DMA 数据从哪里搬也就是 ADC 的数据寄存器地址。DMA_MemoryDataSize和DMA_PeripheralDataSize设置数据位宽这里都是 16 位。DMA_Mode_Circular开启循环模式让 DMA 一直搬运数据。ADC_DMACmd开启 ADC 的 DMA 请求让 ADC 转换完成后自动触发 DMA 搬运。六、常见问题补充DMA不是一次送 64 个而是一个一个搬运搬满 64 次为一轮。DMA 可以同时干很多活例如STM32F103 的 DMA1 有 7 个独立通道每个通道可以独立配置。DMA 有 3 种工作方向外设 → 内存现在 ADC 用的。内存 → 外设比如 SPI 屏幕、串口发送。内存 → 内存数据拷贝比 CPU 快。七、写在后面本文所有代码均在STM32F103C8T6上实测通过可直接复制到 工程中使用无需修改任何参数。本博客仅记录自己的学习进程无任何商业用途基于论坛上已经存在的内容结合自己实操过程完成了此博客自己也做了一些细节验证在此记录下来作为学习沉淀。如有侵权联系速删。

相关文章:

STM32 ADC+高速DMA 采集原理与实战

一、核心概念1. 什么是 ADC?ADC 是模数转换器,作用是把模拟电压转换成数字值。STM32F103 的 ADC 是 12 位的,输出范围 0~4095,对应电压范围 0~3.3V,换算公式:电压 ADC值 3.3V / 4096。2. 什么是 DMA&…...

NX二次开发避坑指南:处理表达式(Expression)TAG时内存泄漏怎么办?

NX二次开发内存管理实战:表达式操作中的资源释放陷阱与解决方案 在NX二次开发领域,表达式(Expression)操作是构建参数化模型的核心技术之一。许多开发者能够熟练使用UF_MODL_ask_exps_of_feature等函数获取表达式数据,却常常忽视背后的内存管…...

终极Windows和Office智能激活方案:KMS_VL_ALL_AIO完整深度解析

终极Windows和Office智能激活方案:KMS_VL_ALL_AIO完整深度解析 【免费下载链接】KMS_VL_ALL_AIO Smart Activation Script 项目地址: https://gitcode.com/gh_mirrors/km/KMS_VL_ALL_AIO 你是否曾为Windows和Office的激活问题而烦恼?当系统频繁弹…...

别再死记硬背74HC138真值表了!用Arduino+面包板,5分钟搞懂3-8译码器怎么省IO口

用Arduino实战破解74HC138:3根线控制8个LED的硬件魔法 记得第一次在电子设计课上看到74HC138真值表时,那种面对16进制代码的茫然感至今难忘。直到某天在创客空间,看到有人用Arduino和面包板搭建了一个会"跑马"的LED阵列——只用3根…...

别再只写“人”看了!企业GEO优化的四大核心要素,让你的品牌成为AI的“默认答案”

AI不会因为你的文采而感动,它只关心能不能在0.1秒内从你的内容里挖出它要的数据和答案。最近和不少做技术出海和B2B营销的朋友聊天,大家都有一个共同的焦虑:内容发了不少,文案也打磨得很漂亮,逻辑结构也算清晰。但无论…...

告别单向控制:用RDM协议给你的DMX灯光系统做个‘体检’和‘点名’

告别单向控制:用RDM协议给你的DMX灯光系统做个‘体检’和‘点名’ 灯光控制系统的运维人员常常面临一个尴尬局面:当舞台上的灯具突然罢工时,你只能靠肉眼和经验去排查故障。传统DMX512协议的单向通信特性,让系统维护变成了"盲…...

如何搭建一个药品市场价格监控智能体来实现100%价格一致性? —— 2026全渠道价格均衡化架构实战指南

在2026年的医药流通领域,随着《关于健全药品价格形成机制的若干意见》的全面深化落实,药品价格监管已从“事后查处”转向“实时监测与动态预警”。 所谓的“100%价格一致性”,在当前政策语境下,并非指全国所有药店的药品价格必须分…...

三大主流推理框架如何选型--SGLang、KTransformers、vLLM

文章目录一、基础信息与核心定位1. vLLM2. SGLang3. KTransformers二、统一测试基准(数据可信前提)三、三大框架量化实测数据(关键支撑)1. 单轮普通对话(无重复上下文)2. 多轮对话 / 重复上下文&#xff08…...

专业相机连接SDK源码,为你的影像应用快速构建可靠传输基础

专业相机连接SDK源码,为你的影像应用快速构建可靠传输基础如果你正在开发图片直播、远程拍摄或自动化影像采集类应用,那么“相机与手机稳定传输”这个基础功能,一定是你无法绕过的技术门槛。今天,我们聊聊为什么选择一套成熟的相机…...

高通Camx架构实战:如何通过日志(Logcat)快速定位Camera启动失败问题

高通Camx架构实战:如何通过日志(Logcat)快速定位Camera启动失败问题 当你在调试高通平台的Camera模块时,是否遇到过这样的场景:应用调用了Camera API,但预览界面一片漆黑,或者直接抛出了Camera设…...

2026 年 7 款国产化企业级智能体横向对比:信创适配与落地能力测评

进入 2026 年,中国信创产业已从基础软硬件的“局部替代”全面迈向核心业务系统的“体系化升级”。在这一背景下,企业级智能体(AI Agent)不再仅仅是技术实验室中的原型,而是成为了驱动金融、能源、政务等关键行业数字化…...

SignalTap II高级玩法:多级触发与多次触发实战详解,精准捕捉复杂时序问题

SignalTap II高级玩法:多级触发与多次触发实战详解,精准捕捉复杂时序问题 调试FPGA设计就像在黑暗森林中寻找一只会隐形的萤火虫——你永远不知道它什么时候会出现,更不知道它会在哪个角落闪烁。SignalTap II作为Intel FPGA开发者的"夜视…...

text-ada-001 完整指南(含训练数据细节与停用说明)

text-ada-001 是 OpenAI 早期 GPT-3 系列中的入门级、超轻量文本生成模型,属于第一代 instruct 系列(后缀 -001),以速度快、成本低为核心优势,现已于 2024 年 1 月 4 日正式停用。该模型与同系列的 text-davinci-003、…...

CANoe Trace窗口保姆级配置指南:从列显示到颜色字体,打造你的专属分析视图

CANoe Trace窗口高阶配置实战:打造高效诊断视图的5个关键策略 在汽车电子系统开发与测试领域,CANoe的Trace窗口就像工程师的"听诊器",但大多数人只停留在基础使用层面。当面对复杂的车载网络数据流时,未经优化的Trace视…...

XGBoost损失函数原理与实战应用指南

1. 理解XGBoost损失函数的重要性在机器学习竞赛和工业实践中,XGBoost(eXtreme Gradient Boosting)长期占据着主导地位。这个强大的算法框架之所以能够持续保持优势,很大程度上得益于其灵活且高效的损失函数设计。损失函数就像是模…...

3分钟快速掌握:ncmdump终极NCM文件转换指南

3分钟快速掌握:ncmdump终极NCM文件转换指南 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的加密NCM文件无法在其他设备播放而烦恼吗?ncmdump就是你的终极解决方案!这款简单…...

PUBG罗技鼠标宏终极指南:5步轻松实现完美压枪

PUBG罗技鼠标宏终极指南:5步轻松实现完美压枪 【免费下载链接】logitech-pubg PUBG no recoil script for Logitech gaming mouse / 绝地求生 罗技 鼠标宏 项目地址: https://gitcode.com/gh_mirrors/lo/logitech-pubg 你是否在《绝地求生》中总是因为武器后…...

EMAGE:从音频到全身动作,揭秘统一框架如何重塑数字人动画生成

1. 为什么数字人动画需要统一框架? 数字人动画技术这几年发展得特别快,从早期的僵硬机械动作,到现在能做出几乎以假乱真的表情和肢体语言。但不知道你有没有发现,很多数字人在说话时,嘴巴动得很自然,身体却…...

联易融从稳居第一到解锁全球——2026年价值重估逻辑

2026年4月,联易融科技集团(09959.HK)发布2025年全年业绩报告。超越单一数据的点评,从整体视角重新审视2025年报揭示的联易融增长图景——它的过去够不够扎实,它的现在够不够清晰,它的未来够不够可期。先看&…...

从像素到感知:主流颜色空间(RGB, YUV, HSV, CMYK, HSI)的技术演进与应用分野

1. 颜色空间的本质与数字化过程 当你用手机拍下一张晚霞照片时,相机究竟如何将那些绚丽的色彩转化为数字信号?这要从人眼的生理特性说起。我们看到的颜色本质上是不同波长的光刺激视网膜后,大脑解码产生的视觉感知。有趣的是,人类…...

3种格式一键转换:浏览器图片格式转换终极解决方案

3种格式一键转换:浏览器图片格式转换终极解决方案 【免费下载链接】Save-Image-as-Type Save Image as Type is an chrome extension which add Save as PNG / JPG / WebP to the context menu of image. 项目地址: https://gitcode.com/gh_mirrors/sa/Save-Image…...

3步掌握GPX Studio:开源在线GPX编辑器的终极指南

3步掌握GPX Studio:开源在线GPX编辑器的终极指南 【免费下载链接】gpxstudio.github.io The online GPX file editor 项目地址: https://gitcode.com/gh_mirrors/gp/gpxstudio.github.io 在户外运动、骑行导航和GPS轨迹处理的世界里,GPX文件是你探…...

最后50天,PMP还能过吗?能,只要你别把PMBOK当《圣经》啃

大家好,我是那个在倒数50天才开始认真备考、最后竟然通关的懒癌患者阿陈。今天是4月23日。先给你一个灵魂拷问——报名截止了吗?没有。全国统一报名截止时间是今天下午16:00。没错,这篇文章发出来的时候,报名通道还在开着&#xf…...

Yakit WebFuzzer序列实战:巧用数据提取器和Nuclei DSL函数,动态处理上传路径

Yakit WebFuzzer序列实战:动态路径处理与Nuclei DSL高阶应用 在渗透测试中,文件上传漏洞的验证往往需要处理服务器返回的动态路径。这些路径可能包含相对路径符号(如../upload/)、时间戳或随机字符串,直接使用这些路径…...

终极指南:在Windows电脑上直接运行安卓APK文件的完整解决方案

终极指南:在Windows电脑上直接运行安卓APK文件的完整解决方案 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 你是否想过在Windows电脑上直接运行安卓应用&…...

别再死记硬背了!用Tiny210原理图,手把手拆解DDR内存Bank和Rank的硬件连接

从Tiny210原理图实战拆解DDR内存硬件设计奥秘 在嵌入式系统开发中,DDR内存的设计与调试往往是硬件工程师面临的核心挑战之一。许多开发者虽然了解DDR的基本原理,但当面对实际原理图时,那些抽象的Bank、Rank概念突然变得难以捉摸——地址线为什…...

eCodeSDK发票组件三步搭建

在泛微E9流程表单中,通过ecodeSDK快速搭建一个功能完善的发票夹组件,可以极大地简化发票数据的选择与录入流程。以下是一个清晰的三步搭建指南,涵盖了从环境准备到功能集成的全过程。 第一步:项目初始化与组件注册 首先,在泛微E9的ecode开发平台中创建一个新的功能包,并…...

ComfyUI WD1.4 反推插件TensorRT依赖缺失报错分析与修复

1. ComfyUI WD1.4反推插件报错现象解析 最近在ComfyUI社区里,不少小伙伴反馈WD1.4反推提示词插件运行时出现奇怪的报错。我自己在搭建AI绘画工作流时也踩过这个坑,当时看到满屏红色错误日志真是头皮发麻。典型的报错信息长这样: [E:onnxrunti…...

保姆级教程:手把手教你给Jenkins装上Gitee插件并配置全局连接(含Docker重启避坑)

Jenkins与Gitee深度集成实战:从插件安装到自动化构建全流程解析 在当今快速迭代的软件开发环境中,持续集成与持续交付(CI/CD)已成为团队协作的标配。作为开源CI/CD工具的标杆,Jenkins凭借其强大的插件生态和灵活性,依然是众多开发…...

MathType与Word联动的秘密:从加载机制解析‘错误53‘的根治方法(附注册表修复技巧)

MathType与Word联动的技术内幕:从加载机制到"错误53"的终极解决方案 当你在深夜赶制学术论文,突然遭遇MathType罢工,屏幕上跳出"错误53,文件未找到MathPage.WLL"的提示,那种焦虑感恐怕每个科研工…...