STM32中ADC模数转换器
一、ADC简介
ADC模拟-数字转换器
ADC可以将引脚连续变化的模拟电压转换为内存中存储的数字变量,建立模拟电路到数字电路的桥梁
12位逐次逼近型ADC,1us转换时间
输入电压范围: 0~3.3V,转换结果范围:0~4095
18个输入通道,可测量16个外部和2个内部信号源
规则组和注入组两个转换单元
模拟看门狗自动检测输入电压范围
STM32F2103C8T6 ADC资源:ADC1、ADC2、10个外部输入通道
二、逐次逼近型ADC
逐次逼近型ADC内部结构
ADC0809:是一个独立的8位逐次逼近型ADC芯片,在以前的时候,单片机的性能还不是很强,所以需要外挂一个ADC芯片才能进行AD转换,这个ADC0809就是一款比较经典的ADC芯片,但现在单片机的性能和集成度都有很大的提升,很多单片机内部就已经集成了ADC外设,这样就不用外挂芯片了,引脚可以直接测电压,使用还是非常方便的
结构的分析
首先在最左边这里IN0~IN7,是8路输入通道,通过通道选择开关,选中一路,输入到比较器前面的箭头的位置进行转换
其次下面的这里是地址锁存器和译码:就是你想选择哪个通道,就把通道号放在这三个脚上,然后给一个锁存信号,上面这里对应的通道开关就可以自动拨好了
上面这两个部分就可以看作是一个可以通过模拟信号的数据选择器
因为ADC转换是一个很快的过程,你给一个开始信号,过个us就转换完成了,所以说如果想转换多路信号,那不必设计多个AD转换器,只需要一个AD转换器,然后加一个多路选择开关,想转换哪一路,就先拨一下开关,选中对应通道,然后在开始转换就行了
这就是输入通道选择的部分,这个ADC0809只有8个输入通道,我们STM32内部的ADC是有18个输入通道的,所以对应这里,就是一个18路输入的多路开关,然后输入信号我们选择好了,我们来看下一部分
怎么才能知道这个电压对应的编码数据是多少呢
这个就需要我们用逐次逼近的方法来一一比较了,首先一个电压比较器,它可以判断两个输入信号电压的大小关系,输出一个高低电平指示谁大谁小,它的两个输入端,一个待测的电压,另一个这里DAC的电压输出端,DAC是数模转换器(给他一个数据,他就可以输出数据对应的电压,DAC内部是使用加权电阻网络来实现的转换,想要深入探究看江科大51单片机教程里的DA/AD一节)
现在我们有了一个外部通道输入的未知编码的电压和一个DAC输出的已知编码的电压,它们同时输入到电压比较器,进行大小判断,如果ADC输出的电压比较大,我就调小DAC数据,如果DAC输出的电压比较小,我就增大DAC数据,直到DAC输出的电压和外部通道输入的电压近似相等,这样DAC输入的数据就是外部电压的编码数据,这就是DAC的实现原理。这个电压调节的过程就是这个逐次逼近SAR来完成的,为了最快找到未知电压的编码,通常我们会使用二分法进行寻找
例如:这里是8位的ADC,那编码就是从0~255,那第一次比较的时候,我们就给DAC输入255的一半,进行比较,就是128,然后看看谁大谁小,如果DAC电压大了,如果第二次比较的时候,在就给128的一半,64,如果还是大,第三次比较的时候就给32,如果这次DAC电压小了,那第四次就给32到64中间的值,然后继续,这样依次进行下去,就能最快地找到未知电压的编码
那然后AD转化结束后,DAC的输入数据就是未知电压的编码,输出8位就有8根线,12位就有12根线
最上面EOC是转换结束信号
START是开始转换,给一个输入脉冲,开始转换
CLOCK是ADC时钟,因为ADC内部是一步一步进行判断的,所以需要时钟来推动这个过程
下面的B\VREF+和VREF-是DAC的参考电压,比如你给一个数据255,就是对应5V还是3.3V,就由这个参考电压决定,这个DAC的参考电压也决定了ADC的输入范围,所以它也是ADC参考电压,最后左边是整个芯片电路的供电,VCC和GND,通常这个参考电压的正极和VCC是一样的会接在一起,参考电压的负极和GND也是一样的,也连接在一起,所以一般情况下,ADC输入电压的范围就和ADC的供电是一样的
STM32F103C8T6内部的ADC结构
这里左边是ADC的输入通道,包括16个GPIO口,IN0~IN15,和两个内部的通道,一个内部温度传感器,一个是VREFINT内部参考电压,然后18个输入通道,然后是一个模拟多路开关,可以指定我们想要选择的通道,右边是多路开关的输出,进入到模数转换器,这里模数转换器就是执行的我们刚才讲过的逐次比较的过程,转换的结果会直接放在这个数据寄存器里,我们读取寄存器就能知道ADC转换的结果了
在模拟多路开关中,对于普通的ADC,多路开关一般都是只选一个的,就是选中某一个通道,开始转换,等待转换完成,取出结果,这是普通的流程
但是这里比较高级,他可以同时选中多个,而且在转换的时候,还分成了两个组,规则通道组和注入通道组,其中规则组可以一次性最多选中16个通道,注入组最多选中4个通道
在这里这个东西有什么作用呢
举个简单的例子
这就像你去餐厅点菜,普通的ADC是你指定一个菜,老板给你做,然后做好了送给你。但在这里是你指定一个菜单,这个菜单最多可以填16个菜,然后你直接递个菜单给老板,老板按照菜单的顺序依次做好,一次性给你端上来,这样的话就可以大大提高效率,当然你的菜单也可以只写一道菜,这样这个菜单就简化成了普通的模式了
对于这个菜单呢也有两种,一种是规则组菜单,可以同时上16个菜,但是有一点,这个规则通道数据寄存器是有一个,也就是说这个桌子比较小,最多只能放一个菜,如果上16个菜,那不好意思,前15个菜都会被挤掉,你只能得到16个菜,所以对于规则组转换来说,如果使用这个菜单的话,最好配合DMA来实现,DMA是一个数据转运小帮手,它可以在每上一个菜之后把这儿菜挪到其他地方去,放置被覆盖
注入组:这个注入组就比较高级了,它相当于餐厅的VIP座位,在这个座位上,一次性最多可以点4个菜,并且这里数据寄存器有4个,是可以同时上4个菜的,对于注入组而言,就不用担心数据覆盖的问题了,一般情况下我们使用规则组就完全足够了
首先,左下角这里就是触发转换的部分,也就是最上面的START信号,开始转换,对于STM32的ADC,触发ADC开始转换的信号有两种,一种是软件触发,就是你在程序中手动调用一条代码,就可以启动转换了,另一种就是硬件触发,就是右下角部分这些触发源,上面是注入组的触发源,下面这些是规则组的触发源,这些触发源只要来自定时器,有定时器的各个通道,还有TRGO定时器主模式的输出,定时器可以通向ADC,DAC这些外设,用于触发转换。那因为ADC经常需要过一个固定时间段转换一次(比如每隔1ms转换一次,正常思路就是,用定时器,每隔1ms申请一次中断,在中断里手动开始一次转换,这样也是可以的)但是频繁进入中断对我们的程序是有一定影响的,比如你有很多中断都需要频繁进入,那肯定会影响主程序的执行,并且不同中断之间,由于优先级的不同,也会导致某些中断不能及时得到响应,如果触发ADC的中断不能及时响应,那么我们ADC的转换频率就肯定会产生影响了,所以对于这种需要频繁进中断,并且在中断里只完成了简单工作的情况,一般都会有硬件的支持
在左上角这里是VREF+、VREF-、VDDA和VSSA,上面是ADC的参考电压,决定了ADC输入电压的范围,下面是ADC的供电引脚,一般情况下,VREF+要接VDDA,VREF-要接VSSA
右边的这里的ADCCLK是ADC的时钟,用于驱动内部逐次比较的时钟,这个是来自ADC预分频器,这个ADC预分频器是来源于RCC的
DMA请求是用于触发DMA进行数据转运的
模拟看门狗:它里面可以存一个阈值高限和阈值底限,如果启动了模拟看门狗,并指定了看门的通道,那这个看门狗就会关注它看门的通道,一旦超过这个阈值范围了,它就会乱叫,就会在上面申请一个模拟看门狗的中断,最后通向NVIC,对于规则组和注入组而言呢,它们转换完成之后,也会有一个EOC转换完成的信号
EOC:规则组的完成信号
JEOC:注入组完成的信号
这两个信号会在状态寄存器里置一个标志位,我们读取标志位,就能知道是不是转换结束了,同时这两个标志位也可以去到NVIC申请中断,如果开启了NVIC对应的通道,它们就会触发中断
ADC基本结构
输入通道
这些就是ADC通道和引脚复用的关系
这个对应关系也可以通过引脚定义表看出来
转换模式
单次转换,非扫描模式
这个是最简单的
这里左边画了一个列表,这个表就是规则组里的菜单,有16个空位,分别是序列1都序列16,你可以在这里“点菜”就是写入你要转换的通道,在非扫描的模式下,这个菜单就只有第一个序列1的位置有效。这时菜单同时选中一组的方式就退化为简单地选中一个的方式了,这里序列1的位置指定我们想转换的通道,比如通道2,然后就可以触发转换,ADC就会对这个通道2进行模数转换,过一点时间,转换完成。转换结果放在数据寄存器里,同时EOC标志位置1。我们判断这个EOC标志位,如果转换完了,那我们就可以在数据寄存器里读取结果了,如果我们想在启动一次转换,那就需要在触发一次,转换结束,置EOC标志位,读结果。如果想换一个通道转换,那在转换之前,把第一个位置的通道2改成其他通道,然后在启动转换,这样就行了
连续转换,非扫描模式
它与上一种单次转换不同的是,它在一次转换结束后不会停止,而是立刻开始下一轮的转换,然后一直持续下去。这样就只需要最开始触发一次,之后就可以一直转换了。这个模式的好处就是开始转换之后不需要等待一段时间的,因为它一直都在转换,所以你就不需要手动开始转换了,也不用判断是否结束的,想要读AD值的时候,直接从数据寄存器取就是了,这就是连续转换,非扫描的模式
单次转换,扫描模式
这个模式也是单次转换,所以每触发一次转换结束后,就会停下来,下次转换就得在触发才能开始,然后它是扫描模式,这就会用到这个菜单列表了,你可以在这个菜单里点菜(比如第一菜是通道2,第二菜是通道5,等等),这里每隔位置是通道几可以任意指定,并且也是可以重复的然后初始化结构体里还会有个参数,就是通道数目,以为这16个位置你可以不用完,只用前几个,那你就需要在给一个通道数目的参数,告诉他,我有几个通道(比如这里指定通道数目为7,那它就只看前7个位置,然后每次触发之后会,他就依次对这前7个位置进行AD转换,转换结果都放在数据寄存器里,这里为了防止数据被覆盖,就需要用到DMA及时将数据挪走,那7个通道转换完成之后,产生EOC信号,转换结束,然后在触发下一次,就又开始新一轮的转换)这个就是单次转换,扫描模式的工作流程
连续转换,扫描模式
这个模式的转换就是在上一个的基础上变了一点,就是一次转换完成后,立刻开始下一次的转换
触发控制
这个表就是规则组的触发源,这个表里,有来自定时器的信号,还有外部引脚或定时器的信号,这个具体是引脚还是定时器,需要用AFIO重映射来确定,最后是软件控制位,也就是我们之间说的然软件触发,这些触发信号怎么选择,可以通过设置右边这个寄存器来完成,当然使用库函数的话,直接给一个参数就行了
数据对齐
我们这个ADC是12位的,它的转换结果就是一个12位的数据,但是这个数据寄存器是16位的,所以就存在一个数据对齐的问题
数据右对齐:就是12位的数据向右靠,高位多出来的几位就补0
数据左对齐:就是12位的数据向左靠,低位多出来的几位补0
在这里我们一般使用的都是第一种右对齐,这样读取这个16位寄存器,直接就是转换结果
如果是左对齐,直接读的话,得到的数据会比实际的大
转换时间
校准
这个我们不需要理解,因为这个过程是固定的,我们只需要在ADC初始化的最后,加几条代码就行了,至于怎么计算,怎么校准的,我们不需要管,所以这个了解一下就行
硬件电路
第一个是一个单位器产生一个可调的电压
相关文章:

