STM32——ADC篇(ADC的使用)

news2024/10/6 12:20:45

一、ADC的介绍 

1.1什么是ADC
        ADC(Analogto-Digital Converter)模拟数字转换器,是将模拟信号转换成数字信号的一种外设。比如某一个电阻两端的是一个模拟信号,单片机无法直接采集,此时需要ADC先将短租两端的电压这个模拟信号转化成数字信号,单片机才能够进行处理。

1.2 ADC的用途

        ADC具有将模拟信号转换成数字信号的能力,比如将模拟的电压转换成数字信号,单片机进行处理。可以用作温度监测或者电流监测等方面,用途极广。

1.3 STM32F1系列的ADC介绍 

        STM32F1的ADC为12位ADC,是一种逐次逼近型模拟数字转换器。它有多达18个通道,可测量16个外部和2个内部 信号源。各通道的A/D转换可以单次、连续、扫描或间断模式执行。ADC的结果可以左对齐或右 对齐方式存储在16位数据寄存器中。 模拟看门狗特性允许应用程序检测输入电压是否超出用户定义的高/低阀值。 ADC的输入时钟不得超过14MHz,它是由PCLK2经分频产生。

        STM32的ADC其转换时间为1us。 

二、STM32的ADC时钟介绍

        下图是截取的时钟树关于ADC部分,至于时钟树可以在编程参考手册的56页找到或者直接搜索时钟树就可以找到了。 

        

       可以看见其时钟来源于APB2总线,其频率最大可以达到72MHz,而ADC的时钟最大只能为14MHz,故先经过ADC预分频器经行6分频得到12MHz的时钟。

 三、ADC框图介绍:

        对于ADC的框图,下图以经把各个功能模块以及分好了,见下图:

 

3.1  ADC的18个通道介绍        

        首先其16个外部通道接口对应着某些GPIO口,至于哪些就不介绍了,可以查看引脚定义。

        而内部通道一个为内部温度传感器,可以用于查看CPU温度,另一个则是内部参考电压了,为一个1.2V左右的基准电压(不会随外部供电电压变化而变化)。有没有想过为什么ADC初始化需要校准呢?假如你芯片的供电电压不是标准的3.3V,那测量外部引脚的电压就可能不对,这时就可以读取这个基准电压经行校准,就能得到正确的电压值了,这就是校准的作用。

3.2  ADC转换单元的介绍

        规则组和注入组两个转换单元,在图中可以看见注入组最多四个通道,而规则组最多16个通道。如何选择这两种转换单元呢?下面我来说明这两种的区别:

        

        首先是通道数规则组可以包含最多16个转换,而注入组最多只能有4个转换。这意味着规则组适用于更多的通道同时进行转换,而注入组则更适合于顺序执行的单次转换。注:注入通道虽然只有4个通道,但是每一个通道都有自己的数据寄存器,即注入组有四个数据寄存器。而规则组虽然有16个转换通道,但只有一个数据寄存器。

        使用场景规则组通常用于大规模的连续转换条件下,而注入组则多用于执行单次的转换,仅在需要时进行转换。

        触发方式注入组可以打断规则组的转换,具有更高的优先级。具体来说,如果注入组在规则组转换期间被触发,当前规则组的转换会被中断,并开始执行注入组的转换。注入组转换完成后,规则组的转换会继续。此外,注入组可以在规则通道之后自动进行转换,这种模式允许最多20个转换序列的组合,其中规则通道在前,注入通道在后。

        综上所述,规则组和注入组的选择取决于具体的应用需求和场景。规则组适合于需要连续、大规模数据采集的场景,而注入组则适用于需要快速响应、单次数据采集的情况。

3.3  模拟看门狗的介绍

        模拟看门狗检测输入电压范围:用于检测ADC值,当检测值低于或高于某个阈值时,用来执行某些操作(也就相当于报警,而监测不需要人为去看守,不需要自己手动读值再用if判断,相当于家里养了狗,有陌生人来了狗就会叫,而这个陌生人代指超阈值)。

