STM32-ADC一步到位学习手册

1.按部就班陈述概念

ADC 是 Analog-to-Digital Converter 的缩写,指的是模拟/数字转换器。它将连续变量的模拟信号转换为离散的数字信号。在 STM32 中,ADC 具有高达 12 位的转换精度,有多达 18 个测量通道,其中 16 个为外部通道,2 个为内部通道。各通道的 A/D 转换可以单次、连续、扫描或间断模式执行,并将扫描结果存储在 16 位的数据寄存器中

2.突如其来的结构讲解

  • 输入电压范围:ADC 所能测量的电压范围,一般为 0 ~ VREF+,其中 VREF+ 可以是 VDDA 或外部参考电压
  • 输入通道:ADC 的信号通过输入通道进入单片机内部,每个通道可以是外部的 GPIO 或内部的 VREFINT、VSS、温度传感器等
  • 转换通道:ADC 的输入通道在转换时又分为规则通道和注入通道,规则通道最多有 16 路,注入通道最多有 4 路,它们可以有不同的转换顺序和触发方式
  • 触发源:ADC 的转换可以由软件或外部触发,外部触发可以是定时器或外部引脚,它们可以有不同的极性和源选择
  • 转换周期:ADC 的转换需要一定的采样时间和转换时间,采样时间可以由 SMP[2:0] 位设置,转换时间由 ADC 时钟决定,总转换时间为 Tconv = 采样时间 + 12.5 个周期
  • 数据寄存器:ADC 的转换结果存储在 16 位的数据寄存器中,可以是左对齐或右对齐,可以是单个或双个,可以是规则或注入
  • 数据传输:ADC 的转换结果可以通过中断或 DMA 的方式传输到内存或其他外设,可以设置不同的传输模式和优先级

3.程序实例

数据转换结束后,可以产生中断,中断分为三种:规则通道转换结束中断,注入转换通道转换结
束中断,模拟看门狗中断,除了产生中断外,还可以产生 DMA 请求。因此代码部分,我仅采用单通道和 AD多通道。

AD单通道

   RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);	//开启ADC1的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	//开启GPIOA的时钟
	
	/*设置ADC时钟*/
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);						//选择时钟6分频,ADCCLK = 
    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);					//将PA0引脚初始化为模拟输入
	
	/*规则组通道配置*/
	ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);		//规 
   则组序列1的位置,配置为通道0
	
	/*ADC初始化*/
	ADC_InitTypeDef ADC_InitStructure;						//定义结构体变量
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;		//模式,选择独立模式,即单独使用ADC1
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;	//数据对齐,选择右对齐
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;	//外部触发,使用软件触发,不需要外部触发
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;		//连续转换,失能,每转换一次规则组序列后停止
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;			//扫描模式,失能,只转换规则组的序列1这一个位置
	ADC_InitStructure.ADC_NbrOfChannel = 1;					//通道数,为1,仅在扫描模式下,才需要指定大于1的数,在非扫描模式下,只能是1
	ADC_Init(ADC1, &ADC_InitStructure);						//将结构体变量交给ADC_Init,配置ADC1
	
	/*ADC使能*/
	ADC_Cmd(ADC1, ENABLE);									//使能ADC1,ADC开始运行
	
	/*ADC校准*/
	ADC_ResetCalibration(ADC1);								//固定流程,内部有电路会自动执行校准
	while (ADC_GetResetCalibrationStatus(ADC1) == SET);
	ADC_StartCalibration(ADC1);
	while (ADC_GetCalibrationStatus(ADC1) == SET);
}

AD带中断

GPIO_InitTypeDef GPIO_InitStructure;
	
	// 打开 ADC IO端口时钟
	ADC_GPIO_APBxClock_FUN ( ADC_GPIO_CLK, ENABLE );
	
	// 配置 ADC IO 引脚模式
	// 必须为模拟输入
	GPIO_InitStructure.GPIO_Pin = ADC_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	
	// 初始化 ADC IO
	GPIO_Init(ADC_PORT, &GPIO_InitStructure);				
}

/**
  * @brief  配置ADC工作模式
  * @param  无
  * @retval 无
  */
