热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:STM32学习笔记(13)——模数转换ADC

篇首语:本文由编程笔记#小编为大家整理,主要介绍了STM32学习笔记(13)——模数转换ADC相关的知识,希望对你有一定的参考价值。

篇首语:本文由编程笔记#小编为大家整理,主要介绍了STM32学习笔记(13)——模数转换ADC相关的知识,希望对你有一定的参考价值。






这个月一直忙于准备考试,已经考完一半科目了,偷闲写了这篇文章。因为还没考完试,估计还得咕一段时间了。



STM32学习笔记(13)——模数转换ADC


  • 第一部分:ADC功能框图
    • 一、输入电压
    • 二、输入通道
    • 三、规则通道
    • 四、注入通道
    • 五、触发源
      • 1. 软件触发
      • 2. 外部事件触发

    • 六、转换时间
    • 六、数据寄存器
      • 1. 数据规则寄存器(ADC_DR)
      • 2. 数据注入寄存器(ADC_JDRx,x=1, 2, 3, 4)

    • 七、中断

  • 第二部分:ADC结构体和库函数
    • 一、ADC初始化结构体
      • 1. 工作模式
      • 2. 扫描模式
      • 3. 连续转换模式
      • 4. 外部触发源选择
      • 5. 数据对齐格式
      • 6. 采集通道数

    • 二、ADC常用库函数



模拟量转换为数字量的过程称为A/D模数转换,完成这一转换过程的器件称为ADC(Analog-to-Digital Converter)。

在STM32中,有三个ADC:ADC1、ADC2、ADC3,其分辨率为12位,每个ADC通道具有18个通道,其中外部通道有16个。


第一部分:ADC功能框图

在这里插入图片描述

我们分为七个部分讲解:


一、输入电压

输入电压一般由参考电压VREF-VREF+VDDA(模拟电压源)VSSA(模拟地)提供,具体的输入电压范围为VREF- ≤ VIN ≤ VREF+

在一般的电路设计中,我们会将VSSAVREF-接地(GND),将VDDAVREF+接高电平(即3.3V),如下图电路原理图所示。因此,ADC的输入电压范围为0 ~ 3.3V

我们可以根据数字量来算出模拟量:首先 ADC 分辨率为12位,电压范围为 0~3.3V,则最小精度为






3.3





0




2


12





\\frac{3.3-0}{2^{12}}


2123.30
,假设数字量为X,则最终模拟量 =






3.3





0




2


12







X



\\frac{3.3-0}{2^{12}}\\cdot X


2123.30X

在这里插入图片描述

当然,ADC可以测量范围为 0 ~ 3.3V 的电压,但如果超出这个范围的电压该如何测量呢?举一个简单的例子:如果我们想扩大测量范围至 -10 ~ +10V,可以将电路设计成如下:

在这里插入图片描述

根据KCL(基尔霍夫定律:节点流入电流之和等于流出电流之和)方程可得出:








V


I


N





V


O


U


T




R


2




+




3.3


V





V


O


U


T




R


1




=




V


O


U


T




R


3





\\frac{VIN-VOUT}{R2}+\\frac{3.3V-VOUT}{R1}=\\frac{VOUT}{R3}


R2VINVOUT+R13.3VVOUT=R3VOUT

已知 R1、R2 和 R3,就能根据这个方程得出 VIN 和 VOUT 的关系式。


二、输入通道

STM32 为三个 ADC 分配了 18 个通道,如下表所示:

在这里插入图片描述

这是 STM32F103ZET6 的通道引脚分配,不同型号的芯片有不同的分配。在这里,对于 ADC1 和 ADC2,通道16和17均为内部通道;对于 ADC3,通道9和通道14~17均为内部通道。注意有部分 IO 引脚被重复占用。


三、规则通道

STM32 的 ADC 输入通道分为两类:规则通道和注入通道。ADC 可以对一组指定的通道,按照既定的顺序,逐个转换这组通道,转换结束后,再从头循环。这些指定的通道组被称为规则通道组(规则组),组内的通道被称为规则转换通道(规则通道)。但在实际情况中,有可能需要临时中断规则组的转换,对某些通道进行转换,这些需要中断的规则组就称为注入通道组(注入组),组内的通道被称为注入转换通道(注入通道)