STM32中ADC模数转换器
一、ADC简介 ADC模拟-数字转换器 ADC可以将引脚连续变化的模拟电压转换为内存中存储的数字变量,建立模拟电路到数字电路的桥梁 12位逐次逼近型ADC,1us转换时间 输入电压范围: 0~3.3V,转换结果范围:0~4095 18个输入…...

初学stm32 --- 外部中断
目录 STM32 IO 口中断基础知识 相关库函数: 使用 IO 口外部中断的一般步骤 STM32 IO 口中断基础知识 STM32 的每个 IO 都可以作为外部中断的中断输入口。STM32F103 的中断控制器支持 19 个外部中断/事件请求。每个中断设有状态位,每个中断/事件都有独立…...

wordpress调用指定分类ID下 相同标签的内容
要在WordPress中调用分类ID为1、3、7的分类下,具有相同标签的前10个内容,可以使用自定义的WordPress查询(WP_Query)。以下是实现此功能的步骤和示例代码: 步骤: 确定共同标签: 首先,你需要确定分类1、3、…...

SQL语法基础知识总结
一、引言 在当今数字化时代,数据的存储和管理至关重要。SQL(Structured Query Language),即结构化查询语言,是用于管理关系型数据库的强大工具。无论是开发 Web 应用、进行数据分析还是处理企业级数据,掌握…...