static void ADCx_Mode_Config(void)
{
	ADC_InitTypeDef ADC_InitStructure;	

	// 打开ADC时钟
	ADC_APBxClock_FUN ( ADC_CLK, ENABLE );
	
	// ADC 模式配置
	// 只使用一个ADC,属于独立模式
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
	
	// 禁止扫描模式,多通道才要,单通道不需要
	ADC_InitStructure.ADC_ScanConvMode = DISABLE ; 

	// 连续转换模式
	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

	// 不用外部触发转换,软件开启即可
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;

	// 转换结果右对齐
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
	
	// 转换通道1个
	ADC_InitStructure.ADC_NbrOfChannel = 1;	
		
	// 初始化ADC
	ADC_Init(ADCx, &ADC_InitStructure);
	
	// 配置ADC时钟为PCLK2的8分频,即9MHz
	RCC_ADCCLKConfig(RCC_PCLK2_Div8); 
	
	// 配置 ADC 通道转换顺序和采样时间
	ADC_RegularChannelConfig(ADCx, ADC_CHANNEL, 1, 
	                         ADC_SampleTime_55Cycles5);
	
	// ADC 转换结束产生中断,在中断服务程序中读取转换值
	ADC_ITConfig(ADCx, ADC_IT_EOC, ENABLE);
	
	// 开启ADC ,并开始转换
	ADC_Cmd(ADCx, ENABLE);
	
	// 初始化ADC 校准寄存器  
	ADC_ResetCalibration(ADCx);
	// 等待校准寄存器初始化完成
	while(ADC_GetResetCalibrationStatus(ADCx));
	
	// ADC开始校准
	ADC_StartCalibration(ADCx);
	// 等待校准完成
	while(ADC_GetCalibrationStatus(ADCx));
	
	// 由于没有采用外部触发,所以使用软件触发ADC转换 
	ADC_SoftwareStartConvCmd(ADCx, ENABLE);
}