规则组最多可以设置 16 个通道。

我们可通过规则序列寄存器SQRx(x=1, 2, 3)来设置规则通道的优先顺序。规则序列寄存器一共有三个,除了寄存器SQR1的第23位至20位(SQL[3:0])用做配置转换通道的个数外,其他都是每 5 位一组配置第 n 个转换的通道。如下表所示:

在这里插入图片描述

例如,配置寄存器SQR1SQL[3:0]为3,表明有 3 个规则通道,则可在寄存器SQR3SQ1[4:0]SQ2[4:0]SQ3[4:0]中分别配置为11、5、7,表明通道5、7和11都是规则通道,而且转换顺序是先通道11、再通道5、最后通道7。


四、注入通道

注入通道和规则通道有所不同的是,注入通道与中断程序类似,在规则通道进行转换时“强行”插入进行转换。因此,注入也有插入的意思,插入和规则是相对的,注入通道只有在规则通道存在的时候才会出现。

我们可通过注入序列寄存器JQSR来设置注入通道的优先顺序。注入序列寄存器只有一个,第21和20位两位(JL[1:0])用来设置转换通道的个数,其余都是每 5 位一组配置第 n 个转换通道。如下表所示:

在这里插入图片描述

因为与规则通道序列寄存器类似,因此就不举例了。但要注意一点:寄存器JSQR和寄存器SQR的转换顺序是不一样的。JSQR的第 4 个转换通道其实是第一次进行转换的,第 3 个转换通道是第二次进行转换的,正好是反过来的,以此类推。

关于规则组和注入组的例子:系统需要采集温度,但又要适时监控湿度,那么湿度采集的转换通道可以放在注入组中,通过某种触发源启动转换。一旦启动注入通道转换,规则通道转换被暂停,然后等待注入通道转换完成后,规则组在进行转换。


五、触发源


1. 软件触发

是否启动 ADC 由寄存器ADC_CR2ADON位控制,写入1则表示打开或启动模拟至数字转换器的电压。

启动转换器后,由寄存器ADC_CR2SWSTART位和JSWSTART位分别控制规则通道的转换和注入通道的转换,写入1则表示转换使能允许。


2. 外部事件触发

寄存器ADC_CR2EXTSEL位和EXTTRIG位控制规则通道的触发源,触发源来自TIM1_CHx(x=1, 2, 3)TIM2_CH2TIM4_CH4TIM3_TRGOEXTSEL位用于选择使用哪个触发源,EXTTRIG位用于使能触发允许或禁止。

类似地,寄存器ADC_CR2JEXTSEL位和JEXTTRIG位控制注入通道的触发源,触发源来自TIM1_CH4TIM2_CH1TIM3_CH4TIM1_TRGOTIM2_TRGOTIM4_TRGOJEXTSEL位用于选择使用哪个触发源,JEXTTRIG位用于使能触发允许或禁止。

注意,以上描述的是 ADC1 和 ADC2 的触发源,ADC3 与前两者有区别,具体可参考手册内容。

GPIO 外部中断的 EXTI11 和 EXTI15 也可作为触发源。


六、转换时间

转换时间公式为:T(conv) = 采样时间 + 12.5个周期

转换速度由 ADC 模拟时钟(ADC_CLK)决定,其最大频率为 14MHz。 ADC_CLK 由 PCLK2 提供。之前在讲解时钟树的时候已经提及过,PCLK2 在经过 APB2 预分频器后最大频率可达到 72MHz。因为 ADC_CLK 规定最大频率为 14MHz,因此, 时钟信号经过 的 ADC 预分频器的分频因子最小为 6,所以实际的最大频率为72MHz / 6 = 12MHz

在这里插入图片描述

那么在哪里可以配置 ADC 预分频因子呢?注意,并不在 ADC 相关的寄存器中配置,而是在与 RCC 相关的寄存器进行配置。在寄存器RCC_CFGRADCPRE[1:0]可以配置 ADC 预分频因子。

