当前位置: 首页 > 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# 定义容器启…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

华为OD机试-食堂供餐-二分法

import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec&#xff1f; IPsec VPN 5.1 IPsec传输模式&#xff08;Transport Mode&#xff09; 5.2 IPsec隧道模式&#xff08;Tunne…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)

本期内容并不是很难&#xff0c;相信大家会学的很愉快&#xff0c;当然对于有后端基础的朋友来说&#xff0c;本期内容更加容易了解&#xff0c;当然没有基础的也别担心&#xff0c;本期内容会详细解释有关内容 本期用到的软件&#xff1a;yakit&#xff08;因为经过之前好多期…...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

React---day11

14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store&#xff1a; 我们在使用异步的时候理应是要使用中间件的&#xff0c;但是configureStore 已经自动集成了 redux-thunk&#xff0c;注意action里面要返回函数 import { configureS…...