3.4  ADC触发源的介绍

        其触发源可以来自定时器、外部引脚以及软件控制位来触发。即两种触发源:软件触发以及外部触发(内部定时器、外部中断)。

        3.4.1  定时器触发:

        ADC在平常使用过程中经常需要过一个固定时间转换一次,比如每个1ms转换一次,正常思路是在定时器中断中用软件控制位来控制触发。但是这样频繁进入中断对主程序是有一定影响的,当你有很多中断时由于优先级不同也会导致某些中断不能及时得到响应,还是有很大影响,所以对于这种需要频繁进入中断且在中断只完成简单工作的情况的一般都有硬件的支持。在这里便可以这样使用:先给定时器设置定时时间,并把定时器更新事件选择为TRGO输出,然后在ADC这里选择开始触发信号为定时器的TRGO,这样定时器的更新事件就能自动触发ADC转换了且无需进入中断,节省了中断资源。

        3.4.2  外部中断触发

        外部中断可以产生一个触发脉冲,触发Adc转换。先设置EXTTRIG控制位,则外部事件就能够触发转换。

        3.4.3  软件自动触发

        软件控制位触发

3.5  ADC时钟介绍

        上文有介绍到其时钟最大不超过14MHz,那么为什么有这个规定呢?

我们可以看到其ADC的转换时间为1us,如果其频率超过了14MHz,会导致转换时间少于1us,也就导致其采样不精确。ADC的总转换时间如下:

                                Tconv = 采样时间 + 12.5个周期;

例如:当其频率ADCCLK = 14MHz,采样时间为1.5个周期(最小为1.5个周期)见下图:

 那么此时转换时间为 :Tconv = 1.5 + 12.5 = 14个周期,而频率为14MHz,则时间T = 14 * (单个周期时间)1/14MHz = 1MHz,也就是1us。这下你应该明白了吧?

四、ADC转换模式的介绍

        在ADC的配置过程中会遇到配置两个参数,即是否使用连续转换(ADC_ContinuousConvMode)以及是否启用扫描模式(ADC_ScanConvMode),而这两个配置也就产生了四种结果:单次转换非扫描、连续转换非扫描、单次转换扫描、连续转换扫描模式。

        单次转换:     只执行转换一次

        连续转换:      转换一次后立马进行下一次转换。

        非扫描模式:   只转换ADC_SQRx或ADC_JSQR选中的第一个通道。

        扫描模式:       一次性转换所有被选中的通道

下面介绍ADC的几种转换模式:

4.1   单次转换非扫描模式

        即一次只转换选中的某一个通道,且只转换一次。其转换结果放在数据寄存器里面,给EOC标志位置1表示转换完成。想获取转换结果只需要判断EOC标志位,为1时便可以读取数据了。如果还想继续转换,就得重新再触发一次。

        如果想换一个通道转换就在转换之前将第一个位置的通道改成其他通再启动转换。

4.2  连续转换非扫描模式

        一次只转换选中的某一个通道,开始时只需要触发一次便可以一直转换。与上面的区别就是不需要你再次触发了,且读取AD值直接去数据寄存器里面取,无需判断转换是否结束。

4.3  单次转换、扫描模式

        即触发转换后只转换一次,每触发一次转换结束后就会停下来,再次转换得重新触发一次。单和单次转换非扫描模式的区别就是一次可以转换多个指定的通道,即按你指定的顺序依次转换并放入到数据寄存器中。但数据寄存器只有一个,所以为了防止覆盖需要及时将数据挪走(不及时木挪走读取到的便是被后面通道所覆盖的数据)。当转换完成也会产生一个EOC信号,即转换结束。

4.4   连续转换扫描模式

        讲到这里你应该已经明白了,无非是单次转换扫描模式换成连续扫描而已。即一次转换完成继续下一次转换且可以转换多个通道而已。

五、ADC的对齐模式:

        由于此芯片的ADC为12位的,而数据寄存器为16位的,如果选择左对齐也就是相当于往左位移了4位,也就是扩大了AD采集结果。二进制特点就是数据左移一次就等效于把这个数据乘2,而左移4次也就是扩大了16倍了。

        而数据右对齐则没有这种情况,且平常都是使用右对齐。

六、ADC配置流程

        1. GPIO的初始化(开启时钟包括ADC的时钟,配置为模拟输入)

        2. 选择ADC的预分频系数(很重要!)

        3. ADC的初始化:ADC的模式(ADC_Mode:选择是否独立模式)、

                                     数据对齐(ADC_DataAlign:左对齐或右对齐)、

                                     外部触发转换选择(ADC_ExternalTrigConv:三种触发源)、

                                     是否为连续转换模式(ADC_ContinuousConvMode)、

                                     是否为扫描模式(ADC_ScanConvMode)、

                                     通道数目(ADC_NbrOfChannel)。最后初始化ADC_Init();

        4.  ADC通道配置: 选择通道以及采样时间

        5.  ADC使能以及校准:ADC_Cmd(ADCx,ENABLE);

        6.  使能或者失能指定的ADC的软件转换启动功能

七、ADC的代码例程展示