ADC 需要若干个 ADC_CLK 周期才能完成对输入模拟量的采样,因此采样时间可由 n
个 ADC_CLK 周期来表示,即采样的周期数。我们可以通过两个采样时间寄存器ADC_SMPRx(x=1, 2) 来配置(如下表所示),位SMPx[2:0] (x=0-17)用来配置采样的周期。其中寄存器ADC_SMPR2控制的是通道 0~9,寄存器ADC_SMPR1控制的是通道 10~17。这意味着每个通道都可以采用不同的采样周期。

在这里插入图片描述

如上表所示,最快的采样周期为 1.5 个 ADC_CLK 周期,最慢的采样周期为 239.5 个 ADC_CLK 周期。而一个周期的时间一般为1 / 12MHz,所以最短的转换时间为:T(conv) = 采样时间 + 12.5个周期 = 1.5 + 12.5 = 14 个周期 = 14 *(1 / 12us) = 1.17us


六、数据寄存器

ADC将转换好的数据存放到数据寄存器中,规则组的数据存放到寄存器ADC_DR中,注入组的数据则存放到寄存器ADC_JDRx(x=1, 2, 3, 4)中。


1. 数据规则寄存器(ADC_DR)

在这里插入图片描述

对于独立模式,即只使用一个 ADC 的情况(即只使用 ADC1 或 ADC2 或 ADC3)下,由于 ADC 分辨率为 12 位,所以只使用寄存器的低16位中的12位,高16位就不使用了。 这12位数据可以左对齐,也可以右对齐,这是由寄存器ADC_CR2ALIGN来决定。

对于双ADC模式(ADC1和ADC2同时使用,注意ADC3是不能用于双ADC模式的),ADC2 的数据存放在寄存器的高16位,而 ADC1 的数据存放在寄存器的低16位。

由于数据规则寄存器只有一个,因此在使用多通道采集的时候寄存器的数据必然会被覆盖,一般的解决办法是采用DMA模式(ADC1和ADC3可用,2不可用),将转换结果转移进 DMA 中。


2. 数据注入寄存器(ADC_JDRx,x=1, 2, 3, 4)

在这里插入图片描述

和数据规则寄存器一样,由于 ADC 分辨率为 12 位,所以只使用寄存器的低16位中的12位,高16位就不使用了。 这12位数据可以左对齐,也可以右对齐,这是由寄存器ADC_CR2ALIGN来决定。

由于数据注入寄存器有 4 个,因此就不存在多通道采集时所产生的数据覆盖问题了。


七、中断

在这里插入图片描述

ADC能产生三种中断,这三种中断对应的标志事件是:转换结束(EOC)、注入转换结束(JEOC)、模拟看门狗事件(AWID),所对应的中断使能位是EOCIE、JEOCIE、AWIDIE。

这里说明一下模拟看门狗的作用:在某些情况下我们希望模拟电压达到一定阈值后就产生一次中断,可以用模拟看门狗来监测模拟电压是否达到这个阈值,如果是,那么就会发出一次中断请求。在 ADC看门狗高阈值寄存器(ADC_HTR)ADC看门狗低阈值寄存器(ADC_LRT) 可以设置这个阈值电压,两者均为低12位有效。


第二部分:ADC结构体和库函数

一、ADC初始化结构体

typedef struct
{
uint32_t ADC_Mode; // ADC工作模式
FunctionalState ADC_ScanConvMode; // ADC扫描(多通道)或单次(单通道)模式
FunctionalState ADC_ContinuousConvMode; // ADC单次转换或连续转换
uint32_t ADC_ExternalTrigConv; // ADC触发源选择
uint32_t ADC_DataAlign; // ADC数据寄存器对齐格式
uint8_t ADC_NbrOfChannel; // ADC采集通道数

}ADC_InitTypeDef;

1. 工作模式

