【STM32学习】标准库实现STM32 ADC采集1路、2路、多路
目录
ADC采集
ADC配置步骤
STM32F103C8T6的ADC
输入通道
编辑
1路ADC(A4 ADC 通道4)
1路ADC源码代码链接:
2路ADC(A4 ADC 通道4、A5 ADC 通道5)基于DMA实现
多路ADC实现采集
ADC采集
ADC配置步骤
- 使能GPIO时钟和ADC时钟,设置引脚为模拟输入
- 设置ADC的分频因子
- 初始化ADC参数,包括ADC工作模式,规则序列等
- 使能ADC并校准
- 触发AD转换,读取AD转换值
STM32F103C8T6的ADC
根据中文参考手册介绍,STM32F103C8T6单片机有2个12位ADC,共有18个通道,可测量16个外部和2个内部信号源。各通道的A/D转换可以单次、连续、扫描或间断模式执行。ADC的结果可以左对齐或右对齐方式存储在16位数据寄存器中。ADC的输入时钟不得超过14MHz,它是由PCLK2经分频产生。
输入通道
内外部共18个,16个GPIO,1个内部温感,1个内部参考电压。
1路ADC(A4 ADC 通道4)
ADC初始化代码:
void Init_adc(void)
{/*1. **开启RCC时钟**:包括ADC和GPIO的时钟。2. **配置GPIO**:将GPIO配置为模拟输入模式。3. **配置多路开关**:将左边的通道接入到规则组或注入组中。4. **配置ADC转换器**:设置ADC的工作模式、数据对齐方式、外部触发方式等。5. **启动ADC和DMA**:调用相关函数使能ADC和DMA,开始数据采集和传输。*/GPIO_InitTypeDef GPIO_InitStruct;ADC_InitTypeDef ADC_InitStruct;ADC_DeInit(ADC1); //将外设 ADC1 的全部寄存器重设为缺省值RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1|RCC_APB2Periph_GPIOA,ENABLE); // 开启RCC时钟// 配置ADC时钟RCC_ADCCLKConfig(RCC_PCLK2_Div6); // 6分频,72/6GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN; // 模拟输入GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4; // |GPIO_Pin_5GPIO_Init(GPIOA,&GPIO_InitStruct);//配置GPIOADC_InitStruct.ADC_ContinuousConvMode = DISABLE; // 持续模式ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right; // 向右对齐模式ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; // 不使用外部触发模式ADC_InitStruct.ADC_Mode = ADC_Mode_Independent; // 独立ADC模式ADC_InitStruct.ADC_NbrOfChannel = 1; // 总共两个通道ADC_InitStruct.ADC_ScanConvMode = DISABLE; // 使用扫描模式ADC_Init(ADC1,&ADC_InitStruct);// 选择多路通道 ,配置在规则组菜单列表的第一个位置写入通道0,55.5个周期ADC_RegularChannelConfig(ADC1,ADC_Channel_4,1,ADC_SampleTime_55Cycles5 );
// ADC_RegularChannelConfig(ADC1,ADC_Channel_5,2,ADC_SampleTime_55Cycles5 );// 开启ADC的DMA支持(要实现DMA功能,还需独立配置DMA通道等参数)
// ADC_DMACmd(ADC1, ENABLE);ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1// 校准ADC_ResetCalibration(ADC1);while(ADC_GetResetCalibrationStatus(ADC1) == SET);ADC_StartCalibration(ADC1);while(ADC_GetCalibrationStatus(ADC1));
}
获取ADC采集值+值过滤
u16 Get_ADC_Value(void)
{u32 temp_val = 0;u8 t = 0;u8 times = 50;// 设置指定ADC的规则组通道,一个序列,采样时间// ADC1,ADC通道,239.5个周期,提高采样时间可以提高精确度ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 1, ADC_SampleTime_239Cycles5); for(t=0;t<times;t++){ADC_SoftwareStartConvCmd(ADC1, ENABLE); // 使能指定的ADC1的软件转换启动功能 while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC )); // 等待转换结束temp_val+=ADC_GetConversionValue(ADC1);delay_ms(5);}return temp_val/times;
}
主函数代码实现片段:
adValue = Get_ADC_Value();
ad = adValue;
sprintf((char*)str,"AD1 = %d ",ad);
Gui_DrawFont_GBK16(0,10,RED,GRAY0, str);// 送至液晶显示
效果:


