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

【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&#xff08;A4 ADC 通道4&#xff09; 1路ADC源码代码链接&#xff1a; 2路ADC&#xff08;A4 ADC 通道4、A5 ADC 通道5&#xff09;基于DMA实现 多路ADC实现采集 ADC采集 ADC配置步骤 使能GPIO…...

【STM32】外部时钟|红外反射光电开关

1.外部时钟 单片机如何对外部触发进行计数&#xff1f;先看一下内部时钟&#xff0c;内部时钟是接在APB1和APB2时钟线上的&#xff0c;APB1,APB2来自stm32单片机内部的脉冲信号&#xff0c;也叫内部时钟。我们用来定时。同样我们可以把外部的信号接入单片机&#xff0c;来对其…...

【语音科学计算器】当前汇率

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配置选项之一&#xff0c;用于设置一个请求中允许的最大输入变量数。它指定了在处理POST请求或者通过URL传递的参数时&#xff0c;PHP脚本能够接收和处理的最大变量数量。 max_input_vars的默认值是1000&#xff0c;意味着一个请求中最多可以包含1000个输入…...

【云服务器】云服务器内存不够用,开启SWAP交换分区

交换分区&#xff08;Swap&#xff09; 1.创建 2GB Swap 文件 sudo fallocate -l 2G /swapfile &#xff08;如果 fallocate 不支持&#xff0c;可以用 dd 命令&#xff09; sudo dd if/dev/zero of/swapfile bs1M count2048 2.设置 Swap 权限 sudo chmod 600 /swapfile…...

未来SLAM的研究方向和热点

SLAM&#xff08;Simultaneous Localization and Mapping&#xff09;是同时定位与地图构建的缩写&#xff0c;指的是机器人或设备在一个未知环境中一边进行自我定位&#xff0c;一边构建出环境的地图。SLAM广泛应用于机器人、自动驾驶、无人机等领域&#xff0c;涉及多个研究方…...

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】多表查询案例

&#x1f4e2;本章节主要学习使用SQL多表查询的案例,多表查询基础概念 请点击此处。 &#x1f384;数据准备 首先我们创建一个新的表也就是薪资等级表&#xff0c;其余两个表(员工表和薪资表)在多表查询章节中已经创建。然后我么根据这三个表完成下面的12个需求。 create tab…...

springboot系列十四: 注入Servlet, Filter, Listener + 内置Tomcat配置和切换 + 数据库操作

文章目录 注入Servlet, Filter, Listener官方文档基本介绍使用注解方式注入使用RegistrationBean方法注入DispatcherServlet详解 内置Tomcat配置和切换基本介绍内置Tomcat配置通过application.yml完成配置通过类配置 切换Undertow 数据库操作 JdbcHikariDataSource需求分析应用…...

力扣-贪心-53 最大子数组和

思路 先把每一个值都加到当前集合中&#xff0c;记录当前的和&#xff0c;直到当前记录和小于0了&#xff0c;再重置改记录&#xff0c;再次尝试累加 代码 class Solution { public:int maxSubArray(vector<int>& nums) {int res INT32_MIN;int curSum 0;for(in…...

吃一堑长一智

工作中经历&#xff0c;有感触记录下 故事一 以前在一家公司时&#xff0c;自己是一名开发人员&#xff0c;遇到问题请教领导解决方案&#xff0c;当时领导给了建议&#xff0c;后来上线后出问题了&#xff0c;背了锅。心里想的是领导说这样做的呀&#xff0c;为什么出问题还…...

aws(学习笔记第二十九课) aws cloudfront hands on

aws(学习笔记第二十九课) 使用aws cloudfront 学习内容&#xff1a; 什么是aws cloudfront练习使用aws cloudfront 1. 什么是aws cloudfront aws cloudfront的整体架构 这里可以看出&#xff0c;aws引入了edge location的概念&#xff0c;用户的client与edge location进行是…...

deepseek自动化代码生成

使用流程 效果第一步&#xff1a;注册生成各种大模型的API第二步&#xff1a;注册成功后生成API第三步&#xff1a;下载vscode在vscode中下载agent&#xff0c;这里推荐使用cline 第四步&#xff1a;安装完成后&#xff0c;设置模型信息第一步选择API provider&#xff1a; Ope…...

【C++八股】内存对⻬

内存对齐是指编译器按照特定规则安排数据在内存中的存储位置&#xff0c;以提高程序的执行效率和可移植性。 内存对齐的原因&#xff1a; 1. 性能优化&#xff1a; 现代处理器通常要求数据在内存中按照特定的边界对齐&#xff0c;以提高内存访问效率。 如果数据未对齐&#x…...

idea连接gitee后.反向创建仓库和分支

文章目录 自动关联你登录的账号填写你的仓库和分支完成后会在gitee上创建一个仓库 (使用idea远程兼容gitee并反向创建仓库和分支) 自动关联你登录的账号 填写你的仓库和分支 完成后会在gitee上创建一个仓库...

汽车自动驾驶辅助L2++是什么?

