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

STM32-ADC模数转换器

目录

一、ADC简介

二、逐次逼近型ADC内部结构

三、STM32内部ADC转换结构

四、ADC基本结构

五、输入通道

六、转换模式

6.1单次转换,非扫描模式

6.2连续转换,非扫描模式

6.3单次转换,扫描模式

6.4连续转换,扫描模式

七、触发控制

​编辑

八、数据对齐

九、转换时间

十、硬件电路

十一、开发步骤

十二、ADC库函数

十三、实验

13.1 AD单通道

13.2 AD多通道


一、ADC简介

>ADC(Analog-Digital Converter)模拟-数字转换器
>ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量,建立模拟电路到数字电路的桥梁
>12位逐次逼近型ADC(表示范围:0-2^12-1(4095)),1us转换时间(频率:1MHz)      
>输入电压范围:0~3.3V,转换结果范围:0~4095
>18个输入通道,可测量16个外部和2个内部信号源
>规则组和注入组两个转换单元
>模拟看门狗自动监测输入电压范围

>STM32F103C8T6 ADC资源:ADC1、ADC2,10个外部输入通道

二、逐次逼近型ADC内部结构

三、STM32内部ADC转换结构

ADCCLK来源于APB2

四、ADC基本结构

五、输入通道

六、转换模式

6.1单次转换,非扫描模式

6.2连续转换,非扫描模式

6.3单次转换,扫描模式

6.4连续转换,扫描模式

七、触发控制

八、数据对齐

(一般采用右对齐,读出来的数据直接就是结果)

九、转换时间

①AD转换的步骤:采样,保持,量化,编码

②STM32 ADC的总转换时间为:
    TCONV = 采样时间 + 12.5个ADC周期(12位)

例如:当ADCCLK=14MHz,采样时间为1.5个ADC周期
    TCONV = 1.5 + 12.5 = 14个ADC周期 = 1μs

十、硬件电路

十一、开发步骤

①开启RCC时钟,包括ADC和GPIO,ADCCLK的分频器也要配置

②配置GPIO,模拟输入模式

③配置多路开关,将通道接入规则组列表中

④结构体配置ADC转换器(单次/多次、扫描/非扫描、通道数、触发源、数据对齐方式)

(可选)⑤模拟看门狗,配置阈值和监测通道,开启中断ITConfig,NVIC

⑤开关控制,调用ADC_Cmd函数,开启ADC,校准

十二、ADC库函数

/*rcc.h*/

void RCC_ADCCLKConfig(uint32_t RCC_PCLK2);

作用:配置ADCCLK分频器

/*adc.h*/

void ADC_DeInit(ADC_TypeDef* ADCx);//恢复缺省配置
void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);//Init初始化
void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct);//StructInit结构体初始化

void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);//使能ADC

void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState);//开启DMA输出信号

void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState);//中断输出控制

============================控制校准的函数=============================
void ADC_ResetCalibration(ADC_TypeDef* ADCx);//复位校准
FlagStatus ADC_GetResetCalibrationStatus(ADC_TypeDef* ADCx);//获取复位校准状态
void ADC_StartCalibration(ADC_TypeDef* ADCx);//开始校准
FlagStatus ADC_GetCalibrationStatus(ADC_TypeDef* ADCx);//获取开始校准状态

=====================================================================

void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);

//ADC_软件开始转换控制,用于软件触发的函数(重要)
FlagStatus ADC_GetSoftwareStartConvStatus(ADC_TypeDef* ADCx);

//ADC获取软件开始转换状态(一般不用)

============================间断模式==================================
void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number);

//每隔几个通道间断一次
void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState);

//是不是启用间断模式

=====================================================================
void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);

//ADC规则组通道配置

参数:

①ADCx

②ADC_Channel,通道

③Rank,序列几的位置

④ADC_SampleTime,指定通道的采样时间

=====================================================================
void ADC_ExternalTrigConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);

//ADC_外部触发转换控制,是否允许外部触发转换

=====================================================================
uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx);

//ADC获取转换值(重要)

=====================================================================
uint32_t ADC_GetDualModeConversionValue(void);

//ADC_获取双模式转换值
============================模拟看门狗=================================

void ADC_AnalogWatchdogCmd(ADC_TypeDef* ADCx, uint32_t ADC_AnalogWatchdog);

//是否启动模拟看门狗
void ADC_AnalogWatchdogThresholdsConfig(ADC_TypeDef* ADCx, uint16_t HighThreshold, uint16_t LowThreshold);

