stm32 ADC
目录
简介
stm32的adc
框图
①电压输入范围
②输入通道
编辑③ADC通道
④ADC触发
⑤ADC中断
⑥ADC数据
⑦ADC时钟
ADC的四种转换模式
hal库代码
标准库代码
简介
自然界的信号几乎都是模拟信号,比如光亮、温度、压力、声音,而为了方便存储、处理,计算机里面都是数字的 0/1 信号,将模拟信号(连续信号)转换为数字信号(离散信号)的器件就叫模数转换器(Analogto-Digital Converter, ADC)
按原理可分为:并行比较型 A/D 转换器(FLASH ADC)、逐次比较型 A/D 转换器(SAR ADC)和双积分式 A/D转换器(Double Integral ADC)。
A/D转换过程通常为4步:采样、保持、量化和编码

采样是对模拟信号周期性地抽取样值,使模拟信号转化为时间上离散的脉冲信号。采样频率( fS)越高,采样越密集,采样值越多,也就越接近模拟信号。
ADC的主要有三个性能指标:分辨率、转换时间和转换精度
分辨率:又称为转换精度, 指ADC能分辨的最小电压,通常使用二进制有效位表示,反应了ADC对输入模拟量微小变化的分辨能力。当最大输入电压一定时,位数越多,量化单位越小,误差越小,分辨率越高。
转换时间:其倒数为转换速率,指ADC从控制信号到来开始,到输出端得到稳定的数字信号所经历的时间。转换时间通常与ADC类型有关。双积分型ADC的转换时间一般为几十毫秒,属于低速ADC;逐次逼近型ADC的转换时间一般为几十微妙,属于中速ADC;并联比较型ADC的转换时间一般为几十纳秒,属于高速ADC。
转换精度:指ADC输出的数字量所表示的模拟值与实际输入的模拟量之间的偏差,通常为1个或半个最小数字量的模拟变化量,表示为1LSB或1/2LSB。
stm32的adc
框图
STM32F10x系列内部有三个12位逐次逼近型ADC,拥有多达18个通道,可测量16个外部模拟输入源和2个内部信号源的A/D转换。每个通道的A/D转换可采用单次、连续、扫描或间断模式执行。 ADC的的转换结果为12位的二进制数,可按左对齐或右对齐存储在16位数据寄存器中。 ADC具有模拟看门狗特性,允许应用程序检测输入电压是否超过用户自定义的阈值上限或下限

①电压输入范围

ADC 输入范围为: VREF- ≤ VIN ≤ VREF+。由 VREF-、 VREF+ 、 VDDA 、 VSSA、这四个外部引脚决定。引脚VDDA和VSSA为专门为模拟电路设计的独立电源,以过滤和屏蔽来自PCB上的毛刺和干扰。 ADC为提高转换精确度,使用VDDA和VSSA供电。一般把 VSSA 和 VREF- 接地,把 VREF+ 和 VDDA 接 3V3,得到 ADC 的输入电压范围为: 0~3.3V
②输入通道

电压怎么输入到 ADC?通过输入通道。ADCx_IN0~ADCx_IN15为ADC的输入信号通道,每个输入通道连接一个GPIO引脚。需要GPIO设置为对应模拟输入的复用模式,如下图为各ADC通道所对应引脚,STM32F103C8T6只有ADC1和ADC2。其中ADC1有两个内部通道:通道17连接内部参考电压VREFINT,通道16连接了芯片内部温度传感器
③ADC通道

当 ADC 的多个通道以任意顺序进行转换就诞生了成组转换,这里有两种成组转换类型:
规则组和注入组
规则通道组: 顾名思意,规则通道就是很规矩的意思,一般使用的就是这个通道。最多支持16个通道,在该组的ADC通道,根据序列寄存器SQRx( x=1~3)的配置顺序,依次转换。

