STM32-ADC模数转换

目录

1.0 逐次逼近型ADC

2.0 ADC触发

3.0 ADC时钟

4.0 转换模式

5.0 转换时间

6.0 校准

7.0 硬件电路

8.0 数据手册

9.0 程序实现

9.0.1 时钟初始化

9.0.2 GPIO结构体初始化

9.0.3 ADC结构体初始化

9.0.4 ADC转换

9.0.5 AD初始化

9.0.6 获取ADC值

9.0.7 ADC头文件

9.0.8 MAIN函数

10.0 AD多通道

10.0.1 RCC时钟初始化

10.0.2 GPIO初始化

10.0.3 ADC结构体初始化

10.0.4 头文件

10.0.5 主函数文件


定义:


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

注:单片机内部将采集到的模拟信号转换为单片机可以识别的数组信号


1.0 逐次逼近型ADC




2.0 ADC触发


ADC的触发方式有两种一种是软件的触发方式,一种是硬件的促发方式,ADC的硬件结构如下图所示:


3.0 ADC时钟


外部通道对应的GPIOA口对应引脚,ADC1和ADC2的引脚是相同的,还有双ADC模式,以下是通道和引脚的转换关系,以及对应的引脚关系图。


4.0 转换模式







二进制的特定:将数据左移一次相当于是把数据X2也就是扩大了一倍,左移了4次就相当于把结果X16,一般是选择右对齐。 


5.0 转换时间


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

ADC的总转换时间为:     TCONV = 采样时间【采样,保持】 + 12.5个ADC周期【量化,编码

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


6.0 校准


ADC有一个内置自校准模式。校准可大幅减小因内部电容器组的变化而造成的准精度误差。校准期间,在每个电容器上都会计算出一个误差修正码(数字值),这个码用于消除在随后的转换中每个电容器上产生的误差

建议在每次上电后执行一次校准 启动校准前, ADC必须处于关电状态超过至少两个ADC时钟周期


7.0 硬件电路



8.0 数据手册

......


9.0 程序实现


9.0.1 时钟初始化

	// RCC开启ADC时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);// RCC开启GPIO时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);// 设置ADC时钟,分频系数是6分频RCC_ADCCLKConfig(RCC_PCLK2_Div6);

9.0.2 GPIO结构体初始化

	// 初始化GPIOGPIO_InitTypeDef GPIO_InitStruct;// GPIO_Mode_AIN 模拟输入模式,该模数下所有的GPIO口无效GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStruct);

9.0.3 ADC结构体初始化

	// 配置规则组通道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 数据对齐模式ADC_InitStructure.ADC_ExternalTrigConv 	 = ADC_ExternalTrigConv_None; // ADC 触发模式ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;					  // 转换模式是单次转换还是连续

9.0.4 ADC转换

	ADC_InitStructure.ADC_ScanConvMode       = DISABLE;					  // 扫描模式ADC_InitStructure.ADC_NbrOfChannel 		 = 1;						  // 指定ADC转换的通道数目// ADC 结构体初始化ADC_Init(ADC1, &ADC_InitStructure);									  // 初始化ADC结构体// 使能ADCADC_Cmd(ADC1, ENABLE);// ADC 校准ADC_ResetCalibration(ADC1);// 获取ADC校准寄存器的状态while (ADC_GetResetCalibrationStatus(ADC1) == SET);ADC_StartCalibration(ADC1);// 等待校准是否完成while (ADC_GetCalibrationStatus(ADC1) == SET);

9.0.5 AD初始化


