STM32—ADC配置


一、ADC简介

ADC是一种逐次逼近型模拟数字转换器。
有多达18个通道,可测量16个外部和2个内部信号源。
各通道的A/D转换可以单次、连续、扫描或间断模式执行。
ADC的结果可以左对齐或右对齐方式存储在16位数据寄存器中。每次转换结束、注入转换结束和发生模拟看门狗事件时产生中断。
模拟看门狗特性允许应用程序检测输入电压是否超出用户定义的高/低阀值。
ADC的输入时钟不得超过14MHz,它是由PCLK2经分频产生。

二、ADC结构框图

在这里插入图片描述

模块1:电压输入引脚

在这里插入图片描述

在这里插入图片描述

ADC 输入电压范围为: VREF- ≤ VIN ≤ VREF+。
通常把VDDA和VSSA 和 VREF-接地,把 VREF+和 VDDA 接 3.3V,因此输入范围是0-3.3V 。不要直接将高于 3.3V 的电压接到 ADC 管脚上,那样将可能烧坏芯片。

模块2:输入通道

在这里插入图片描述

STM32 的 ADC 的输入通道多达 18 个,其中外部的 16 个通道就是框图中的
ADCx_IN-15(x=1/2/3,表示 ADC 数),通过这 16 个外部通道可以采集模拟信号。
其中 ADC1 还有 2 个内部通道:ADC1 的通道 16 连接到了芯片内部的温度传感器,通道 17 连接到了内部参考电压 VREFINT。ADC2 和ADC3 的通道 16、 17 全部连接到了内部的 VSS。
在这里插入图片描述

模块3:通道转换顺序

在这里插入图片描述

外部的 16 个通道在转换的时候可分为 2 组通道:规则通道组(最多16个)和注入通道组(最多4个)。
规则通道组:类似于正常执行的程序。通常我们使用的都是这个通道。
注入通道组:类似于中断。在规则通道转换过程中,有注入通道插队,那么就要
先转换完注入通道,等注入通道转换完成后,再回到规则通道的转换流程。

每个组包含一个转换序列,该序列可按任意顺序在任意通道上完成。
1、规则通道组序列寄存器
有 3 个,最多支持16个通道( SQR1 的位 L[3:0]决定)
分别是 SQR3、 SQR2、 SQR1。
SQR3 :控制着规则序列中的第一个到第六个转换,对应位:SQ1[4:0]~SQ6[4:0]。SQR2 控制着规则序列中的第 7 到第 12 个转换,对应的位为: SQ7[4:0]~SQ12[4:0]。SQR1 控制着规则序列中的第 13 到第 16 个转换,对应位为: SQ13[4:0]~SQ16[4:0]

2、注入通道组序列寄存器:
只有一个 JSQR。它最多支持 4 个通道(由 JSQR 的 JL[2:0]决定)。
当 JL[1:0] = 3(有 4 次注入转换)时, ADC 将按以下顺序转换通道:
JSQ1[4:0]、JSQ2[4:0]、 JSQ3[4:0] 和 JSQ4[4:0]。
当 JL = 2(有 3 次注入转换)时,ADC 将按以下顺序转换通道:JSQ2[4:0]、
JSQ3[4:0] 和 JSQ4[4:0]。
当 JL = 1(有 2 次注入转换)时,ADC 转换通道的顺序为:先是 JSQ3[4:0],
而后是 JSQ4[4:0]。
当 JL = 0(有 1 次注入转换)时, ADC 将仅转换 JSQ4[4:0] 通道。
如果在转换期间修改 ADC_SQRx 或 ADC_JSQR 寄存器,将复位当前转换并向
ADC 发送一个新的启动脉冲,以转换新选择的通道组。

模块4:触发源

在这里插入图片描述

选择好输入通道,设置好转换顺序之后,就可以开始转换。要开启 ADC转换,可以直接设置 ADC 控制寄存器 ADC_CR2 的 ADON 位为 1,即使能 ADC。
在这里插入图片描述

                    图:ADC控制寄存器2

ADON:开/关A/D转换器 (A/D converter ON / OFF)
该位由软件设置和清除。当该位为’0’时,写入’1’将把ADC从断电模式下唤醒。
当该位为’1’时,写入’1’将启动转换。应用程序需注意,在转换器上电至转换开始有一个延迟 tSTAB
0:关闭ADC转换/校准,并进入断电模式; 1:开启ADC并启动转换。
注:如果在这个寄存器中与ADON一起还有其他位被改变,则转换不被触发。这是为了防止触 发错误的转换。

ADC 还支持外部事件触发转换,触发源有很多,具体选择哪一种触发源,由ADC_CR2 的 EXTSEL[2:0]和 JEXTSEL[2:0]位来控制。

