AD单通道AD多通道

AD单通道接线图

7-1 AD单通道

滑动变阻器的内部结构

image-20241201220413850

左边和右边的两个引脚接的是电阻的两个固定端,中间这个引脚接的是滑动抽头,电位器外边这里有个十字形状的槽可以拧,往左拧,抽头就往左靠,往右拧,抽头就往右靠。所以外围电路这里,我们把左边的固定端接在负极,右边的固定端接在正极,中间就可以输出从负极到正极可调的电压了,然后右边这里我们把可调的电压输出,接在PA0口,在这里,根据引脚定义表,PA0到PB1这10个引脚是ADC的10个通道,所以这10个引脚你可以任意选,接在哪个都行

根据结构框图写代码

Snipaste_2024-12-01_22-10-57

我们把这个结构打通, 在原理上能够让这个外设运转起来,那该怎么配置,自己心里就应该有数了

第一步,开启RCC时钟,包括ADC和GPIO的时钟,另外这里ADCCLK的分频器,也需要配置一下

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //开启ADC1的时钟,ADC都是APB2上的设备
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //因为我们要使用PA0口,所以得开启GPIOA的时钟

RCC_ADCCLKConfig(RCC_PCLK2_Div6); //6分频,这个PCLK2就是APB2时钟的意思,分频之后,ADCCLK=72MHz/6=12MHz

RCC_ADCCLKConfig

/**
  * @brief  Configures the ADC clock (ADCCLK).
  * @param  RCC_PCLK2: defines the ADC clock divider. This clock is derived from 
  *   the APB2 clock (PCLK2).
  *   This parameter can be one of the following values:
  *     @arg RCC_PCLK2_Div2: ADC clock = PCLK2/2
  *     @arg RCC_PCLK2_Div4: ADC clock = PCLK2/4
  *     @arg RCC_PCLK2_Div6: ADC clock = PCLK2/6
  *     @arg RCC_PCLK2_Div8: ADC clock = PCLK2/8
  * @retval None
  */
void RCC_ADCCLKConfig(uint32_t RCC_PCLK2)

第二步,配置GPIO把需要用的GPIO配置成模拟输入的模式

GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入模式,在AIN模式下,GPIO口是无效的,断开GPIO,防止GPIO口的输入输出对模拟电压造成干扰,所以AIN模式就是ADC的专属模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //A0口
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);

这样PA0口就被初始化成了模拟输入的引脚了

第三步,配置这里的多路开关,把左边的通道接入到右边的规则组列表里,这个过程就是我们之前说的点菜,把各个通道的菜,列在菜单里。

ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);

第四步,配置ADC转换器,在库函数里,是用结构体来配置的,可以配置这一大块电路的参数

Snipaste_2024-12-01_22-10-5

包括ADC是单次转换还是连续转换、 扫描还是非扫描、 有几个通道,触发源是什么,数据对齐是左对齐还是右对齐,这一大批参数,用一个结构体配置就可以了。

然后上面这些, 如果你需要模拟看门狗,那会有几个函数用来配置阈值和监测通道的,如果你想开启中断,那就在中断输出控制里用ITConfig函数开启对应的中断输出,然后再在NVIC里,配置一下优先级,这样就能触发中断了,不过这一块,模拟看门狗和中断,我们本节暂时不用。

开关控制,调用一下ADC_Cmd函数,开启ADC,这样ADC就配置完成了,就能正常工作了,当然,在开启ADC之后,根据手册里的建议,我们还可以对ADC进行一下校准, 这样可以减小误差,那在ADC工作的时候,如果想要软件触发转换,那会有函数可以触发,如果想读取转换结果, 那也会有函数可以读取结果,这个等会儿介绍库函数的时候就可以看到了

首先我们看一下ADCCLK的配置函数,这是在RCC里面的

void RCC_ADCCLKConfig(uint32_t RCC_PCLK2);// 这个函数是用来配置ADCCLK分频器的,它可以对APB2的72MHZ时钟选择2、4、6、8分频,输入到ADCCLK,这就是这个函数的作用,是在RCC库函数里面的,别忘了配置了

ADC的库函数

void ADC_DeInit(ADC_TypeDef* ADCx);
void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);
void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct);
前三个是老熟人了

void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);//给ADC上电,也就是PPT这里的开关控制

void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState);//开启DMA输出信号,如果使用DMA转运数据,那就得调用这个函数

void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState);//中断输出控制,也就是PPT的右上角,用于控制某个中断,能不能通往NVIC

下面四个是用于控制校准的函数
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);//用于软件触发的函数,调用一下,就能软件触发转换了,也就是这里的触发控制,我们这个代码目前使用软件触发,