// AD 初始化函数
void AD_Init(void)
{// RCC开启ADC时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);// RCC开启GPIO时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);// 设置ADC时钟,分频系数是6分频RCC_ADCCLKConfig(RCC_PCLK2_Div6);// 初始化GPIOGPIO_InitTypeDef GPIO_InitStruct;// GPIO_Mode_AIN 模拟输入模式,该模数下所有的GPIO口无效GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStruct);// 配置规则组通道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 数据对齐模式ADC_InitStructure.ADC_ExternalTrigConv 	 = ADC_ExternalTrigConv_None; // ADC 触发模式ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;					  // 转换模式是单次转换还是连续转换ADC_InitStructure.ADC_ScanConvMode       = DISABLE;					  // 扫描模式ADC_InitStructure.ADC_NbrOfChannel 		 = 1;						  // 指定ADC转换的通道数目// ADC 结构体初始化ADC_Init(ADC1, &ADC_InitStructure);									  // 初始化ADC结构体// 使能ADCADC_Cmd(ADC1, ENABLE);// ADC 校准ADC_ResetCalibration(ADC1);// 获取ADC校准寄存器的状态while (ADC_GetResetCalibrationStatus(ADC1) == SET);ADC_StartCalibration(ADC1);// 等待校准是否完成while (ADC_GetCalibrationStatus(ADC1) == SET);}

9.0.6 获取ADC值

// 获取ADC的值
uint16_t AD_GetValue(void)
{// 软件触发AD转换ADC_SoftwareStartConvCmd(ADC1, ENABLE);// reset 转换未完成while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);return ADC_GetConversionValue(ADC1);
}

9.0.7 ADC头文件


#ifndef __AD_H_
#define __AD_H_void AD_Init(void);
uint16_t AD_GetValue(void);#endif

9.0.8 MAIN函数


#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();			//OLED初始化AD_Init();				//AD初始化/*显示静态字符串*/OLED_ShowString(1, 1, "ADValue:");OLED_ShowString(2, 1, "Voltage:0.00V");while (1){ADValue = AD_GetValue();					//获取AD转换的值Voltage = (float)ADValue / 4095 * 3.3;		//将AD值线性变换到0~3.3的范围,表示电压OLED_ShowNum(1, 9, ADValue, 4);				//显示AD值OLED_ShowNum(2, 9, Voltage, 1);				//显示电压值的整数部分OLED_ShowNum(2, 11, (uint16_t)(Voltage * 100) % 100, 2);	//显示电压值的小数部分Delay_ms(100);			//延时100ms,手动增加一些转换的间隔时间}
}

10.0 AD多通道


10.0.1 RCC时钟初始化

时钟初始化:开启RCC与ADC时钟,ADC时钟控制设置为6分频

	// RCC开启时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);// ADC时钟初始化RCC_ADCCLKConfig(RCC_PCLK2_Div6);

10.0.2 GPIO初始化

GPIO结构体初始化,分别设置引脚,模式,时钟频率

	// 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);

10.0.3 ADC结构体初始化

    // ADC初始化ADC_InitTypeDef ADC_InitStructure;// ADC模式为独立模式ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;// 数据对齐,对齐方式为右对齐ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;// 触发方式,内部软件触发ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;// ADC是否使用连续转换模式,此处每转换一次规则组转换方式失能ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;// 扫描模式,失能,只转换规则组的序列1这一个位置ADC_InitStructure.ADC_ScanConvMode = DISABLE;// 通道数,为1,仅在扫描模式下,才需要指定大于1的数,在非扫描模式下,只能是1ADC_InitStructure.ADC_NbrOfChannel = 1;// 将结构体变量交给ADC_Init,配置ADC1ADC_Init(ADC1, &ADC_InitStructure);

ADC使能与校准

	// 使能ADC1,ADC开始运行ADC_Cmd(ADC1, ENABLE);/*ADC校准*/ADC_ResetCalibration(ADC1); 	// 固定流程,内部有电路会自动执行校准while (ADC_GetResetCalibrationStatus(ADC1) == SET);ADC_StartCalibration(ADC1);while (ADC_GetCalibrationStatus(ADC1) == SET);

 ADC结构体初始化

/*** 函    数:获取AD转换的值* 参    数:ADC_Channel 指定AD转换的通道,范围:ADC_Channel_x,其中x可以是0/1/2/3* 返 回 值:AD转换的值,范围:0~4095*/
uint16_t AD_GetValue(uint8_t ADC_Channel)
{ADC_RegularChannelConfig(ADC1, ADC_Channel, 1, ADC_SampleTime_55Cycles5);	//在每次转换前,根据函数形参灵活更改规则组的通道1ADC_SoftwareStartConvCmd(ADC1, ENABLE);					//软件触发AD转换一次while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);	//等待EOC标志位,即等待AD转换结束return ADC_GetConversionValue(ADC1);					//读数据寄存器,得到AD转换的结果
}

10.0.4 头文件