JEXTSEL[2:0]:选择启动注入通道组转换的外部事件 (External event select for injected
group) 这些位选择用于启动注入通道组转换的外部事件。 ADC1和ADC2的触发配置如下 000:定时器1的TRGO事件
100:定时器3的CC4事件 001:定时器1的CC4事件 101:定时器4的TRGO事件
110:EXTI线15/TIM8_CC4事件(仅大容量产品具有TIM8_CC4) 010:定时器2的TRGO事件
011:定时器2的CC1事件 111:JSWSTART ADC3的触发配置如下 000:定时器1的TRGO事件
100:定时器8的CC4事件 001:定时器1的CC4事件 101:定时器5的TRGO事件 010:定时器4的CC3事件
110:定时器5的CC4事件 011:定时器8的CC2事件 111:JSWSTART

EXTSEL[2:0]:选择启动规则通道组转换的外部事件 (External event select for regular group)
位19:17 这些位选择用于启动规则通道组转换的外部事件 ADC1和ADC2的触发配置如下 000:定时器1的CC1事件
100:定时器3的TRGO事件 001:定时器1的CC2事件 101:定时器4的CC4事件 110:EXTI线11/
TIM8_TRGO事件,仅大容量产品具有TIM8_TRGO功能 010:定时器1的CC3事件 011:定时器2的CC2事件
111:SWSTART ADC3的触发配置如下 000:定时器3的CC1事件 100:定时器8的TRGO事件
001:定时器2的CC3事件 101:定时器5的CC1事件 010:定时器1的CC3事件 110:定时器5的CC3事件
011:定时器8的CC1事件 111:SWSTART

选定好触发源之后,触发源是否要激活,则由 ADC 控制寄存器 ADC_CR2 的 EXTTRIG 和JEXTTRIG 这两位来激活。

JEXTTRIG:注入通道的外部触发转换模式 (External trigger conversion mode for injected
channels) 该位由软件设置和清除,用于开启或禁止可以启动注入通道组转换的外部触发事件。 0:不用外部事件启动转换;
1:使用外部事件启动转换。

JSWSTART:开始转换注入通道 (Start conversion of injected channels)
由软件设置该位以启动转换,软件可清除此位或在转换开始后硬件马上清除此位。如果在
JEXTSEL[2:0]位中选择了JSWSTART为触发事件,该位用于启动一组注入通道的转换, 0:复位状态; 1:开始转换注入通道

如果使能了外部触发事件 ,我们还可以通过设置 ADC_CR2 的 EXTEN[1:0]和 JEXTEN[1:0]来控制触发极性,可以有 4 种状态,分别是:禁止触发检测、上升沿检测、下降沿检测以及上升沿和下降沿均检测。

模块5:ADC时钟

在这里插入图片描述

ADC 输入时钟 ADC_CLK 由 APB2 经过分频产生,最大值是 14MHz,
在这里插入图片描述

               图:ADC挂接在APB2上

分频因子由 RCC 时钟配置寄存器 RCC_CFGR 的位 15:14 ADCPRE[1:0]设置
在这里插入图片描述

      图:RCC 时钟配置寄存器 RCC_CFGR

ADCPRE[1:0]:ADC预分频 (ADC prescaler) 位15:14 由软件置’1’或清’0’来确定ADC时钟频率
00:PCLK2 2分频后作为ADC时钟 01:PCLK2 4分频后作为ADC时钟 10:PCLK2 6分频后作为ADC时钟
11:PCLK2 8分频后作为ADC时钟
此处没有一份频,ADC最大时钟为14M,因此分频系数6,得到12M的时钟

ADC 要完成对输入电压的采样需要若干个 ADC_CLK 周期,采样的周期数可通
过 ADC 采样时间寄存器 ADC_SMPR1 和 ADC_SMPR2 中的 SMP[2:0]位设置,

在这里插入图片描述

图:ADC采样时间寄存器 1(控制通道0-9,
                  如果是寄存器2则控制10-17)

SMPx[2:0]:选择通道x的采样时间 (Channel x Sample time selection)
这些位用于独立地选择每个通道的采样时间。在采样周期中通道选择位必须保持不变。 000:1.5周期 100:41.5周期
001:7.5周期 101:55.5周期 010:13.5周期 110:71.5周期 011:28.5周期
111:239.5周期 注:ADC1的模拟输入通道16和通道17在芯片内部分别连到了温度传感器和VREFINT。
ADC2的模拟输入通道16和通道17在芯片内部连到了Vss。 ADC3模拟输入通道14、15、16、17与Vss相连

ADC 的总转换时间跟 ADC 的输入时钟和采样时间有关,其公式如下:
Tconv(ADC总转换时间) = 采样时间(最小周期为1.5)+ 12.5 个周期

最短Tcovn=1.5+12.5=14 个周期=1us。通常经过 ADC 预分频器能分频到最大的时钟只能是 12M,采样周期设置为 1.5 个周期,算出最短的转换时间为 1.17us,这个才是最常用的。

模块6:数据寄存器

在这里插入图片描述

规则组的数据放在 ADC_DR 寄存器内,注入组的数据放在 JDRx 内。
在这里插入图片描述

         图:ADC规则数据寄存器ADC_DR

在这里插入图片描述

         图:ADC注入数据寄存器x ADC_JDRx

ADC 是 12 位转换精度,而数据寄存器是 16 位,所以 ADC在存放数据的时候就有左对齐和右对齐区分。通过 ADC_CR2 的 11 位 ALIGN 设置。