自动驾驶辅助级别有哪些&#xff1f; 依照SAE&#xff08;SAE International&#xff0c;Society of Automotive Engineers国际自动机工程师学会&#xff09;的标准&#xff0c;大致划分为6级&#xff08;L0-L5&#xff09;&#xff1a; L0人工驾驶&#xff1a;即没有驾驶辅助…...

围棋打谱应用软件设计制作

围棋打谱应用软件设计制作 五子棋游戏是大家耳熟能详的游戏&#xff0c;深受大众喜爱。可见其在智能游戏中的地位。我在本站发了好几篇文章介绍编制方法和算法。而类似的围棋游戏则是智能游戏的顶级存在。今在此基础上编制一款围棋打谱软件。当然这是简单的游戏程序&#xff0…...

论文笔记-WSDM2025-ColdLLM

论文笔记-WSDM2025-Large Language Model Simulator for Cold-Start Recommendation ColdLLM&#xff1a;用于冷启动推荐的大语言模型模拟器摘要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]|北大丘维声教授《怎样学习线性代数?》(红色字体为博主注释)

文章目录 说明一、线性代数的内容简介二、学习线性代数的用处三、线性代数的特点四、学习线性代数的方法五、更新时间记录 说明 文章中红色字体为博主敲录完丘教授这篇文章后所加&#xff0c;刷到这篇文章的读者在首次阅读应当跳过红色字体&#xff0c;先通读一读文章全文&…...

使用 C++ 和 gRPC 的常见陷阱及解决方案

文章目录 1. 环境配置的陷阱1.1 依赖版本冲突或混淆1.2 gRPC 工具缺失 2. 编译和链接的陷阱2.1 运行时库不匹配&#xff08;/MT vs /MD&#xff09;2.2 未解析的外部符号 3. Protobuf 文件生成的陷阱3.1 工具版本不匹配3.2 生成文件运行时库不一致 4. 运行时的陷阱4.1 缺少 DLL…...

重启Eureka集群中的节点,对已经注册的服务有什么影响

先看答案&#xff0c;如果正确地操作&#xff0c;重启Eureka集群中的节点&#xff0c;对已经注册的服务影响非常小&#xff0c;甚至可以做到无感知。 但如果操作不当&#xff0c;可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...

Python 包管理器 uv 介绍

Python 包管理器 uv 全面介绍 uv 是由 Astral&#xff08;热门工具 Ruff 的开发者&#xff09;推出的下一代高性能 Python 包管理器和构建工具&#xff0c;用 Rust 编写。它旨在解决传统工具&#xff08;如 pip、virtualenv、pip-tools&#xff09;的性能瓶颈&#xff0c;同时…...

《C++ 模板》

目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板&#xff0c;就像一个模具&#xff0c;里面可以将不同类型的材料做成一个形状&#xff0c;其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式&#xff1a;templa…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档&#xff09;&#xff0c;如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下&#xff0c;风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

day36-多路IO复用

一、基本概念 &#xff08;服务器多客户端模型&#xff09; 定义&#xff1a;单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用&#xff1a;应用程序通常需要处理来自多条事件流中的事件&#xff0c;比如我现在用的电脑&#xff0c;需要同时处理键盘鼠标…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)

前言&#xff1a; 双亲委派机制对于面试这块来说非常重要&#xff0c;在实际开发中也是经常遇见需要打破双亲委派的需求&#xff0c;今天我们一起来探索一下什么是双亲委派机制&#xff0c;在此之前我们先介绍一下类的加载器。 目录 ​编辑 前言&#xff1a; 类加载器 1. …...

面试高频问题

文章目录 &#x1f680; 消息队列核心技术揭秘&#xff1a;从入门到秒杀面试官1️⃣ Kafka为何能"吞云吐雾"&#xff1f;性能背后的秘密1.1 顺序写入与零拷贝&#xff1a;性能的双引擎1.2 分区并行&#xff1a;数据的"八车道高速公路"1.3 页缓存与批量处理…...

【实施指南】Android客户端HTTPS双向认证实施指南

&#x1f510; 一、所需准备材料 证书文件&#xff08;6类核心文件&#xff09; 类型 格式 作用 Android端要求 CA根证书 .crt/.pem 验证服务器/客户端证书合法性 需预置到Android信任库 服务器证书 .crt 服务器身份证明 客户端需持有以验证服务器 客户端证书 .crt 客户端身份…...

数据结构:泰勒展开式:霍纳法则(Horner‘s Rule)

目录 &#x1f50d; 若用递归计算每一项&#xff0c;会发生什么&#xff1f; Horners Rule&#xff08;霍纳法则&#xff09; 第一步&#xff1a;我们从最原始的泰勒公式出发 第二步&#xff1a;从形式上重新观察展开式 &#x1f31f; 第三步&#xff1a;引出霍纳法则&…...

MySQL基本操作(续)

第3章&#xff1a;MySQL基本操作&#xff08;续&#xff09; 3.3 表操作 表是关系型数据库中存储数据的基本结构&#xff0c;由行和列组成。在MySQL中&#xff0c;表操作包括创建表、查看表结构、修改表和删除表等。本节将详细介绍这些操作。 3.3.1 创建表 在MySQL中&#…...