static void ADC_NVIC_Config(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
	// 优先级分组
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

  // 配置中断优先级
  NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQ;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

4.结语

ADC 是 stm32 单片机的一个重要的外设,它可以让我们获取外部的模拟信号,并进行一些有用的操作,例如:

  • 测量电压、电流、电阻、电容等电路参数
  • 测量温度、湿度、气压、光照等环境参数
  • 采集声音、图像、视频等多媒体信号
  • 实现模拟信号的滤波、放大、调制、解调等信号处理

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

小朋友来自多少小区 - 华为OD统一考试(C卷)

OD统一考试(C卷) 分值: 100分 题解: Java / Python / C 题目描述 幼儿园组织活动,老师布置了一个任务: 每个小朋友去了解与自己同一个小区的小朋友还有几个。 我们将这些数量汇总到数组 garden 中。 请…

gofly框架接口入参验证使用介绍

接口传入的参数做相关性质验证是开发中较为常用,gofly框架内置校验工具,提供开发效率,开发接口简单调用即可实现验证,下面介绍gofly框架数据验证设计思路及使用方法。 gofly框架提供了功能强大、使用便捷、灵活易扩展的数据/表单…

jupyter调用envs环境——jupyter内核配置虚拟环境

1.jupyter无法使用envs环境 pycharm的终端打开jupyter notebook: 在kernel下找不到上面的Pytorch_GPU环境: 2.解决方法 在对应的envs环境中安装ipykernel: 将该环境写入jupyter: python -m ipykernel install --user --name Py…

蓝桥杯前端Web赛道-自适应页面

蓝桥杯前端Web赛道-自适应页面 题目链接:1.自适应页面 - 蓝桥云课 (lanqiao.cn) 先看题目要求: 简单的来说就是需要完成上面规定的布局和要求当800px及以下的时候要显示移动端布局来完成下面gif的效果,那么我们先一步一步来 首先想到的就…

逻辑漏洞(pikachu)

#水平,垂直越权,未授权访问 通过个更换某个id之类的身份标识,从而使A账号获取(修改、删除)B账号数据 使用低权限身份的账号,发送高权限账号才能有的请求,获得其高权限操作 通过删除请求中的认…

SpringCloud微服务技术栈-什么是Docker?怎么安装Docker?

初识Docker以及常见技术及其概念概述 1、项目部署存在的问题 大型项目组件较多,运行环境也较为复杂,部署时会碰到一些问题: 依赖关系复杂,容易出现兼容性问题 开发、测试、生产环境有差异 Docker如何解决大型项目依赖关系复杂&#xff0…

面试高频率问答题目

索引: 主键索引:表的id (唯一 且 不能为空) 唯一索引:表User 假设有account 字段 ,用户名不重复 (唯一 可以为空) 复合索引:where() 的条件 用户名,密码 …

判断点是否在多边形内

std::vector<cv::Point2d> vanCorner_;bool inArea(const Pose &pos) {cv::Point2d point cv::Point2d(pos.position.x(), pos.position.y());double distance cv::pointPolygonTest(vanCorner_, point, false);return distance > 0; } 似乎效果不太好,会误报 …

springboot236基于springboot在线课程管理系统的设计与实现

基于SpringBoot在线课程管理系统的设计与实现 摘要 本文首先介绍了在线课程管理系统的现状及开发背景&#xff0c;然后论述了系统的设计目标、系统需求、总体设计方案以及系统的详细设计和实现&#xff0c;最后对在线课程管理系统进行了系统检测并提出了还需要改进的问题。本系…

STM32 | 零基础 STM32 第一天

零基础 STM32 第一天 一、认知STM32 1、STM32概念 STM32:意法半导体基于ARM公司的Cortex-M内核开发的32位的高性能、低功耗单片机。 ST:意法半导体 M:基于ARM公司的Cortex-M内核的高性能、低功耗单片机 32&#xff1a;32位单片机 2、STM32开发的产品 STM32开发的产品&a…

李宏毅机器学习入门笔记——第八节

Auto-Encoder 输入图片经过两个网络后&#xff0c;计算他们两个越接近越好。 类似于Cycle GAN。 encoder将高纬度数据降维&#xff0c;作为低纬度向量 假如噪声进行训练&#xff0c;encoder将图片中的噪声去除。 其实BERT而言&#xff0c;就是以后个auto-encoder。 Feature d…

linux之进程理解(1)

目录 1. 冯诺依曼体系结构 2. 操作系统(OS) 2.1 概念 2.2 设计OS的目的 2.3 定位 2.4 理解管理 3. 系统调用和库函数概念 4. 补充 1. 冯诺依曼体系结构 我们常见的计算机&#xff0c;如笔记本。我们不常见的计算机&#xff0c;如服务器&#xff0c;大部分都遵守冯诺依曼体…

电子电气架构——AUTOSAR架构下EcuM唤醒源事件详解

电子电气架构——AUTOSAR架构下EcuM唤醒源事件详解 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 没有人关注你。也无需有人关注你。你必须承认自己的价值,你不能站在他人的角度来反对自己。人…

CDC作业历史记录无法删除问题

背景 数据库开启CDC功能后&#xff0c;每天会生成大量的历史记录&#xff0c;即使达到参数“每个作业的最大历史记录“的阈值后也不会被删除&#xff0c;导致其它作业的历史记录被删除&#xff0c;无法查看以前的执行情况&#xff0c;非常不方便。 现象 数据库开启CDC后会创建…

JavaScript入门学(Web APIs)

1.变量声明 2 DOM介绍 2.1 什么是DOM 2.2 DOM树 2.3 DOM对象&#xff08;重要&#xff09; 3.DOM&#xff08;文档对象模型&#xff09;-获取元素 3.1 获取匹配的第一个元素 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8&…

swoole

php是单线程。php是靠多进程来处理任务&#xff0c;任何后端语言都可以采用多进程处理方式。如我们常用的php-fpm进程管理器。线程与协程,大小的关系是进程>线程>协程,而我们所说的swoole让php实现了多线程,其实在这里来说,就是好比让php创建了多个进程,每个进程执行一条…

Python爬虫——Urllib库-3

目录 ajax的get请求 获取豆瓣电影第一页的数据并保存到本地 获取豆瓣电影前十页的数据 ajax的post请求 总结 ajax的get请求 获取豆瓣电影第一页的数据并保存到本地 首先可以在浏览器找到发送数据的接口 那么我们的url就可以在header中找到了 再加上UA这个header 进行请…

ssm个人学习01

Spring配置文件: spring环境的搭建: 1:导入对应的spring坐标 也就是依赖 2:编写controller, service, dao相关的代码 3:创建配置文件(在resource下面配置文件) 例如:applicationContext.xml <bean id "" class ""> <property name "&…

共同学习|Spring Cloud Alibaba一一Nacos配置

Nacos配置中心 在服务或者应用运行过程中&#xff0c;提供动态配置或者元数据以及配置管理的服务提供者。 从Nacos中拉去配置文件 pom文件 2、bootstrap.yml 修改application.yml为bootstrap.yml spring:cloud: nacos:config:server-addr: localhost:8848 #nacos服务地址…

nginx,php-fpm

一&#xff0c;Nginx是异步非阻塞多进程&#xff0c;io多路复用 1、master进程&#xff1a;管理进程 master进程主要用来管理worker进程&#xff0c;具体包括如下4个主要功能&#xff1a; &#xff08;1&#xff09;接收来自外界的信号。 &#xff08;2&#xff09;向各worker进…