10.0.5 主函数文件

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "AD.h"uint16_t AD0, AD1, AD2, AD3;	//定义AD值变量int main(void)
{/*模块初始化*/OLED_Init();				//OLED初始化AD_Init();					//AD初始化/*显示静态字符串*/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);		//单次启动ADC,转换通道0AD1 = AD_GetValue(ADC_Channel_1);		//单次启动ADC,转换通道1AD2 = AD_GetValue(ADC_Channel_2);		//单次启动ADC,转换通道2AD3 = AD_GetValue(ADC_Channel_3);		//单次启动ADC,转换通道3OLED_ShowNum(1, 5, AD0, 4);				//显示通道0的转换结果AD0OLED_ShowNum(2, 5, AD1, 4);				//显示通道1的转换结果AD1OLED_ShowNum(3, 5, AD2, 4);				//显示通道2的转换结果AD2OLED_ShowNum(4, 5, AD3, 4);				//显示通道3的转换结果AD3Delay_ms(100);			//延时100ms,手动增加一些转换的间隔时间}
}

......

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

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

相关文章

数据结构:LinkedList与链表—面试题(三)

目录 1、移除链表元素 2、反转链表 3、链表的中间结点 4、返回倒数第k个结点 5、合并两个有序链表 1、移除链表元素 习题链接https://leetcode.cn/problems/remove-linked-list-elements/description/ 描述:给你一个链表的头节点 head 和一个整数 val &#xff…

使用 SQL 和表格数据进行问答和 RAG(1)—数据库准备

一. 从 .sql/csv/xlsx 文件创建 sqlite 数据库。 要从.sql文件准备 SQL DB,这里会将创建数据库的代码放到了,将文件复制到data/sql目录中,然后在终端中的项目文件夹中执行: pip install sqlite3现在创建一个名为sqldb的数据库&a…

案例研究:UML用例图中的结账系统

在软件工程和系统分析中,统一建模语言(UML)用例图是一种强有力的工具,用于描述系统与其用户之间的交互。本文将通过一个具体的案例研究,详细解释UML用例图的关键概念,并说明其在设计结账系统中的应用。 用…

EasyExcel上传校验文件错误信息放到文件里以Base64 返回给前端

产品需求: 前端上传个csv 或 excel 文件,文件共4列,验证文件大小,类型,文件名长度,文件内容,如果某行某个单元格数据验证不通过,就把错误信息放到这行第五列,然后把带有…

机器学习免费使用的数据集及网站链接

机器学习领域存在许多可以免费使用的数据集,这些数据集来自于学习、研究、比赛等目的。 一、综合性数据集平台 1.Kaggle 网址:Kaggle 数据集https://www.kaggle.com/datasets Kaggle是一个数据科学竞赛和社区平台,提供了大量的数据集供用…

Nacos 3.0 Alpha 发布,在安全、泛用、云原生更进一步

自 2021 年发布以来,Nacos 2.0 在社区的支持下已走过近三年,期间取得了诸多成就。在高性能与易扩展性方面,Nacos 2.0 取得了显著进展,同时在易用性和安全性上也不断提升。想了解更多详细信息,欢迎阅读我们之前发布的回…

IP查询于访问控制保护你我安全

IP地址查询 查询方法: 命令行工具: ①在Windows系统中,我们可以使用命令提示符(WINR)查询IP地址,在弹窗中输入“ipconfig”命令查看本地网络适配器的IP地址等配置信息; ②在Linux系统中&…

解决 ssh connect to host github.com port 22 Connection timed out

一、问题描述 本地 pull/push 推送代码到 github 项目报 22 端口连接超时,测试连接也是 22 端口连接超时 ssh 密钥没问题、也开了 Watt Toolkit 网络是通的,因此可以强制将端口切换为 443 二、解决方案 1、测试连接 ssh -T gitgithub.com意味着无法通…

如何在Windows 11 WSL2 Ubuntu 环境下安装和配置perf性能分析工具?

在Windows 11 WSL2 Ubuntu 环境下完整安装和配置perf性能分析工具 一、背景二、准备工作三、获取并编译Linux内核源码四、安装和配置perf五、测试perf六、总结 一、背景 由于WSL2使用的是微软定制的内核,并非标准的Ubuntu内核,因此直接使用apt安装linux…