/*
 *==============================================================================
 *函数名称:ADC1_Init
 *函数功能:初始化ADCx
 *输入参数:无
 *返回值:无
 *备  注:无
 *==============================================================================
 */
void ADC1_Init(void)
{
	// 结构体定义
	GPIO_InitTypeDef GPIO_InitStructure;
	ADC_InitTypeDef ADC_InitStructure;
	
	// 开启时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1,ENABLE);
	
	// 设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);
	
	// GPIO配置
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;   //ADC1通道1
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;   // 模拟输入
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	// ADC参数配置
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;   // 独立模式
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;   // 非扫描模式	
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;   // 关闭连续转换
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;   // 禁止触发检测,使用软件触发
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;   // 右对齐	
	ADC_InitStructure.ADC_NbrOfChannel = 1;   // 1个转换在规则序列中 也就是只转换规则序列1 
	ADC_Init(ADC1, &ADC_InitStructure);   // ADC初始化
	
    ADC_RegularChannelConfig(ADC1,ADC_Channel_1, 1, ADC_SampleTime_239Cycles5 );

	ADC_Cmd(ADC1, ENABLE);   // 开启AD转换器
	
	// ADC校准
	ADC_ResetCalibration(ADC1);   // 重置指定的ADC的校准寄存器
	while(ADC_GetResetCalibrationStatus(ADC1));   // 获取ADC重置校准寄存器的状态
	
	ADC_StartCalibration(ADC1);   // 开始指定ADC的校准状态
	while(ADC_GetCalibrationStatus(ADC1));   // 获取指定ADC的校准程序

	ADC_SoftwareStartConvCmd(ADC1, ENABLE);   // 使能或者失能指定的ADC的软件转换启动功能
}

uint16_t AD_GetValue(void)
{
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);//开启转换
	while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);//等待转换完成标志位
	return ADC_GetConversionValue(ADC1);// 返回获取转换结果
}

这里附上一张ADC库函数图:

 由于扫描模式得配合DMA使用,否则数据来不及移走导致清空,所以这里先不介绍,在下篇DMA的文章中将会介绍。

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

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

相关文章

免费获取云服务器

这几天刚入手了阿贝云的 “免费云服务器 ” ,接下来给大家讲讲如何免费注册阿贝云的免费云服务器 如何获取免费云服务器 打开阿贝云官网,注册并认证 即可以领取免费云服务器 阿贝云地址:https://www.abeiyun.com/ 服务器优势 永久免费&…

单点登录(SSO)前端怎么做

单点登录(SSO)前端怎么做 本文介绍单点登录(SSO)是什么,还有就是前端怎么做。 单点登录(SSO)是什么 单点登录(SSO,Single Sign On),是在企业内部…

【Java笔记】第9章:三个修饰符

前言1. abstract(抽象的)2. static(静态的)3. final(最终的)结语 上期回顾:【Java笔记】第8章:面向对象的三大特性(封装、继承、多态) 个人主页:C_GUIQU 归属…

瑞鑫RK3588 画中画 OSD 效果展示

这些功能本来在1126平台都实现过 但是迁移到3588平台之后 发现 API接口变化较大 主要开始的时候会比较费时间 需要找到变动接口对应的新接口 之后 就比较好操作了 经过几天的操作 已实现 效果如下

项目工具|git相关

本博客暂时只作为个人资料,后续会进行完善,主要内容来自: 【【Git第一讲】:git分区与两个盒子的故事】 理解暂存区和未暂存区 git为什么要多一个暂存区?难道不能我把代码写完后就是未暂存区,然后直接提交…

ROS2从入门到精通4-3:全局路径规划插件开发案例(以A*算法为例)

目录 0 专栏介绍1 路径规划插件的意义2 全局规划插件编写模板2.1 构造规划插件类2.2 注册并导出插件2.3 编译与使用插件 3 全局规划插件开发案例(A*算法)常见问题 0 专栏介绍 本专栏旨在通过对ROS2的系统学习,掌握ROS2底层基本分布式原理,并具有机器人建…

docker bash: vi: command not found 修改文件无法使用 vi yum的方法

如题,被入坑很多次。也参考了很多的修复docker 中的vi yum等方法。最终都未解决。 因为要修改 已安装容器中的各类配置信息。无法使用vi yum很麻烦。除去使用docker 挂载文件方法外,还可以使用如下方法直接修改对应的配置文件信息。 如: 修改 logstas…

通过抑制治疗上调的环氧化酶-2来改善光动力性能的肿瘤归巢嵌合肽菱形体