css 实现呼吸灯效果
先看效果: 动画的结果就想实在呼吸,完整的代码如下: <template><div class"container"><div class"long-breath"></div></div> </template><style lang"less"> html, body{h…...

IMX6ULL开发板如何关掉自带的QT的GUI界面和poky的界面的方法
重要说明:其实最后发现根本没必要去关掉自带的QT的GUI界面,直接把屏幕先刷黑就可以看到测试效果了,把屏蔽先刷黑的代码见博文: https://blog.csdn.net/wenhao_ir/article/details/144594705 不过,既然花了时间摸索如何…...

几种广泛使用的 C++ 编译器
C 编译器有很多种,它们在不同的操作系统和开发环境中提供服务。以下是几种广泛使用的 C 编译器: 1. GCC (GNU Compiler Collection) 平台:跨平台(Linux, macOS, Windows)特点:GCC 是一个自由软件编译器套…...

《Vue进阶教程》第十六课:深入完善响应式系统之单例模式
往期内容: 《Vue进阶教程》第五课:ref()函数详解(重点) 《Vue进阶教程》第六课:computed()函数详解(上) 《Vue进阶教程》第七课:computed()函数详解(下) 《Vue进阶教程》第八课:watch()函数的基本使用 《Vue进阶教…...

C语言版解法力扣题:将整数按权重排序
1.题目描述 我们将整数 x 的 权重 定义为按照下述规则将 x 变成 1 所需要的步数: 如果 x 是偶数,那么 x x / 2 如果 x 是奇数,那么 x 3 * x 1 比方说,x3 的权重为 7 。因为 3 需要 7 步变成 1 (3 --> 10 -->…...

Unity ECS和OOP优劣对比
OOP的优劣 面向对象编程(OOP, Object-Oriented Programming)是一种通过对象及其交互来组织代码的编程范式,广泛应用于软件开发中。以下是OOP的优缺点: 优点 代码可重用性 继承机制:通过继承,子类可以复用…...

【Java基础面试题026】Java中的String、StringBuffer和StringBuilder的区别是什么?
回答重点 他们都是Java中处理字符串的类,区别主要体现在可变性、线程安全和性能上 1)String 不可变:String是不可变类,字符串对象创建,存储在堆中,字符串内容存储在字符串常量池中,一旦创建内…...

解析在OceanBase创建分区的常见问题|OceanBase 用户问题精粹
在《分区策略和管理分区计划的实践方案》这篇文章中,我们介绍了在ODC中制定分区策略及有效管理分区计划的经验。有不少用户在该帖下提出了使用中的问题,其中一个关于创建分区的限制条件的问题,也是很多用户遭遇的老问题。因此本文以其为切入&…...

Flutter组件————Container
Container Container 是 Flutter 中最常用的布局组件之一 参数 参数名称类型描述alignmentAlignmentGeometry定义子组件在其内部的对齐方式,默认为 null,即不改变子组件的位置。paddingEdgeInsetsGeometry内边距,用于在子组件周围添加空间…...

Java重要面试名词整理(二):SpringMyBatis
文章目录 Spring篇Spring核心推断构造方法AOP动态代理Advice的分类Advisor的理解AOP相关的概念 定义BeanASM技术JFR依赖注入循环依赖LifecycleSpring AOT Spring事务Spring事务传播机制Spring事务传播机制是如何实现的呢?Spring事务传播机制分类 SpringMVCHandlerHandlerMappi…...

Excel生成DBC脚本源文件
Excel制作 新建一个Excel,后缀为“.xls” 工作本名称改为“CAN_Matrix” 在首行按照列来起名字,在里面只需要填写必须的内容即可。 列数名称第0列Message Name第1列Message Format第2列Message ID第3列Message Length (byte)第4列Message Transmitte…...

Git进阶:本地或远程仓库如何回滚到之前的某个commit
在Git的使用过程中,我们经常会遇到需要回滚到之前某个commit的情况。无论是为了修复错误、撤销更改,还是为了重新组织代码,回滚到特定commit都是一个非常有用的技能。本文将介绍几种常用的回滚方法,帮助读者更好地掌握Git版本控制…...

linux 中文输入法设置的宏观思路 (****)
乱是永远的不乱,变是永远的不变。 $ ibus help # 注意:help 前没有杠符号 $ setxkbmap -help # 注意:help 前只有一个杠符号 $ localectl --help # 注意:help 前有 2 个杠符号 $ man im-config # 注意:-h, --help 只出来提示信息:请参考。。。。。。。 $ man abc…...

271-基于XC7V690T的12路光纤PCIe接口卡
一、板卡概述 基于XC7V690T的12路光纤PCI-E接口卡,用于实现多通道高速光纤数据接收和发送,板卡兼容PCIe 2.0和PCIe 3.0规范,利用PCI-E Switch PEX 8748实现FPGA芯片与计算机的通信,计算机与板卡接口处提供PCI-e 16速接口ÿ…...

Semaphore UI安装和实践
本次实验环境采用centos7.9操作系统,使用rpm包安装方式。 1.配置yum源 --下载centos华为云镜像仓库 wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.huaweicloud.com/repository/conf/CentOS-7-anon.repo[rootlocalhost ~]# wget -O /etc/yum.repos.…...

Redis篇--常见问题篇7--缓存一致性2(分布式事务框架Seata)
1、概述 在传统的单体应用中,事务管理相对简单,通常使用数据库的本地事务(如MySQL的BEGIN和COMMIT)来保证数据的一致性。然而,在微服务架构中,由于每个服务都有自己的数据库,跨服务的事务管理变…...

Docker Compose 安装 Harbor
我使用的系统是rocky Linux 9 1. 准备环境 确保你的系统已经安装了以下工具: DockerDocker ComposeOpenSSL(用于生成证书)#如果不需要通过https连接的可以不设置 1.1 安装 Docker 如果尚未安装 Docker,可以参考以下命令安装&…...

使用docker compose安装gitlab
使用docker compose安装gitlab GitLab简介设置GITLAB_HOME路径创建docker挂载目录获取可用的GitLab版本编写docker-compose.yml文件启动docker基础配置GITLAB_OMNIBUS_CONFIG修改配置 中文设置数据库配置系统邮箱配置 GitLab简介 GitLab是一个基于Git的开源项目,…...

大模型日报 2024-12-18
大模型日报 2024-12-18 大模型资讯 标题: 3B模型长思考后击败70B!HuggingFace逆向出o1背后技术细节并开源 摘要:这篇文章探讨了小模型在经过长时间思考后,如何在性能上超越更大规模模型的现象。HuggingFace通过逆向工程和开源技术…...

Linux安装mysql5.7
一、下载mysql5.7 首先我们需要去下载linux版本的mysql-5.7.24的安装包。 1.可以去官方网站链接: https://downloads.mysql.com/archives/community/ ,下载mysql-5.7.24-linux-glibc2.12-x86_64.tar压缩包。 2.在线下载,使用wget命令,直接从官网下载…...

【容器】k8s学习笔记原理详解(十万字超详细)
Pod详解 Pod介绍 Pod结构 每个Pod中都可以包含一个或者多个容器,这些容器可以分为两类: 用户程序所在的容器,数量可多可少Pause容器,这是每个Pod都会有的一个根容器,它的作用有两个: 可以以它为依据&am…...

.NET重点
B/S C/S B/S: 浏览器端:JavaScript,HTML,CSS 服务器端:ASP(.NET)PHP/JSP 优势:维护方便,易于升级和扩展 劣势:服务器负担沉重 C/S java/.NET/VC系列 …...

SMMU软件指南SMMU编程之虚拟机结构和缓存
安全之安全(security)博客目录导读 目录 一、虚拟机结构(VMS) 二、缓存 一、虚拟机结构(VMS) 虚拟机结构(VMS)是SMMU中的概念,是一个由STE.VMSPtr字段指向的结构,包含每个虚拟机的配置设置。在相同安全状态下具有相同虚拟机ID(VMID)的多个STE必须指向相同的VMS。…...

Go 语言并发实战:利用协程处理多个接口进行数据融合
高效地处理多个数据源并将其整合为有意义的结果是开发中一项重要的任务。Go 语言,以其强大的并发特性,为我们提供了优雅而高效的解决方案。那么我们探讨一下如何利用 Go 语言的协程,同时调用多个接口获取数据,并将这些数据无缝地合…...

Redis Hash Tag 知识详解
一、Redis Hash Tag概述 Redis Hash Tag是Redis集群环境里用于控制数据分片的关键机制。在Redis集群中,数据依据键的哈希值来确定分片存储位置。Hash Tag能让用户指定键的特定部分作为哈希计算核心部分,进而使相关键存储于同一节点,这对处理…...

在 Ubuntu 上安装 Muduo 网络库的详细指南
在 Ubuntu 上安装 Muduo 网络库的详细指南 首先一份好的安装教程是非常重要的 C muduo网络库知识分享01 - Linux平台下muduo网络库源码编译安装-CSDN博客 像这篇文章就和shit一样,安装到2%一定会卡住,如果你不幸用了这个那真是遭老罪了 环境…...