ALIGN:数据对齐 (Data alignment) 该位由软件设置和清除。参考图29和图30。 0:右对齐; 1:左对齐。

(1)规则组中,含有 16 路通道,对应着存放规则数据的寄存器只有 1 个,如
果使用多通道转换,那么转换后的数据就全部挤在 ADC_DR 寄存器内,前一个时
间点转换的通道数据,就会被下一个时间点的另外一个通道转换的数据覆盖掉。
解决方法:
1)最常使用的是开启 DMA 模式,把数据传输到内存里面,不然就会造成数据的覆盖。
2)我们一般通过 ADC 状态寄存器 ADC_SR 获取当前 ADC 转换的进度状态,进而进行程序控制,在通道转换完成后就应该把数据取走

(2)注入组中,最多含有 4 路通道,对应着存放注入数据的寄存器正好有 4
个,不会跟规则寄存器那样产生数据覆盖的问题。

模块7:中断

在这里插入图片描述

发生如下事件且使能相应中断标志位时,ADC 能产生中断。
①转换结束(规则转换与注入转换)
数据转换结束后,如果使能中断转换结束标志位,转换一结束就会产生转换
结束中断。
②模拟看门狗事件
当被 ADC 转换的模拟电压低于低阈值或者高于高阈值时,就会产生中断,
前提是我们开启了模拟看门狗中断,其中低阈值和高阈值由 ADC_LTR 和
ADC_HTR 设置。
③DMA 请求
规则和注入通道转换结束后,除了产生中断外,还可以产生 DMA 请求,把
转换好的数据直接存储在内存里面。要注意的是只有 ADC1 和 ADC3 可以产
生 DMA 请求。一般我们在使用 ADC 的时候都会开启 DMA 传输。

ADC转换模式有单次转换与连续转换区分。
在单次转换模式下,ADC 执行一次转换。可以通过 ADC_CR2 寄存器的SWSTART 位(只适用于规则通道)启动,也可以通过外部触发启动(适用于规则通道和注入通道),这时 CONT 位为 0。
以规则通道为例,一旦所选择的通道转换完成,转换结果将被存在 ADC_DR 寄存器中,EOC(转换结束)标志将被置位,如果设置了 EOCIE,则会产生中断。然后 ADC 将停止,直到下次启动。
在连续转换模式下,ADC 结束一个转换后立即启动一个新的转换。CONT 位为 1 时,可通过外部触发或将 ADC_CR2 寄存器中的 SWSTRT 位置 1 来启动此模式(仅适用于规则通道)。
需要注意的是:此模式无法连续转换注入通道。连续模式下唯一的例外情况是,注入通道配置为在规则通道之后自动转换(使用JAUTO 位)。

二、ADC配置步骤

1.ADC初始化

void ADCx_Init(void)  
{ 
//使能端口时钟和 ADC 时钟,设置引脚模式为模拟输入
GPIO_InitTypeDef GPIO_InitStructure; //定义结构体变量 
ADC_InitTypeDef ADC_InitStructure; 
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1,ENABLE); 

//设置 ADC 的分频因子
RCC_ADCCLKConfig(RCC_PCLK2_Div6);//设置 ADC 分频因子 6 72M/6=12,ADC 最大时间不能超过14M 

//初始化 ADC 参数,包括 ADC 工作模式、规则序列等  
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;//ADC 
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN; //模拟输入 
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; 
GPIO_Init(GPIOA,&GPIO_InitStructure); 
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //独立模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE;//非扫描模式 
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//关闭连续转换 
24. ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//禁止 
触发检测,使用软件触发 
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐 
ADC_InitStructure.ADC_NbrOfChannel = 1;//1 个转换在规则序列中 也就是只转换规则序列 1 
ADC_Init(ADC1, &ADC_InitStructure);//ADC 初始化 

//使能 ADC 并校准
ADC_Cmd(ADC1, ENABLE);//开启 AD 转换器 
ADC_ResetCalibration(ADC1);//重置指定的 ADC 的校准寄存器 
while(ADC_GetResetCalibrationStatus(ADC1));//获取 ADC 重置校准寄存器的状态 
ADC_StartCalibration(ADC1);//开始指定 ADC 的校准状态 
while(ADC_GetCalibrationStatus(ADC1));//获取指定 ADC 的校准程序 
ADC_SoftwareStartConvCmd(ADC1, ENABLE);//使能或者失能指定的 ADC 的软件转换启 
} 

2.ADC获取函数

u16 Get_ADC_Value(u8 ch,u8 times) 
9. 
{ 
u32 temp_val=0; 
u8 t; 
//设置指定 ADC 的规则组通道,一个序列,采样时间 
ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5); 
//ADC1,ADC 通道,239.5 个周期,提高采样时间可以提高精确度 
for(t=0;t<times;t++) 
{ 
ADC_SoftwareStartConvCmd(ADC1, ENABLE);//使能指定的 ADC1 的软件转换启动功能 
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束 
temp_val+=ADC_GetConversionValue(ADC1); 
delay_ms(5); 
} 
return temp_val/times; 
} 
  • 8
    点赞
  • 75
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值