1路ADC源码代码链接:
STM32学习标准库实现STM32ADC采集1路、2路、多路资源-CSDN文库
2路ADC(A4 ADC 通道4、A5 ADC 通道5)基于DMA实现
初始化代码:
#define N 50 //每通道采50次
#define M 2 //为2个通道vu16 AD_Value[N][M]; //用来存放ADC转换结果,也是DMA的目标地址
vu16 After_filter[M]; //用来存放求平均值之后的结果
int i;void Init_adc(void)
{/*1. **开启RCC时钟**:包括ADC和GPIO的时钟。2. **配置GPIO**:将GPIO配置为模拟输入模式。3. **配置多路开关**:将左边的通道接入到规则组或注入组中。4. **配置ADC转换器**:设置ADC的工作模式、数据对齐方式、外部触发方式等。5. **启动ADC和DMA**:调用相关函数使能ADC和DMA,开始数据采集和传输。*/GPIO_InitTypeDef GPIO_InitStruct;ADC_InitTypeDef ADC_InitStruct;ADC_DeInit(ADC1); //将外设 ADC1 的全部寄存器重设为缺省值RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1|RCC_APB2Periph_GPIOA,ENABLE); // 开启RCC时钟// 配置ADC时钟RCC_ADCCLKConfig(RCC_PCLK2_Div8); // 6分频,72/6GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN; // 模拟输入GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5;GPIO_Init(GPIOA,&GPIO_InitStruct);//配置GPIOADC_InitStruct.ADC_ContinuousConvMode = ENABLE; // 持续模式ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right; // 向右对齐模式ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; // 不使用外部触发模式ADC_InitStruct.ADC_Mode = ADC_Mode_Independent; // 独立ADC模式ADC_InitStruct.ADC_NbrOfChannel = M; // 总共两个通道ADC_InitStruct.ADC_ScanConvMode = ENABLE; // 使用扫描模式ADC_Init(ADC1,&ADC_InitStruct);// 选择多路通道 ,配置在规则组菜单列表的第一个位置写入通道0,55.5个周期ADC_RegularChannelConfig(ADC1,ADC_Channel_4,1,ADC_SampleTime_55Cycles5 );ADC_RegularChannelConfig(ADC1,ADC_Channel_5,2,ADC_SampleTime_55Cycles5 );// 开启ADC的DMA支持(要实现DMA功能,还需独立配置DMA通道等参数)ADC_DMACmd(ADC1, ENABLE);ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1// 校准ADC_ResetCalibration(ADC1);while(ADC_GetResetCalibrationStatus(ADC1) == SET);ADC_StartCalibration(ADC1);while(ADC_GetCalibrationStatus(ADC1));
} void DMA_Configuration(void)
{DMA_InitTypeDef DMA_InitStructure;RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);DMA_DeInit(DMA1_Channel1); //将DMA的通道1寄存器重设为缺省值DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&ADC1->DR; //DMA外设ADC基地址DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&AD_Value; //DMA内存基地址DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //内存作为数据传输的目的地DMA_InitStructure.DMA_BufferSize = N*M; //DMA通道的DMA缓存的大小DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不变DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_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_InitStructure.DMA_Priority = DMA_Priority_High; //DMA通道 x拥有高优先级DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输DMA_Init(DMA1_Channel1, &DMA_InitStructure); //根据DMA_InitStruct中指定的参数初始化DMA的通道ADC_SoftwareStartConvCmd(ADC1, ENABLE);DMA_Cmd(DMA1_Channel1, ENABLE); //启动DMA通道
}
取值滤波
/// 数值滤波
void filter(void)
{int sum = 0;u8 count;for(i=0;i<M;i++){for( count=0;count<N;count++){sum += AD_Value[count][i];}After_filter[i]=sum/N;sum=0;}}
主函数代码:
while(1){ filter();sprintf((char*)str,"AD1 = %d ",After_filter[0]);Gui_DrawFont_GBK16(0,10,RED,GRAY0, str);sprintf((char*)str,"AD2 = %d ",After_filter[1]);Gui_DrawFont_GBK16(0,30,RED,GRAY0, str);}
实现效果:



