STM32 ADC采样详解

news2024/9/24 0:23:57

Content

  • 0x00 前言
  • 0x01 ADC配置
  • 0x02 滤波处理

0x00 前言

在单片机开发过程中,常常涉及到ADC的使用,市面上大部分便宜的传感器都是采用的ADC来获取其数据,如MQ-2 烟雾传感器、光敏传感器等等。
在这里插入图片描述
在这里插入图片描述

此类传感器工作原理为根据所采集到的数据变化,造成其电阻率、电导率等参数变化,从而改变输出电压的大小。而我们通过采集传感器模块的输出电压,即可分析到所需要的信息,这个过程是由模拟信号(因为数据并不是直接以数字体现,而是以电压形式给出,所以称模拟)转化为数字信号(我们需要的是一个数值:浓度,强度),所以这个外设被称为ADC(Anology to Digital),其中C表示的Convert,为转换器的意思。

那么通俗的来说,ADC就是将模拟信号转换为数字信号的一个外设。通过ADC,可以获取到以电压形式体现的信息。还是以烟雾传感器传感器为例,假设烟雾传感器的电压输出范围是0-5v,其中显而易见0代表的是烟雾浓度为0%,5v代表的是烟雾浓度为100%,2.5v代表的烟雾浓度为50%。

我们为获取当前环境的烟雾传感器浓度,只需要采集到 烟雾传感器输出的电压即可。

0x01 ADC配置

现在需要确定一下你的引脚选择,既然是要使用ADC,那么所选择的引脚必须是具有ADC功能才对,现在可以在以下表中选择ADC引脚,例如我选择PA1引脚,那么我接下来应该配置ADC1的通道1。
在这里插入图片描述

具体的配置参数细节都已经在注释之中了:

void ADC_Init()
{
	ADC_InitTypeDef ADC_InitStructure; 
	GPIO_InitTypeDef GPIO_InitStructure;
	
	// 使能ADC1外设时钟,以及将PA1引脚设置为模拟输入模式。
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1, ENABLE );
	// 设置ADC的时钟频率,也就是STM32的主频 72M/分频因子6 = 12M, 不能超过14M,否则会造成ADC采样精度下降
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);
	
	// 配置为模拟输入模式 Anology Input                    
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	ADC_DeInit(ADC1);  //复位ADC1 
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;	//ADC工作模式:ADC1和ADC2工作在独立模式
	// 开启扫描模式,则会依次扫描通道,例如你有多个烟雾传感器连接在通道1,通道2,通道3 ,通道4
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;	//模数转换工作在单通道模式
	// 单次转换模式或连续转换模式,如果开启了连续转换模式就会自动连续进行转换,否则需要自己需要的时候开启转换
	// 使用DMA时开启自动转换也会更加方便
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;	//模数转换工作在单次转换模式
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;	//转换由软件而不是外部触发启动
	//左对齐,数据范围0-65535,右对齐,数据范围0-4065(精度一样都是12位,只是12位数据以不同的对齐方式放在了uint16_t变量中)
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Left;	//ADC数据右对齐
	ADC_InitStructure.ADC_NbrOfChannel = 1;//顺序进行规则转换的ADC通道的数目
	
	ADC_Init(ADC1, &ADC_InitStructure);	//根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器

	// 注意这两个函数是不一样的,先复位校准再进行初始校准
	ADC_Cmd(ADC1, ENABLE);	//使能指定的ADC1
	ADC_ResetCalibration(ADC1);	//使能复位校准  
	while(ADC_GetResetCalibrationStatus(ADC1));	//等待复位校准
	ADC_StartCalibration(ADC1);	 //开启AD校准
	while(ADC_GetCalibrationStatus(ADC1));	 //等待初始校准
}

至此ADC校准就结束了,此时就可以编写ADC的单次转换函数了

uint16_t GetAdcValue(u8 ch)   
{
  	// 对ADC1的通道1 进行单次转换
	ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 );
	//使能指定的ADC1的软件转换启动功能	
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);		
	while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束
	return (ADC_GetConversionValue(ADC1));	// 返回ADC采样值
}

0x02 滤波处理

一般由于ADC采样到的值是不稳定的,并且电压变化的速率以及大于了ADC的采样速率,并且现实中也会有各种的干扰情况发生,所以单次采样的值并不能代表实际采样的值。

为减少这种情况的发生,所以就要进行一定的滤波处理了。