如果转换通道 16 想第一个转换,那么在 SQ1[4:0] 写 16 即可。 SQR2 控制着规则序列中的第 7 到第 12 个转换,对应的位为: SQ7[4:0]~SQ12[4:0],如果转换通道 1 想第 8 个转换,则 SQ8[4:0] 写 1 即可,如果通道 6 想第 10 个转换,则SQ10[4:0] 写 6 即可。具体使用多少个通道,由 SQR1 的位 L[3:0] 决定。触 发 ADC 采 样 后 ,依次按规则通道序列的顺序采集
注入通道组: 可以理解为插入,插队的意思,是一种不安分的通道,类似中断,如果在规则通道转换过程中,有注入通道插队,那么就要先转换完注入通道,等注入通道转换完成后,再回到规则通道的转换流程,最多支持4个通道。如下图所示, JSQR控制通道顺序1~4,配置方法和规则组一样,当规则通道正在依次转换时, 可注入到转换序列中,优先转换。

如果 JL=00(1 个转换),那么转换的顺序是从JSQR4[4:0] 开始,而不是从 JSQR1[4:0] 开始,跟 SQR 刚好相反
④ADC触发

输入电压确定了,转换的顺序也设置好了,那接下来就该开始转换了。A/D转换需要触发信号才能开始工作,触发信号的产生方式通常有软件和外部触发。
软件触发:由软件编程控制,使能触发启动位;ADC 转换可以由 ADC 控制寄存器 2: ADC_CR2 的 ADON 这个位来控制,写 1 的时候开始转换,写 0 的时候停止转换
外部触发: 这个触发包括内部定时器触发和外部 IO 触发。触发源有很多,具体选择哪一种触发源,由 ADC 控制寄存器 2:ADC_CR2 的 EXTSEL[2:0]规则通道的触发源和JEXTSEL[2:0] 注入通道的触发源来控制。其中 ADC3 的规则转换和注入转换的触发源与 ADC1/2的有所不同,在框图上已经表示出来
⑤ADC中断

ADC在每个通道转换结束后,可产生相应的中断请求。
规则通道转换结束中断:
若ADC_CR1寄存器的EOCIE位被置1,注入通道或规则通道转换结束后,将产生EOC中断;
注入转换通道转换结束中断:
若ADC_CR1寄存器的JEOCIE位被置1,注入通道转换结束后,将产生JEOC中断;
模拟看门狗中断:
ADC 转换的模拟电压低于低阈值或者高于高阈值时,就会产生中断,若ADC_CR1寄存器的AWDIE位被置1。置高阈值是2.5V,超出阈值或低于阈值,将产生AWD中断。
⑥ADC数据

一切准备就绪后, ADC 转换后的数据根据转换组的不同,规则组的数据放在 ADC_DR 寄存器,注入组的数据放在 JDRx。
ADC转换的结果是一个12位的二进制数,而寄存器是16位的,因此涉及到数据对齐问题。 ADC对齐方式有左对齐和右对齐两种,通常使用右对齐方式,因为数据传输一般是从最低位开始(对应右边开始)。例如, 16位数据寄存器,数据采用右对齐方式,则转换的数据范围为0~212-1,即0~4095。ADC_CR2 的11 位 ALIGN 设置。
规则数据寄存器
寄存器 ADC_DR 只有一个,是一个 32 位的寄存器,低 16 位在单 ADC 时使用,高 16 位是在 ADC1 中双模式下保存 ADC2 转换的规则数据,双模式就是 ADC1 和 ADC2 同时使用。
规则通道可以有 16 个这么多,可规则数据寄存器只有一个,如果使用多通道转换,那转换的数据就全部都挤在了 DR 里面。所以当通道转换完成后就应该把数据取走,或者开启 DMA 模式,把数据传输到内存里面,不然就会造成数据的覆盖。最常用的做法就是开启 DMA 传输。注意,不是所有ADC的规则通道组转换结束后都能产生DMA请求,只有ADC1和ADC3能产生,ADC2转换数据可以在双ADC模式中使用ADC1的DMA请求。
注入数据寄存器
ADC 注入组最多有 4 个通道,刚好注入数据寄存器也有 4 个,每个通道对应着自己的寄存器,不会跟规则寄存器那样产生数据覆盖的问题。
⑦ADC时钟