2路ADC源码代码链接:
STM32学习标准库实现STM32ADC采集1路、2路、多路资源-CSDN文库
多路ADC实现采集
多路和2路ADC一致,只需要在2路的基础上修改即可。修改的点如下:
#define M 2 //为2个通道
多少通道就写多少通道。
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN; // 模拟输入
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5;
GPIO_Init(GPIOA,&GPIO_InitStruct);//配置GPIO
修改所选的多通道引脚。
// 选择多路通道 ,配置在规则组菜单列表的第一个位置写入通道0,55.5个周期ADC_RegularChannelConfig(ADC1,ADC_Channel_4,1,ADC_SampleTime_55Cycles5 );ADC_RegularChannelConfig(ADC1,ADC_Channel_5,2,ADC_SampleTime_55Cycles5 );
依次增加所添加的通道。
其它不需要修改,即可完成多于2通道采集。
相关文章:
【STM32学习】标准库实现STM32 ADC采集1路、2路、多路
目录 ADC采集 ADC配置步骤 STM32F103C8T6的ADC 输入通道 编辑 1路ADC(A4 ADC 通道4) 1路ADC源码代码链接: 2路ADC(A4 ADC 通道4、A5 ADC 通道5)基于DMA实现 多路ADC实现采集 ADC采集 ADC配置步骤 使能GPIO…...
【STM32】外部时钟|红外反射光电开关
1.外部时钟 单片机如何对外部触发进行计数?先看一下内部时钟,内部时钟是接在APB1和APB2时钟线上的,APB1,APB2来自stm32单片机内部的脉冲信号,也叫内部时钟。我们用来定时。同样我们可以把外部的信号接入单片机,来对其…...
【语音科学计算器】当前汇率
JSON_MARKER_HORN{“base”:“USD”,“rates”:{“EUR”:0.9758,“JPY”:157.68,“GBP”:0.8190,“CNY”:7.3327,“HKD”:7.7872,“AUD”:1.6260,“CAD”:1.4422,“CHF”:0.9157,“SGD”:1.3714,“KRW”:1473.05,“NZD”:1.7992,“THB”:34.54,“MYR”:4.4930,“PHP”:57.32,“…...
PHP post 数据丢失问题
max_input_vars是PHP配置选项之一,用于设置一个请求中允许的最大输入变量数。它指定了在处理POST请求或者通过URL传递的参数时,PHP脚本能够接收和处理的最大变量数量。 max_input_vars的默认值是1000,意味着一个请求中最多可以包含1000个输入…...
【云服务器】云服务器内存不够用,开启SWAP交换分区
交换分区(Swap) 1.创建 2GB Swap 文件 sudo fallocate -l 2G /swapfile (如果 fallocate 不支持,可以用 dd 命令) sudo dd if/dev/zero of/swapfile bs1M count2048 2.设置 Swap 权限 sudo chmod 600 /swapfile…...
未来SLAM的研究方向和热点
SLAM(Simultaneous Localization and Mapping)是同时定位与地图构建的缩写,指的是机器人或设备在一个未知环境中一边进行自我定位,一边构建出环境的地图。SLAM广泛应用于机器人、自动驾驶、无人机等领域,涉及多个研究方…...
Orange 单体架构 - 快速启动
1 后端服务 1.1 基础设施 组件说明版本MySQLMySQL数据库服务5.7/8JavaJava17redis-stackRedis向量数据库最新版本Node安装Node22.11.0 1.2 orange-dependencies-parent 项目Maven依赖版本管理 1.2.1 项目克隆 GitHub git clone https://github.com/hengzq/orange-depende…...
【SQL】多表查询案例
📢本章节主要学习使用SQL多表查询的案例,多表查询基础概念 请点击此处。 🎄数据准备 首先我们创建一个新的表也就是薪资等级表,其余两个表(员工表和薪资表)在多表查询章节中已经创建。然后我么根据这三个表完成下面的12个需求。 create tab…...
springboot系列十四: 注入Servlet, Filter, Listener + 内置Tomcat配置和切换 + 数据库操作
文章目录 注入Servlet, Filter, Listener官方文档基本介绍使用注解方式注入使用RegistrationBean方法注入DispatcherServlet详解 内置Tomcat配置和切换基本介绍内置Tomcat配置通过application.yml完成配置通过类配置 切换Undertow 数据库操作 JdbcHikariDataSource需求分析应用…...
力扣-贪心-53 最大子数组和
思路 先把每一个值都加到当前集合中,记录当前的和,直到当前记录和小于0了,再重置改记录,再次尝试累加 代码 class Solution { public:int maxSubArray(vector<int>& nums) {int res INT32_MIN;int curSum 0;for(in…...
吃一堑长一智
工作中经历,有感触记录下 故事一 以前在一家公司时,自己是一名开发人员,遇到问题请教领导解决方案,当时领导给了建议,后来上线后出问题了,背了锅。心里想的是领导说这样做的呀,为什么出问题还…...
aws(学习笔记第二十九课) aws cloudfront hands on
aws(学习笔记第二十九课) 使用aws cloudfront 学习内容: 什么是aws cloudfront练习使用aws cloudfront 1. 什么是aws cloudfront aws cloudfront的整体架构 这里可以看出,aws引入了edge location的概念,用户的client与edge location进行是…...
deepseek自动化代码生成
使用流程 效果第一步:注册生成各种大模型的API第二步:注册成功后生成API第三步:下载vscode在vscode中下载agent,这里推荐使用cline 第四步:安装完成后,设置模型信息第一步选择API provider: Ope…...
【C++八股】内存对⻬
内存对齐是指编译器按照特定规则安排数据在内存中的存储位置,以提高程序的执行效率和可移植性。 内存对齐的原因: 1. 性能优化: 现代处理器通常要求数据在内存中按照特定的边界对齐,以提高内存访问效率。 如果数据未对齐&#x…...
idea连接gitee后.反向创建仓库和分支
文章目录 自动关联你登录的账号填写你的仓库和分支完成后会在gitee上创建一个仓库 (使用idea远程兼容gitee并反向创建仓库和分支) 自动关联你登录的账号 填写你的仓库和分支 完成后会在gitee上创建一个仓库...
汽车自动驾驶辅助L2++是什么?
自动驾驶辅助级别有哪些? 依照SAE(SAE International,Society of Automotive Engineers国际自动机工程师学会)的标准,大致划分为6级(L0-L5): L0人工驾驶:即没有驾驶辅助…...
围棋打谱应用软件设计制作
围棋打谱应用软件设计制作 五子棋游戏是大家耳熟能详的游戏,深受大众喜爱。可见其在智能游戏中的地位。我在本站发了好几篇文章介绍编制方法和算法。而类似的围棋游戏则是智能游戏的顶级存在。今在此基础上编制一款围棋打谱软件。当然这是简单的游戏程序࿰…...
论文笔记-WSDM2025-ColdLLM
论文笔记-WSDM2025-Large Language Model Simulator for Cold-Start Recommendation ColdLLM:用于冷启动推荐的大语言模型模拟器摘要1.引言2.前言3.方法3.1整体框架3.1.1行为模拟3.1.2嵌入优化 3.2耦合漏斗ColdLLM3.2.1过滤模拟3.2.2精炼模拟 3.3模拟器训练3.3.1LLM…...
线代[8]|北大丘维声教授《怎样学习线性代数?》(红色字体为博主注释)
文章目录 说明一、线性代数的内容简介二、学习线性代数的用处三、线性代数的特点四、学习线性代数的方法五、更新时间记录 说明 文章中红色字体为博主敲录完丘教授这篇文章后所加,刷到这篇文章的读者在首次阅读应当跳过红色字体,先通读一读文章全文&…...
使用 C++ 和 gRPC 的常见陷阱及解决方案
文章目录 1. 环境配置的陷阱1.1 依赖版本冲突或混淆1.2 gRPC 工具缺失 2. 编译和链接的陷阱2.1 运行时库不匹配(/MT vs /MD)2.2 未解析的外部符号 3. Protobuf 文件生成的陷阱3.1 工具版本不匹配3.2 生成文件运行时库不一致 4. 运行时的陷阱4.1 缺少 DLL…...
重启Eureka集群中的节点,对已经注册的服务有什么影响
先看答案,如果正确地操作,重启Eureka集群中的节点,对已经注册的服务影响非常小,甚至可以做到无感知。 但如果操作不当,可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...
Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...
day36-多路IO复用
一、基本概念 (服务器多客户端模型) 定义:单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用:应用程序通常需要处理来自多条事件流中的事件,比如我现在用的电脑,需要同时处理键盘鼠标…...
【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...
面试高频问题
文章目录 🚀 消息队列核心技术揭秘:从入门到秒杀面试官1️⃣ Kafka为何能"吞云吐雾"?性能背后的秘密1.1 顺序写入与零拷贝:性能的双引擎1.2 分区并行:数据的"八车道高速公路"1.3 页缓存与批量处理…...
【实施指南】Android客户端HTTPS双向认证实施指南
🔐 一、所需准备材料 证书文件(6类核心文件) 类型 格式 作用 Android端要求 CA根证书 .crt/.pem 验证服务器/客户端证书合法性 需预置到Android信任库 服务器证书 .crt 服务器身份证明 客户端需持有以验证服务器 客户端证书 .crt 客户端身份…...
数据结构:泰勒展开式:霍纳法则(Horner‘s Rule)
目录 🔍 若用递归计算每一项,会发生什么? Horners Rule(霍纳法则) 第一步:我们从最原始的泰勒公式出发 第二步:从形式上重新观察展开式 🌟 第三步:引出霍纳法则&…...
MySQL基本操作(续)
第3章:MySQL基本操作(续) 3.3 表操作 表是关系型数据库中存储数据的基本结构,由行和列组成。在MySQL中,表操作包括创建表、查看表结构、修改表和删除表等。本节将详细介绍这些操作。 3.3.1 创建表 在MySQL中&#…...