初中老师以及教过,对于化学、物理、生物实验,为了避免实验的偶然性,应当多做实验。ADC 采样也不例外,可以多次测量,取平均值,在短时间内进行多次ADC采样,取得平均值结果。那么这个就是叫做平均值滤波。这个一般只是一个很简单的处理,通常也是误差比较大的,因为加入你采到了一个非常离谱的数据,贸然取平均值便会导致整体采样值偏移。

如图,以下是由180个采样点,插入一些随机的噪声,贸然取平均值得到的数据,整体大致偏移了2000,这算是很大的误差了

在这里插入图片描述

那么还有一个方法是参考其他的采样数据,从而剔除不合理的数据,例如采用方差
等数据剔除不合理的数据,筛选一遍过后,计算得到平滑数据,如下:
在这里插入图片描述
当然,并非只有一种滤波算法可选,也可以选择一套动态的滤波算法如FFT,适用且可以应用于大多数场景。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2099688.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Axure健康助理小程序原型图70+页,医疗类高保真高交互模板

作品概况 页面数量:共 70 页 源文件格式:限 Axure RP 9/10,非app软件无源码 适用领域:医疗健康、健康助理 作品特色 本作品为健康助理小程序的Axure原型设计图,属于医疗健康项目,设计规范内容清晰&#…

坐牢第三十三天(手搓string)

一.mystring类 #include <iostream> #include <cstring> // 引入cstring以使用memcpy using namespace std; class myString {char *str; // 记录c风格的字符串int size; // 记录字符串的实际长度int my_capacity; // 记录最大容量 public:// 无参构…

LACP链路聚合

链路聚合包含两种模式&#xff1a;手动负载均衡模式和LACP&#xff08;Link AggregationControl Protocol&#xff09;模式。 手工负载分担模式&#xff1a;Eth-Trunk的建立、成员接口的加入由手工配置&#xff0c;没有链路聚合控制协议的参与。该模式下所有活动链路都参与数…

嵌入式软件--51单片机 DAY 2

一、数码管 1.数码管概况 2.设计 &#xff08;1&#xff09;硬件设计 我们可以通过阴极控制显示的位置&#xff0c;通过阳极控制显示的内容。两个数码管共有8个阴极引脚和16和阳极引脚&#xff0c;如果所有引脚都直接接入MCU&#xff0c;会造成MCU引脚的极大浪费。 为了节省…

Java编程基础-类加载机制

文章目录 基本概念类加载器的层次结构类的加载过程双亲委派模型自定义类加载器注意事项 Java 类加载器&#xff08;Class Loader&#xff09;是 Java 运行时环境的一部分&#xff0c;它负责在应用程序运行时加载类和接口的字节码。类加载器对于 Java 的动态特性和安全性有着至关…

Microsoft DirectML 现在支持 Copilot+ PC 和 WebNN

DirectML 是一个底层应用程序接口&#xff0c;使开发人员能够在任何兼容 DirectX 12 的 AMD、英特尔和英伟达&#xff08;NVIDIA&#xff09;GPU 上运行机器学习工作负载 。它首次出现在Windows 10 的 1903 版本中。最近&#xff0c;微软 开始在 DirectML 中支持现代 SoC 中的N…

新能源汽车超级电容和电池能量管理系统的simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1 电池模型 4.2 电池荷电状态&#xff08;SOC&#xff09;估算 4.3 超级电容器模型 4.4 能量管理 5.完整工程文件 1.课题概述 新能源汽车的能量管理系统&#xff08;Energy Management System, EMS…

Conda离线部署django

要在没有网络连接的环境中使用conda部署Django&#xff0c;你需要预先在有网络连接的机器上创建一个包含所有必要包的环境&#xff0c;并导出该环境的配置文件。然后&#xff0c;你可以将这个配置文件和必要的包传输到目标机器上进行安装。 下面是详细的步骤&#xff1a; 1. …

mysql优化案例分享

一、mysql介绍 1、InnoDB引擎 mysql5.5.8版本开始后。InnoDB引擎就是默认存储引擎&#xff0c;本文介绍知识点也都是围绕该引擎展开。 知识点1聚集存储 InnoDB引擎采用聚集存储&#xff0c;即每张表的存储都是主键的顺序进行存放&#xff0c;也就是每行存储的物理顺序和主键…

基于SparkGraphX实现带权重的PageRank算法