//配置高低阈值
void ADC_AnalogWatchdogSingleChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel);

//配置看门的通道

===============================内部两通道==============================

void ADC_TempSensorVrefintCmd(FunctionalState NewState);

//ADC_温度传感器、内部参考电压控制

=============================标志位===================================

FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);

//获取标志位状态
void ADC_ClearFlag(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);

//清除标志位
ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint16_t ADC_IT);

//获取中断状态
void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint16_t ADC_IT);

//清除中断挂起位状态

十三、实验

13.1 AD单通道

实验现象:用电位器产生一个0~3.3V连续变化的模拟电压信号,接到PA0,ADC读取数据显示到屏幕上

参考代码:

AD.c

#include "stm32f10x.h"                  // Device header//*本例程使用连续非扫描模式,软件触发一次即可*//
void AD_Init(void)
{/*一、开启RCC时钟(ADC,GPIO)*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//ADCCLK分频RCC_ADCCLKConfig(RCC_PCLK2_Div6);//72MHz/6=12MHz/*二、配置GPIO,模拟输入*/GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);/*三、配置多路开关,左边通道接入右边规则组列表(选择规则组的注入通道)*/ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);/*四、配置ADC转换器*/ADC_InitTypeDef ADC_InitStructure;ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//工作模式(独立/双ADC)ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//数据对齐(左/右)ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//触发源,此处使用软件触发ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//连续转换/单次转换ADC_InitStructure.ADC_ScanConvMode = DISABLE;//扫描/非扫描ADC_InitStructure.ADC_NbrOfChannel = 1;ADC_Init(ADC1,&ADC_InitStructure);//扫描模式下用到几个通道/*五、开关控制,开启ADC*/ADC_Cmd(ADC1,ENABLE);   //校准ADC_ResetCalibration(ADC1);//复位校准while(ADC_GetResetCalibrationStatus(ADC1) == SET);//等待复位校准完成ADC_StartCalibration(ADC1);//启动校准while(ADC_GetCalibrationStatus(ADC1) == SET);//等待校准是否完成ADC_SoftwareStartConvCmd(ADC1,ENABLE);
}uint16_t AD_GetValue(void)
{return ADC_GetConversionValue(ADC1);
}

AD.h

#ifndef __AD_H
#define __AD_Hvoid AD_Init(void);
uint16_t AD_GetValue(void);#endif

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "AD.h"uint16_t ADValue;//AD值
float Voltage;//电压值int main(void)
{OLED_Init();AD_Init();OLED_ShowString(1,1,"ADValue:");OLED_ShowString(2,1,"Voltage:0.00V");while (1){ADValue = AD_GetValue();Voltage = (float)ADValue/4095*3.3;OLED_ShowNum(1,9,ADValue,4);OLED_ShowNum(2,9,Voltage,1);//整数OLED_ShowNum(2,11,(uint16_t)(Voltage*100)%100,2);//小数部分Delay_ms(100);}
}

*OLED代码参考本专栏文章STM32-OLED

13.2 AD多通道

实验设置:将电位器、光敏电阻、热敏电阻、反射红外模块的AO(模拟电压输出端)分别接到PA0/PA1/PA2/PA3

参考代码:

AD.c

#include "stm32f10x.h"                  // Device header//*本例程使用单次非扫描模式*//
void AD_Init(void)
{/*一、开启RCC时钟(ADC,GPIO)*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//ADCCLK分频RCC_ADCCLKConfig(RCC_PCLK2_Div6);//72MHz/6=12MHz/*二、配置GPIO,模拟输入*/GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);/*四、配置ADC转换器*/ADC_InitTypeDef ADC_InitStructure;ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;ADC_InitStructure.ADC_ScanConvMode = DISABLE;ADC_InitStructure.ADC_NbrOfChannel = 1;ADC_Init(ADC1,&ADC_InitStructure);/*五、开关控制,开启ADC*/ADC_Cmd(ADC1,ENABLE);   //校准ADC_ResetCalibration(ADC1);//复位校准while(ADC_GetResetCalibrationStatus(ADC1) == SET);//等待复位校准完成ADC_StartCalibration(ADC1);//启动校准while(ADC_GetCalibrationStatus(ADC1) == SET);}uint16_t AD_GetValue(uint8_t ADC_Channel)
{/*三、配置多路开关,左边通道接入右边规则组列表(选择规则组的注入通道)*/ADC_RegularChannelConfig(ADC1,ADC_Channel,1,ADC_SampleTime_55Cycles5);ADC_SoftwareStartConvCmd(ADC1,ENABLE);while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == RESET);//通过标志位来查看是否转换完成return ADC_GetConversionValue(ADC1);
}