NOVA:AutoRegressive Video Generation Without Vector Quantization——自回归视频生成无需向量量化

这篇文章介绍了一种名为NOVA的新型自回归模型,用于高效的文本到图像和文本到视频生成。以下是文章的主要内容总结: 1. 研究背景与问题 自回归大语言模型(LLMs)在自然语言处理(NLP)中表现出色,但…

eNSP之家——路由器--入门实例详解

eNSP路由器配置:IP、DHCP与DNS详解-CSDN博客 练习1:两个路由器配置ip地址,并用ping命令测试连通性。 打开ensp,拉进来两个路由器AR2220,再用auto连接两个路由器。 选中两个路由器,右键启动,等待半分钟路由…

Spring 设计模式:经典设计模式

Spring 设计模式:经典设计模式 引言 Spring 框架广泛使用了经典设计模式。 这些模式在 Spring 内部发挥着重要作用。 通过理解这些设计模式在 Spring 中的应用,开发者可以更深入地掌握 Spring 框架的设计哲学和实现细节。 经典设计模式 控制反转&am…

【HarmonyOS NEXT】鸿蒙应用点9图的处理(draw9patch)

【HarmonyOS NEXT】鸿蒙应用点9图的处理(draw9patch) 一、前言: 首先在鸿蒙中是不支持安卓 .9图的图片直接使用。只有类似拉伸的处理方案,鸿蒙提供的Image组件有与点九图相同功能的API设置。 可以通过设置resizable属性来设置R…

STM32-笔记39-SPI-W25Q128

一、什么是SPI? SPI是串行外设接口(Serial Peripheral Interface)的缩写,是一种高速的,全双工,同步的通信总线,并且 在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为…

【微服务】8、分布式事务 ( XA 和 AT )

文章目录 利用Seata解决分布式事务问题(XA模式)AT模式1. AT模式原理引入2. AT模式执行流程与XA模式对比3. AT模式性能优势及潜在问题4. AT模式数据一致性解决方案5. AT模式一阶段操作总结6. AT模式二阶段操作分析7. AT模式整体特点8. AT模式与XA模式对比…

CTF知识点总结(三)

空格绕过方式&#xff1a; $IFS ${IFS} $IFS$数字 < <> 三种绕过方式&#xff1a; 1.sh /?ip127.0.0.1;echo$IFS$2Y2F0IGZsYWcucGhw|base64$IFS$2-d|sh 2.变量拼接 /?ip127.0.0.1;ag;cat$IFS$2fla$a.php 3.内联注释(将反引号命令的结果作为输入来执行命令) /?i…

《Spring Framework实战》5:Spring Framework 概述

欢迎观看《Spring Framework实战》视频教程 Spring 使创建 Java 企业应用程序变得容易。它为您提供一切 需要在企业环境中采用 Java 语言&#xff0c;并支持 Groovy 和 Kotlin 作为 JVM 上的替代语言&#xff0c;并且可以灵活地创建许多 类型的架构。从 Spring Framework 6.0 开…

解决npm报错:sill idealTree buildDeps

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl 报错信息 使用 npm 安装依赖时报错&#xff1a;sill idealTree buildDeps 解决方案 请按照以下步骤进行相关操作&#xff1a; 1、删除 C:\Users{账户}\ 文件夹中的 .npm…

formik 的使用

礼记有言&#xff1a;独学而无友&#xff0c;则孤陋而寡闻 让我们一起了解更多便捷方法&#xff0c;缩短开发时间去摸鱼&#xff0c;嘿嘿。 框架&#xff1a;react 在写表单的时候&#xff0c;我不太喜欢把验证写的很繁琐&#xff0c;这里讲介绍&#xff0c;验证表单的非常好用…

JVM实战—OOM的生产案例

1.每秒仅上百请求的系统为何会OOM(RPC超时时间设置过长导致QPS翻几倍) (1)案例背景 在这个案例中&#xff0c;一个每秒仅仅只有100请求的系统却因频繁OOM而崩溃。这个OOM问题会涉及&#xff1a;Tomcat底层工作原理、Tomcat内核参数的设置、服务请求超时时间。 (2)系统发生OOM的…