FlagStatus ADC_GetSoftwareStartConvStatus(ADC_TypeDef* ADCx);//获取软件开始转换状态,从名字上来看,这个函数好像是判断转换是不是正在进行的,那我们是不是可以调用这个函数,来判断转换是否已经结束呢,答案是不行的,可以看看源码,这个函数就是用来获取CR2的SWSTART这一位,然后再对照手册的寄存器描述,这一位的作用是,开始转换规则通道,由软件设置该位以启动转换,转换开始后硬件马上清除此位,所以这里,ADC_SoftwareStartConvCmd函数就是给SWSTART位置1,以开始转换的,本返回SWSTART的状态,由于SWSTART位在转换开始后立刻就清零了,所以这个函数的返回值跟转换是否结束,毫无关系,那如何才能知道转换是否结束呢?我们需要用到下面的ADC_GetFlagStatus函数,获取标志位状态,然后参数给EOC的标志位,判断EOC标志位是不是置1了,如果转换结束,EOC标志位置1。所以简单来说本函数其实没啥用,我们一般不用,不要被他误导了

然后下面这两个函数 是用来配置间断模式的
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规则组通道配置,这个函数比较重要,它的作用就是这里(转换模式那个序列i一格一格的),给序列的每个位置填写指定的通道,就是填写点菜菜单的过程,第一个参数是ADCx,第二个ADCChannel 就是你想指定的通道,第三个Rank,就是序列几的位置,然后第四个SampleTime,就是指定通道的采样时间

void ADC_ExternalTrigConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);//ADC外部触发转换控制,就是是否允许外部触发转换

uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx);//ADC获取转换值,这个函数也比较重要,就是获取AD转换的数据寄存器,读取转换结果就要使用这个函数,
uint32_t ADC_GetDualModeConversionValue(void);//之后,ADC获取双模式转换值,这个是双ADC模式读取转换结果的函数,我们暂时不用
以上这些函数就是对ADC的一些基本功能和规则组的配置

下面这里有一大批函数,这些函数里面都带了一个Injected,就是注入组的意思,所以这一大批函数都是对ADC注入组进行配置的,那注入组我们暂时不多讲,大家感兴趣的话可以自己看一看
void ADC_AutoInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_InjectedDiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_ExternalTrigInjectedConvConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConv);
void ADC_ExternalTrigInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_SoftwareStartInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
FlagStatus ADC_GetSoftwareStartInjectedConvCmdStatus(ADC_TypeDef* ADCx);
void ADC_InjectedChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);
void ADC_InjectedSequencerLengthConfig(ADC_TypeDef* ADCx, uint8_t Length);
void ADC_SetInjectedOffset(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel, uint16_t Offset);
uint16_t ADC_GetInjectedConversionValue(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel);

下面这三个函数就是对模拟看门狗进行配置的
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);//上面ADC_GetSoftwareStartConvStatus函数提了一嘴,获取标志位状态
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); //清除中断挂起位

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

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

相关文章

解决Ubuntu DNS覆盖写入127.0.0.53

ubuntu22.04解析网址时报错如图所示: 因为/etc/resolve.conf中存在 nameserver 127.0.0.53回环地址造成循环引用 原因: ubuntu17.0之后特有,systemd-resolvd服务会一直覆盖 解决方法: 1、修改resolv.config文件中的nameserver…

hint: Updates were rejected because the tip of your current branch is behind!