引用信息 文 章:Tumor Homing Chimeric Peptide Rhomboids to Improve Photodynamic Performance by Inhibiting Therapy‐Upregulated Cyclooxygenase-2. 期 刊:Smal(影响因子:13.3) 发表时间&#xff1a…

赢单有秘诀,大模型智能陪练更懂你

随着数字化技术在营销场景的加速应用,产品营销节奏不断加快,消费者需求日益多元化、个性化,市场竞争日趋激烈。面对复杂多变的市场环境,企业新产品、新服务的推出速度大幅提升,产品知识更新愈加频繁,传统的…

神经网络 torch.nn---优化器的使用

torch.optim - PyTorch中文文档 (pytorch-cn.readthedocs.io) torch.optim — PyTorch 2.3 documentation 反向传播可以求出神经网路中每个需要调节参数的梯度(grad),优化器可以根据梯度进行调整,达到降低整体误差的作用。下面我们对优化器进行介绍。 …

通过龙讯旷腾PWmat发《The Journal of Chemical Physics》 :基于第一性原理分子动力学热力学积分的离子溶剂化自由能计算

背景导读 离子溶解是电化学中一个重要的过程。电化学反应中许多重要的参数,例如电化学还原电位、无限稀释活度系数、亨利定律溶解常数和离子溶解度等,都与离子的溶剂化能有关。然而,由于测量技术和数据处理的困难,离子溶剂化能的…

LabVIEW与Arm控制器之间的通讯

LabVIEW是一个强大的图形化编程环境,广泛应用于自动化控制、数据采集和测试测量等领域。而Arm控制器则是嵌入式系统中常用的处理器架构,广泛用于各种控制和计算任务。将LabVIEW与Arm控制器进行通讯控制,可以结合二者的优势,实现高…

笔记96:前馈控制 + 航向误差

1. 回顾 对于一个 系统而言,结构可以画作: 如果采用 这样的控制策略,结构可以画作:(这就是LQR控制) 使用LQR控制器,可以通过公式 和 构建一个完美的负反馈系统; a a 但是有上…

学习笔记——网络参考模型——TCP/IP模型(网络层)

三、TCP/IP模型-网络层 1、IPV4报头 (1)IPV4报文格式 IP Packet(IP数据包),其包头主要内容如下∶ Version版本∶4 bit,4∶表示为IPv4; 6∶表示为IPv6。 Header Length首部长度∶4 bit,代表IP报头的长度(首部长度),如果不带Opt…

安卓手机平板使用JuiceSSH无公网IP远程连接本地服务器详细流程

文章目录 前言1. Linux安装cpolar2. 创建公网SSH连接地址3. JuiceSSH公网远程连接4. 固定连接SSH公网地址5. SSH固定地址连接测试 前言 处于内网的虚拟机如何被外网访问呢?如何手机就能访问虚拟机呢? 本文就和大家分享一下如何使用 cpolarJuiceSSH 实现手机端远程连接Linux…

conntrack如何限制您的k8s网关

1.1 conntrack 介绍 对于那些不熟悉的人来说,conntrack简单来说是Linux内核的一个子系统,它跟踪所有进入、出去或通过系统的网络连接,允许它监控和管理每个连接的状态,这对于诸如NAT(网络地址转换)、防火墙和保持会话连续性等任务至关重要。它作为Netfilter的一部分运行,…

Ubuntu的启动过程

尽管通常情况下Ubuntu的启动并不需要用户过多地参与,但是Ubuntu系统的启动本身是一个非常复杂的过程。在这个过程中,有硬件的检测、系统内核的准备以及各种系统服务的启动等。作为系统管理员,需要深入了解其中所经历的阶段,才能在…

Cesium开发环境搭建(二)

由于win7搭建很费事,重新安装了OS,win10的。 记录一下,搭建步骤: 1.下载node.js。 百度搜索即可下载对应的版本。下载cesium。 2.安装node.js。 安装后,输入node -v,显示版本信息,表示安装…

【面试干货】索引的作用

【面试干货】索引的作用 1、索引的作用 💖The Begin💖点点关注,收藏不迷路💖 1、索引的作用 索引 可以协助 快速查询、更新数据库表中数据。 通过使用索引,数据库系统能够快速定位到符合查询条件的数据,提…

1.6T模块与DSP技术的演进

近日,光通信行业市场机构LightCounting在市场报告中指出,去年的模块供应商已经展示了首批1.6T光学模块的风采,而今年,DSP供应商更是着眼于第二代1.6T模块设计的未来。这些前沿技术的突破,不仅代表了数据传输速度的飞跃…