根据《参考手册》可知,时钟频率最大72MHZ,一般设置PCLK2=HCLK=72M,ADC可以是 2/4/6/8 分频,ADC最大工作频率为14MHz,所以一般用72MHz/6分频=12MHz
采样时间
A/D转换在采样时信号需要保持一段时间,采样时间越长,转换结果越稳定,但转换速率也就越慢。STM32的ADC每个通道的采样时间都可以进行设置,可设置为采样周期的1.5倍、 7.5倍、 13.5倍、 28.5倍、41.5倍、 55.5倍、 71.5倍或239.5倍,如果要达到最快的采样,那么应该设置采样周期为 1.5 个周期,这里说的周期就是 1/ADC_CLK。 ADC转换总时间可以表示为:
ADC的四种转换模式
单次模式: ADC只执行一次转换;
连续模式:当前ADC转换结束后,立即进入下一个转换;
扫描模式:用来扫描一组通道。通道可以来自规则通道组,也可来自注入通道组。开启扫描模式后,ADC将自动扫描该组所有通道,如此时转换模式设置为单次转换,则扫描本组所有通道后, ADC自动停止;若将转换模式设置为连续模式,则在扫描本组所有通道后,再从第一个通道开始扫描;
间断模式:用来间歇转换一组通道。通道可以来自规则通道组,也可来自注入通道组。假设该组包含0、 1、 2、 3、 5、 6、 7、 8,共8个通道,而设置转换通道数为3,则第一次触发,转换0、 1、 2通道;第二次触发,转换3、 5、 6通道;第三次触发,转换7、 8通道,并产生EOC中断;
hal库代码
// ADC 通道宏定义
#define ADC_IN_CHANNEL ADC_CHANNEL_16ADC_HandleTypeDef hadc1;
DMA_HandleTypeDef hdma;/*初始化ADC1的参数:触发方式、数据格式、转换模式,通道配置及其采样时间*/
void adc1_in_16_init(void)
{ADC_ChannelConfTypeDef sconfig;hadc1.Instance = ADC1;hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;/*选择ADC采集到的数据对齐格式,这里设置为右对齐*/hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;/* 失能ADC的扫描模式,只涉及一个ADC,无需对通道组进行扫描;*/hadc1.Init.ContinuousConvMode = DISABLE;/*失能ADC连续转换模式,不需要该ADC连续转换,只采集一次*/hadc1.Init.NbrOfConversion = 1;/*使能ScanConvMode的情况下, 用于设置规则通道转换序列数,因为扫描模式被禁用,所以ADC只会执行单个通道的转换。*/hadc1.Init.DiscontinuousConvMode = DISABLE;/*失能规则组转换序列的间断模式,不需要间断扫描;*/hadc1.Init.NbrOfDiscConversion = 1;/*通道间转换次数。在启用间断转换模式的情况下,这个值表示在一个转换序列中,ADC会在多少个通道之间进行转换。在这里设定为1,表示ADC会在一个通道上进行一次转换*/hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;/*外部触发源的选择(软件触发ADC采样)*/HAL_ADC_Init(&hadc1);sconfig.Channel = ADC_IN_CHANNEL;/*设置ADC(模数转换器)的输入通道*/sconfig.Rank = ADC_REGULAR_RANK_1;/*放在规则通道组的第一个转换位置*/sconfig.SamplingTime = ADC_SAMPLETIME_7CYCLES_5;/*采样时间*/HAL_ADC_ConfigChannel(&hadc1,&sconfig);HAL_ADCEx_Calibration_Start(&hadc1);/*启动ADC的校准过程*/
}void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};/*配置的外设时钟选择为ADC外设*/PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;/* 选择 ADC 时钟源 72MHz/6=12MHz*/PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);if(hadc->Instance == ADC1){__HAL_RCC_ADC1_CLK_ENABLE(); // 使能ADC1的时钟}
}
标准库代码
// ADC GPIO宏定义
// 注意:用作ADC采集的IO必须没有复用,否则采集电压会有影响
#define ADC_PORT GPIOB
#define ADC_PIN GPIO_Pin_0// ADC 通道宏定义
#define ADC_CHANNEL ADC_Channel_8void ad_config(void)
{ADC_APBxClock_FUN(ADC_CLK,ENABLE);/*规则组的 输入通道,序列、采样时间,这里采样时间为55.5个周期*/ADC_RegularChannelConfig(ADC1,ADC_CHANNEL,1,ADC_SampleTime_1Cycles5);ADC_InitTypeDef ADC_InitStruct;ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;/*独立模式*/ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;/*数据右对齐*/ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;/*不使用外部触发,内部软件触发*/ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;/*连续enable或单次disable*/ADC_InitStruct.ADC_ScanConvMode = DISABLE;/*enable扫描或非扫描disable*/ADC_InitStruct.ADC_NbrOfChannel = 1;/*扫描模式下用的几个通道1-16,非扫描只有序列第一个有校*/ADC_Init(ADCx,&ADC_InitStruct);ADC_Cmd(ADCx, ENABLE);/*手册建议上电后要校准*/ADC_ResetCalibration(ADCx);/*开始复位校准*/while(ADC_GetResetCalibrationStatus(ADCx));/*等待复位完成标志位,0表示复位校准完成*/ADC_StartCalibration(ADCx);/*开始校准*/while(ADC_GetCalibrationStatus(ADCx));/*完成标志位*/
}void ad_init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);/*adc clk时钟配置,6分频:adcclk = 72mhz/6 = 12mhz*/RCC_ADCCLKConfig(RCC_PCLK2_Div6);GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;/*模拟输入*/GPIO_InitStruct.GPIO_Pin = ADC_PIN;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(ADC_PORT,&GPIO_InitStruct);ad_config();
}
相关文章:
stm32 ADC
目录 简介 stm32的adc 框图 ①电压输入范围 ②输入通道 编辑③ADC通道 ④ADC触发 ⑤ADC中断 ⑥ADC数据 ⑦ADC时钟 ADC的四种转换模式 hal库代码 标准库代码 简介 自然界的信号几乎都是模拟信号,比如光亮、温度、压力、声音,而为了方便存储、…...
linux网络服务综合项目
前期环境配置 #主要写了192.168.146.130的代码,131的配置代码和其一样 [rootserver ~]# nmtui #通过图形化界面修改ens160的ip 192.168.146.130 [rootserver ~]# hostnamectl set-hostname Server-Web #修改130主机名…...
每日一题(LeetCode)----数组--移除元素(三)
每日一题(LeetCode)----数组–移除元素(三) 1.题目([283. 移动零](https://leetcode.cn/problems/sqrtx/)) 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。 请…...
AI:57-基于机器学习的番茄叶部病害图像识别
🚀 本文选自专栏:AI领域专栏 从基础到实践,深入了解算法、案例和最新趋势。无论你是初学者还是经验丰富的数据科学家,通过案例和项目实践,掌握核心概念和实用技能。每篇案例都包含代码实例,详细讲解供大家学习。 📌📌📌在这个漫长的过程,中途遇到了不少问题,但是…...
人工智能-深度学习计算:层和块
我们关注的是具有单一输出的线性模型。 在这里,整个模型只有一个输出。 注意,单个神经网络 (1)接受一些输入; (2)生成相应的标量输出; (3)具有一组相关 参数…...
Linux第一个小程序进度条
缓冲区 在写进度条程序之前我们需要介绍一下缓冲区,缓冲区有两种,输入和输出缓冲区,这里主要介绍输出缓冲区。在我们用C语言写代码时,输出一些信息,实际上是先输出到输出缓冲区里,然后才输出到我们的显…...
JavaEE平台技术——预备知识(Maven、Docker)
JavaEE平台技术——预备知识(Maven、Docker) 1. Maven2. Docker 在观看这个之前,大家请查阅前序内容。 😀JavaEE的渊源 😀😀JavaEE平台技术——预备知识(Web、Sevlet、Tomcat) 1. M…...
【ChatOCR】OCR+LLM定制化关键信息抽取(附开源大语言模型汇总整理)
目录 背景技术方案存在的问题及解决思路关键信息提取结果其他解决方案替换文心一言LangChain大型多模态模型(Large Multimodal Model, LMM) 开源大模型汇总LLaMA —— Meta 大语言模型Stanford Alpaca —— 指令调优的 LLaMA 模型Lit-LLaMA —— 基于 na…...
【位运算】XOR Construction—CF1895D
XOR Construction—CF1895D 参考文章 翻译 题目要求构造一个长度为 n n n 的数组 b b b,满足以下条件: 数组 b b b 中包含从 0 0 0 到 n − 1 n-1 n−1 的每个整数,且每个整数仅出现一次;对于 i i i 从 1 1 1 到 n − …...
解决Visual Studio Code 控制台中文乱码问题
C和CPP运行编码指定 "code-runner.executorMap": {"c": "cd $dir && gcc -fexec-charsetGBK $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt","cpp": "cd $dir && g -fexec-charsetGBK $…...
React Native自学笔记
系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 例如:第一章 Python 机器学习入门之pandas的使用 提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目…...
程序员笔记本电脑选 windows 还是 MAC
计算机选择是每个进入 IT 行业同学的第一个重要选择,那么你是怎么选择的呢? 选择操作系统(Windows还是macOS)取决于程序员的需求、偏好和工作流程。每个操作系统都有其优点和缺点,下面将分别讨论它们,以帮助…...
蓝桥杯每日一题2023.11.5
题目描述 方格分割 - 蓝桥云课 (lanqiao.cn) 题目分析 对于每个图我们可以从中间开始搜索,如果到达边界点就说明找到了一种对称的方法,我们可以直接对此进行答案记录每次进行回溯就会找到不同的图像,如果是一样的图像则算一种情况ÿ…...
多媒体应用设计师 2023年(含答案回忆版)
以下是小红书上的回忆版 软考考完疯狂回忆,多媒体应用设计师选择题 1.pattern 2.effective 3.merge 4.applications 5.graphic 6.udp 7.rtp 8.rtsp 9.10cm 10.永久 11…97 12.工作技术管理标准 13.管理型元数据 14.premiere 15.wave 16.500km/h 17.3M 18.44000 19.…...
[Machine Learning][Part 8]神经网络的学习训练过程
目录 训练过程 一、建立模型: 二、建立损失函数 J(w,b): 三、寻找最小损失函数的(w,b)组合 为什么需要激活函数 激活函数种类 二分法逻辑回归模型 线性回归模型 回归模型 训练过程 一、建立模型: 根据需求建立模型,从前面神经网络的…...
Git 内容学习
一、Git 的理解 Git是一个分布式版本控制系统(Distributed Version Control System,简称 DVCS),用于对项目源代码进行管理和跟踪变更。分为两种类型的仓库:本地仓库和远程仓库。 二、Git 的工作流程 详解如下&#x…...
Zookeeper3.7.1分布式安装部署
上传安装文件到linux系统上面 解压安装文件到安装目录 [zhangflink9wmwtivvjuibcd2e package]$ tar -zxvf apache-zookeeper-3.7.1-bin.tar.gz -C /opt/software/3. 修改解压文件名 [zhangflink9wmwtivvjuibcd2e software]$ mv apache-zookeeper-3.7.1-bin/ zookeeper-3.7…...
CSS必学:元素之间的空白与行内块的幽灵空白问题
作者:WangMin 格言:努力做好自己喜欢的每一件事 CSDN原创文章 博客地址 👉 WangMin 我们在开发的过程中,难免会出现一些难以预料的问题。那么其中,CSS空白现象就是非常常见的问题之一。虽然它已经被发现很久,但仍然有许多新手和经…...
C++类中对构造函数的重载
C类中对构造函数的重载 C 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载。 重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它们的参数列表和定义(实现)不…...
QtC++与QLabel详解
介绍 QLabel 类是Qt中的一个用于显示文本或图像的控件类,通常用于用户界面中以提供静态文本或图片显示的功能。以下是对QLabel在Qt中的作用的详细解释: 文本和图像显示: QLabel 可以用来显示文本和图像。这使得它成为显示标签、标题、说明或…...
调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...
React Native 导航系统实战(React Navigation)
导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...
黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...
MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...
并发编程 - go版
1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...
关于easyexcel动态下拉选问题处理
前些日子突然碰到一个问题,说是客户的导入文件模版想支持部分导入内容的下拉选,于是我就找了easyexcel官网寻找解决方案,并没有找到合适的方案,没办法只能自己动手并分享出来,针对Java生成Excel下拉菜单时因选项过多导…...