基于SparkGraphX实现带权重的PageRank算法 文章目录 基于SparkGraphX实现带权重的PageRank算法一、什么是PageRank算法二、PageRank算法的实现三、PagRank算法实现步骤四、大数据量的PageRank算法实现总结 一、什么是PageRank算法 网页排序算法之PageRank 二、PageRank算法的…

【AI视频】Runway注册、基本设置、主界面详解

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AI视频 | Runway 文章目录 &#x1f4af;前言&#x1f4af;Runway的正确启动方式推荐使用Google Chrome打开Chrome翻译 &#x1f4af;Runway的注册&#x1f4af;My Account&#xff08;我的账户&#xff09;General&#xff08;常…

HTTPie CLI:重塑命令行HTTP交互的现代工具

更多内容前往个人网站&#xff1a;孔乙己大叔 在快速发展的数字时代&#xff0c;API&#xff08;应用程序编程接口&#xff09;已成为连接不同服务和应用的桥梁。无论是开发者还是系统管理员&#xff0c;与HTTP服务进行有效且高效的交互都是日常工作的核心部分。然而&#xff0…

idea中git提交或push到远程后回退到之前的某次提交简单有效的解决方案

场景&#xff1a; 1、先模拟出团队多人开发多分支&#xff0c;在各个分支分别提交代码&#xff0c;然后都合并到master分支 2、模拟如下两个分支dev、dev-0902合并到master&#xff0c;并且合并master后push到远程了 3、假如更新版本计划有变&#xff0c;只上dev-0902分支&…

stm32之I2C通信外设

系列文章目录 1. stm32之I2C通信协议 2. stm32之软件I2C读写MPU6050陀螺仪、加速度传感器应用案例 3. stm32之硬件I2C读写MPU6050陀螺仪、加速度传感器应用案例 文章目录 系列文章目录前言一、I2C通信外设1.1 I2C外设简介1.2 软件模拟和硬件外设对比 二、I2C外设电路结构2.1 I…

【数据结构-二维前缀异或和】【分区算法优化】力扣1738. 找出第 K 大的异或坐标值

给你一个二维矩阵 matrix 和一个整数 k &#xff0c;矩阵大小为 m x n 由非负整数组成。 矩阵中坐标 (a, b) 的 目标值 可以通过对所有元素 matrix[i][j] 执行异或运算得到&#xff0c;其中 i 和 j 满足 0 < i < a < m 且 0 < j < b < n&#xff08;下标从 …

IP网络广播系统(IP网络广播系统是什么及它的优势与应用)

一、引言 在当今数字化的时代&#xff0c;音频传播技术也在不断革新。IP网络广播系统作为一种先进的音频传输解决方案&#xff0c;正逐渐在各个领域发挥重要作用。那么&#xff0c;究竟什么是IP网络广播系统呢&#xff1f;它又有着怎样独特的优势和广泛的应用呢&#xff1f;本…

1、Django Admin学习模型

此专栏应用环境和模型基于此文 开发环境 系统&#xff1a;windows11 开发工具&#xff1a;vscode 开发语言&#xff1a;python 3.8 开发框架&#xff1a;django 3.2 数据库&#xff1a;mysql8.4.1 项目目录 settings 注册两个应用 INSTALLED_APPS [django.contrib.ad…

免下载看视频,使用极空间部署P2P磁力种子流媒体服务器『TorrServer』

免下载看视频&#xff0c;使用极空间部署P2P磁力种子流媒体服务器『TorrServer』 哈喽小伙伴们好&#xff0c;我是Stark-C~ 说到在NAS上的观影体验&#xff0c;很多小伙伴的理解可能就是先下载到本地&#xff0c;然后在使用播放器打开观看。今天为大家分享另外一种观影方式&a…

JS设计模式之“语言之魂” - 原型模式

前言 当我们学习JavaScript的时候&#xff0c;经常会听到原型&#xff08;prototype)、原型链&#xff08;prototype chain&#xff09;和原型模式&#xff08;prototype pattern&#xff09;这些概念&#xff0c;它们之间有什么关联呢&#xff1f;怎么样才能使用好原型模式呢…

linux 硬件 arm架构

一.ARM&#xff1a; 1.时钟晶振&#xff1a; 在单片机系统里晶振的作用非常大&#xff0c;他结合单片机内部的电路&#xff0c;产生单片机所必须的时钟频率&#xff0c;单片机的一切指令的执行都是建立在这个基础上的&#xff0c;晶振的提供的时钟频率越高&#xff0c;那单片机…