问题 本地仓库往远段仓库推代码时候提示: error: failed to push some refs to 192.168.2.1:java-base/java-cloud.git hint: Updates were rejected because the tip of your current branch is behind! refs/heads/master:refs/heads/master [rejected] (…

[golang][MAC]Go环境搭建+VsCode配置

一、go环境搭建 1.1 安装SDK 1、下载go官方SDK 官方:go 官方地址 中文:go 中文社区 根据你的设备下载对应的安装包: 2、打开压缩包,根据引导一路下一步安装。 3、检测安装是否完成打开终端,输入: go ve…

关于VNC连接时自动断联的问题

在服务器端打开VNC Server的选项设置对话框,点左边的“Expert”(专家),然后找到“IdleTimeout”,将数值设置为0,点OK关闭对话框。搞定。 注意,服务端有两个vnc服务,这俩都要设置ide timeout为0才行 附件是v…

AIGC时代 | 如何从零开始学网页设计及3D编程

文章目录 一、网页设计入门1. 基础知识2. 学习平台与资源3. 示例代码:简单的HTMLCSSJavaScript网页 二、3D编程入门1. 基础知识2. 学习平台与资源3. 示例代码:简单的Unity 3D游戏 《编程真好玩:从零开始学网页设计及3D编程》内容简介作者简介…

virtualbox给Ubuntu22创建共享文件夹

1.在windows上的操作,创建共享文件夹Share 2.Ubuntu22上的操作,创建共享文件夹LinuxShare 3.在virtualbox虚拟机设置里,设置共享文件夹 共享文件夹路径:选择Windows系统中你需要共享的文件夹 共享文件夹名称:挂载至wi…

C#窗体简单登录

创建一个Windows登录程序,创建两个窗体,一个用来登录,一个为欢迎窗体,要求输入用户名和密码(以个人的姓名和学号分别作为用户名和密码),点击【登录】按钮登录,登录成功后显示欢迎窗体…

es 3期 第12节-选择合适的数据查询方式

#### 1.Elasticsearch是数据库,不是普通的Java应用程序,传统数据库需要的硬件资源同样需要,提升性能最有效的就是升级硬件。 #### 2.Elasticsearch是文档型数据库,不是关系型数据库,不具备严格的ACID事务特性&#xff…

Educator头歌:离散数学 - 图论

第1关&#xff1a;图的概念 任务描述 本关任务&#xff1a;学习图的基本概念&#xff0c;完成相关练习。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a;图的概念。 图的概念 1.一个图G是一个有序三元组G<V,R,ϕ>&#xff0c;其中V是非空顶点集合&am…

day30|leetcode 452. 用最少数量的箭引爆气球, 435. 无重叠区间 , 763.划分字母区间

重叠区间专题 11.用最少的数量引爆气球 有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points &#xff0c;其中points[i] [xstart, xend] 表示水平直径在 xstart 和 xend之间的气球。你不知道气球的确切 y 坐标。 一支弓箭可以沿着 x 轴从不同…

电脑提示报错“Directx error”怎么解决?是什么原因导致的?游戏软件提示“Directx error”错误的解决方案

DirectX Error&#xff08;DX错误&#xff09;通常指的是在使用基于DirectX技术的应用程序&#xff08;尤其是游戏&#xff09;时遇到的问题。这个问题可能由多种因素导致&#xff0c;以下是一些可能的原因及相应的解决方案&#xff1a; 可能的原因 DirectX版本不匹配&#x…

K8S网络系列--Flannel网络下UDP、VXLAN模式的通信流程机制分析

文章目录 前言一、了解overlay、underlay容器网络二、网络通信1.分类2.网络虚拟设备对2.1、什么是网络虚拟设备对veth pair?2.2、如何查看容器的网卡与主机的哪个veth设备对是成对的关系? 3、vxlan和vtep3.1、vtep3.2、vxlan相关概念 三、Flannel网络模式剖析0、flannel的作用…

【OpenGL学习笔记】图形渲染管线

文章目录 渲染管线简介顶点输入顶点着色器片段着色器着色器程序链接顶点属性 VAO VBO绘制图元元素缓冲对象 EBO 渲染管线简介 在OpenGL中&#xff0c;一切都是3D的&#xff0c;但屏幕或者窗口是一个2D像素阵列&#xff0c;因此OpenGL的大部分工作是将所有3D坐标转换为适合屏幕…

Linux下的三种 IO 复用

目录 一、Select 1、函数 API 2、使用限制 3、使用 Demo 二、Poll 三、epoll 0、 实现原理 1、函数 API 2、简单代码模板 3、LT/ET 使用过程 &#xff08;1&#xff09;LT 水平触发 &#xff08;2&#xff09;ET边沿触发 4、使用 Demo 四、参考链接 一、Select 在…

视觉语言动作模型VLA的持续升级:从π0之参考基线Octo到OpenVLA、TinyVLA、DeeR-VLA、3D-VLA

第一部分 VLA模型π0之参考基线Octo 1.1 Octo的提出背景与其整体架构 1.1.1 Octo的提出背景与相关工作 许多研究使用从机器人收集的大量轨迹数据集来训练策略 从早期使用自主数据收集来扩展策略训练的工作[71,48,41,19-Robonet,27,30]到最近探索将现代基于transformer的策略…

【Python爬虫五十个小案例】爬取猫眼电影Top100

博客主页&#xff1a;小馒头学python 本文专栏: Python爬虫五十个小案例 专栏简介&#xff1a;分享五十个Python爬虫小案例 &#x1f40d;引言 猫眼电影是国内知名的电影票务与资讯平台&#xff0c;其中Top100榜单是影迷和电影产业观察者关注的重点。通过爬取猫眼电影Top10…

JVM之Synthetic

Synthetic是人造&#xff0c;合成的意思&#xff0c;在虚拟机很多地方使用ACC_SYNTHETIC表示编译器自动生成的&#xff0c;区别于我们自己写的程序代码。这样说可能比较模糊&#xff0c;我们举个例子&#xff1a;我们创建一个内部类&#xff0c;如下 public class TestInnerCl…

Mysql数据库基础篇笔记

目录 sql语句 DDL——数据库定义语言&#xff08;定义库&#xff0c;表&#xff0c;字段&#xff09; 数据库操作&#xff1a; 表操作&#xff1a; DML 增删改语句 DQL 语法编写顺序&#xff1a; 条件查询 DCL 用户管理&#xff1a; 权限管理&#xff1a; 函数 常见字符串内置函…

【大模型】深度解析 NLP 模型5大评估指标及 应用案例:从 BLEU、ROUGE、PPL 到METEOR、BERTScore

在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;无论是机器翻译、文本生成&#xff0c;还是问答系统开发&#xff0c;模型性能评估指标始终是开发者绕不开的工具。BLEU、ROUGE、PPL&#xff08;困惑度&#xff09;、METEOR 和 BERTScore 是五个最具代表性的指标&am…

【QT】背景,安装和介绍

TOC 目录 背景 GUI技术 QT的安装 使用流程 QT程序介绍 main.cpp​编辑 Wiget.h Widget.cpp form file .pro文件 临时文件 C作为一门比较古老的语言&#xff0c;在人们的认知里始终是以底层&#xff0c;复杂和高性能著称&#xff0c;所以在很多高性能需求的场景之下…