AD.h

#ifndef __AD_H
#define __AD_Hvoid AD_Init(void);
uint16_t AD_GetValue(uint8_t ADC_Channel);#endif

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "AD.h"uint16_t AD0,AD1,AD2,AD3;int main(void)
{OLED_Init();AD_Init();OLED_ShowString(1,1,"AD0:");OLED_ShowString(2,1,"AD1:");OLED_ShowString(3,1,"AD2:");OLED_ShowString(4,1,"AD3:");while (1){AD0 = AD_GetValue(ADC_Channel_0);AD1 = AD_GetValue(ADC_Channel_1);AD2 = AD_GetValue(ADC_Channel_2);AD3 = AD_GetValue(ADC_Channel_3);OLED_ShowNum(1,5,AD0,5);OLED_ShowNum(2,5,AD1,5);OLED_ShowNum(3,5,AD2,5);OLED_ShowNum(4,5,AD3 ,5);Delay_ms(100);}
}

相关文章:

STM32-ADC模数转换器

目录 一、ADC简介 二、逐次逼近型ADC内部结构 三、STM32内部ADC转换结构 四、ADC基本结构 五、输入通道 六、转换模式 6.1单次转换,非扫描模式 6.2连续转换,非扫描模式 6.3单次转换,扫描模式 6.4连续转换,扫描模式 七、…...

谷歌手机安装证书到根目录

1、前提你已经root,安装好面具 2,下载movecert模块,自动帮你把证书从用户证书移动成系统证书 视频教程,手机为谷歌手机 https://www.bilibili.com/video/BV1pG4y1A7Cj?p11&vd_source9c0a32b00d6d59fecae05b4133f22f06 软件下…...

代码随想录 322. 零钱兑换

题目 给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。 计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。 你可以认为每种硬币的数量是无限的。…...

【图的应用二:最短路径】- 用 C 语言实现迪杰斯特拉算法和弗洛伊德算法

目录 一、最短路径 二、迪杰斯特拉算法 三、弗洛伊德算法 一、最短路径 假若要在计算机上建立一个交通咨询系统,则可以采用图的结构来表示实际的交通网络。如下图所示,图中顶点表示城市,边表示城市间的交通联系。 这个咨询系统可以回答旅…...

Qt之判断一个点是否在多边形内部(射线法)

算法思想: 以被测点Q为端点,向任意方向作射线(一般水平向右作射线),统计该射线与多边形的交点数。如果为奇数,Q在多边形内;如果为偶数,Q在多边形外。计数的时候会有一些特殊情况。这种方法适用于任意多边形,不需要考虑精度误差和多边形点给出的顺序,时间复杂度为O(n)…...

压力测试过程中内存溢出(堆溢出、栈溢出、持久代溢出)情况如何解决

在压力测试过程中,可能会遇到内存溢出的问题,其中常见的包括堆内存溢出、栈内存溢出和持久代溢出。解决这类问题需要首先理解各种内存溢出的原因和特点。 堆内存溢出:这种情况通常发生在稳定性压测一段时间后,系统报错&#xff0…...

【工业智能】音频信号相关场景

【工业智能】音频信号相关场景 DcaseDcase introduction:dcase2024有10个主题的任务: ASD硬件设备产品商 方法制造业应用场景 zenodo音频事件检测 与计算机视觉CV相对应,计算机听觉computer audition,简称CA。 Dcase 这里推荐一个…...

(PC+WAP)装修设计公司网站模板 家装公司网站源码下载

(PCWAP)装修设计公司网站模板 家装公司网站源码下载 PbootCMS内核开发的网站模板,该模板适用于装修设计、家装公司类等企业,当然其他行业也可以做,只需要把文字图片换成其他行业的即可; PCWAP,同一个后台&#xff0c…...

使用opencv实现图像中几何图形检测

1 几何图形检测介绍 1.1 轮廓(contours) 什么是轮廓,简单说轮廓就是一些列点相连组成形状、它们拥有同样的颜色、轮廓发现在图像的对象分析、对象检测等方面是非常有用的工具,在OpenCV 中使用轮廓发现相关函数时候要求输入图像是二值图像,这…...

补题与周总结:leetcode第 376 场周赛