在寄存器ADC_CR1DUALMOD[3:0]位可以配置ADC工作模式,下面来简要介绍每种模式(除了独立模式外,剩余的模式都属于双重模式,只能搭配ADC1/2):


  • 独立模式(ADC_Mode_Independent):ADC1/2/3 单独使用其中一个。
  • 同步规则模式(ADC_Mode_RegSimult):ADC1 和 ADC2 同时转换一个规则通道组,其中 ADC1 为主,ADC2 为从,ADC1 转换的结果放在ADC_DR低16位,ADC2 转换的结果放在ADC_DR的高16位。
  • 同步注入模式(ADC_Mode_InjecSimult):ADC1 和 ADC2 同时转换一个注入通道组,其中 ADC1 为主,ADC2 为从,ADC1 转换的结果放在各自的ADC_JDR
  • 快速交叉模式(ADC_Mode_FastInterl):ADC1 和 ADC2 交替采集一个规则通道组(通常为一个规则通道),当 ADC2 触发后,ADC1 需要等待 7 个 ADCCLK 之后才能触发。
  • 慢速交叉模式(ADC_Mode_SlowInterl):ADC1 和 ADC2 交替采集一个规则通道组(只能为一个规则通道),当 ADC2 触发后,ADC1 需要等待 14 个 ADCCLK 之后才能触发。
  • 交替触发模式(ADC_Mode_AlterTrig):ADC1 和 ADC2 轮流采集注入通道组,当 ADC1 采集完所有通道后,ADC2 再采集自己的通道,如此循环。
  • 混合的同步规则+注入同步模式(ADC_Mode_RegInjecSimult):规则组同步转换被中断,以启动注入组的同步转换。
  • 混合的同步规则+交替触发模式(ADC_Mode_RegSimult_AlterTrig):规则组同步转换被中断,以启动注入组的交替触发转换。
  • 混合同步注入+快速交叉模式(ADC_Mode_InjecSimult_FastInterl):快速交叉转换被中断,同步注入启动。
  • 混合同步注入+慢速交叉模式(ADC_Mode_InjecSimult_SlowInterl):慢速交叉转换被中断,同步注入启动。

其中,同步规则模式和快速交叉模式比较常用。


2. 扫描模式

在寄存器ADC_CR1SCAN位进行配置。

实际是一个使能位:选择单通道扫描(ENABLE)还是多通道扫描(DISABLE)。


3. 连续转换模式

在寄存器ADC_CR2CONV位进行配置。

实际是一个使能位:对通道选择采集一次(DISABLE)还是不停地重复采集(ENABLE)。


4. 外部触发源选择

寄存器ADC_CR2EXTSEL位和EXTTRIG位控制规则通道的触发源,寄存器ADC_CR2JEXTSEL位和JEXTTRIG位控制注入通道的触发源。

可参考功能框图讲解的第五节触发源。


5. 数据对齐格式

由寄存器ADC_CR2ALIGN来配置数据的左对齐或右对齐。


6. 采集通道数

由寄存器ADC_SQR1L[3:0]位或寄存器ADC_JSQRJL[1:0]位进行配置。


二、ADC常用库函数

以下为ADC常用的库函数:

void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);
void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);
void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState); // 软件触发
void ADC_ExternalTrigInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState); // 外部引脚触发
void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState);

ADC未完待续~






推荐阅读
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • 本文目录一览:1、\mysybase.dump对数据库正常使用有影响吗 ... [详细]
  • 本文主要介绍关于人工智能,shell的知识点,对【winyyy.sys,hcpidesk.sys,mtlrd.sys,uldfhjfh.sys,servets.exe等1】和【】有兴趣的朋友可以看下由 ... [详细]
  • 篇首语:本文由编程笔记#小编为大家整理,主要介绍了2D阵列选择排序相关的知识,希望对你有一定的参考价值。所以 ... [详细]
  • [更新幻灯]1剔除“伪创新”和“无领域”的领域驱动设计
    如果有人不了解人体的内部结构,就自称医生,声称自己能给人开腹割掉发炎的阑尾,甚至还能开胸给冠心病人做心脏搭桥,你信吗 ... [详细]
  • html+css网页设计源码_11个Html和CSS 动态网页背景免费代码案例
    html+css网页设计源码_11个Html和CSS 动态网页背景免费代码案例 ... [详细]
author-avatar
疯狂人儿-
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有