文章目录 复盘与一周总结2967. 使数组成为等数数组的最小代价(中位数贪心 回文数判断)2968. 执行操作使频率分数最大(中位数贪心 前缀和 滑窗) 复盘与一周总结 wa穿了第3题,赛时其实想到了思路:中位数贪心…...

js指纹库,可跟踪用户唯一性

fingerprintjs官网 资料: Browserleaks - Check your browser for privacy leaks...

Shell三剑客:awk(内部变量)

一、$0 :完整的输入记录 [rootlocalhost ~]# awk -F: {print $0} passwd.txt root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/s…...

JVM中的虚拟机栈的动态链接部分存放到底是什么

在Java虚拟机(JVM)中,每个线程在执行一个方法时都会创建一个栈帧(Stack Frame),栈帧中包含了方法的运行时数据。栈帧通常包括局部变量表、操作数栈、动态链接、方法返回地址等部分。 动态链接 动态链接&a…...

Leetcode 55 跳跃游戏

题意理解: 非负整数数组 nums, 最初位于数组的 第一个下标 。 数组中的每个元素代表你在该位置可以跳跃的最大长度。 需要跳到nums最后一个元素即为成功。 目标:是否能够跳到最后一个元素。 解题思路: 使用贪心算法来解题,需要理解…...

构建陪诊预约系统:技术实战指南

在医疗科技的飞速发展中,陪诊预约系统的应用为患者和陪诊人员提供了更为便捷和贴心的服务。本文将带领您通过技术实现,构建一个简单而实用的陪诊预约系统,以提升医疗服务的效率和用户体验。 技术栈选择 在开始之前,我们需要选择…...

windows和linux将文件删除至回收站【C++】【Go】语言实现

目录 C Windows平台 Linux平台 开平台,代码合并 Go 实现步骤 Go语言实现示例 go单独的windows版本实现 代码解释 C 在C中,将文件移动到回收站的实现在Linux和Windows平台上是不同的。首先,我会为你提供在Windows平台上实现的代码示例…...

10 Vue3中v-html指令的用法

概述 v-html主要是用来渲染富文本内容,比如评论信息,新闻信息,文章信息等。 v-html是一个特别不安全的指令,因为它会将文本以HTML的显示进行渲染,一旦文本里面包含一些恶意的js代码,可能会导致整个网页发…...

华为数通方向HCIP-DataCom H12-831题库(多选题:181-200)

第181题 如图所示,R1、R2、R3、R4都部署为SPF区域0,链路的cost值如图中标识。R1、R2R3、R4的Loopback0通告入OSPF。R1、R2、R3与R4使用Loopback0作为连接接口,建立BGP对等体关系,其中R4为RR设备,R1、R2、R3是R4的客户端。当R4的直连地址172.20,1,4/32通告入BGP后,以下关R…...

DC-磁盘管理

2023年全国网络系统管理赛项真题 模块B-Windows解析 题目 在DC2上安装及配置软RAID 5。在安装好的DC2虚拟机中添加三块10G虚拟磁盘。组成RAID 5,磁盘分区命名为卷标H盘:Raid5。手动测试破坏一块磁盘,做RAID磁盘修复,确认RAID 5配置完毕。配置步骤 关闭虚拟机,添加3块10G磁…...

使用Docker运行镜像文件与设置端口

1&#xff0c;创建镜像文件前准备 # 使用基础镜像FROM alpine:latest# 设置工作目录WORKDIR /app# 复制应用程序文件到镜像中COPY . .# 暴露容器的端口 不会自动将容器的端口映射到宿主机上 docker run -d -p <宿主机端口>:7080 <镜像名称>EXPOSE 7080# 定义容器启…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…...

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…...

linux之kylin系统nginx的安装

一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源&#xff08;HTML/CSS/图片等&#xff09;&#xff0c;响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址&#xff0c;提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

Java 8 Stream API 入门到实践详解

一、告别 for 循环&#xff01; 传统痛点&#xff1a; Java 8 之前&#xff0c;集合操作离不开冗长的 for 循环和匿名类。例如&#xff0c;过滤列表中的偶数&#xff1a; List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

渲染学进阶内容——模型

最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

现代密码学 | 椭圆曲线密码学—附py代码

Elliptic Curve Cryptography 椭圆曲线密码学&#xff08;ECC&#xff09;是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础&#xff0c;例如椭圆曲线数字签…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域&#xff0c;高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表&#xff0c;以及基于它们实现的 Reactor 模式&#xff0c;为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...