STM32学习笔记(18)ADC转换介绍

ADC介绍

ADC:Analog-to-Digital Converter,指模/数转换器或者模拟/数字转换器。是指将连续变量的模拟信号转换为离散的数字信号的器件。(典型的模拟数字转换器将模拟信号转换为表示一定比例电压值的数字信号。)

总而言之,就是获取某个引脚上的模拟信号,通过比例,转化为相应的数字信号。

数字信号与模拟信号的区别

STM32F10x ADC特点

  • 12位逐次逼近型的模拟数字转换器。
  • 最多带3个ADC控制器
  • 最多支持18个通道,可最多测量16个外部和2个内部信号源。
  • 支持单次和连续转换模式
  • 转换结束, 注入转换结束,和发生模拟看门狗事件时产生中断
  • 通道0到通道n的自动扫描模式
  • 自动校准
  • 采样间隔可以按通道编程
  • 规则通道和注入通道均有外部触发选项
  • 转换结果支持左对齐或右对齐方式存储在16位数据寄存器
  • 转换时间:最大转换速率1us。( 最大转换速度为1MHz,在ADCCLK=14M,采样周期为1.5个ADC时钟下得到。)
  • 供电要求: 2.4V-3.6V
  • 输入范围: VREF-(模拟参考负极)≤ ViN≤VREF+(模拟参考正极)

相应通道对应的引脚

在这里插入图片描述
如图,STM32F03ZET6芯片有3个ADC控制器,可测量 16 个外部和 2 个内部信号源。(红色部分表示部分开发板无相应引脚,但芯片有该功能

ADC基本原理

工作框图

在这里插入图片描述

ADC引脚

左上角是ADC的引脚,名称对应的信号类型与介绍如下图
在这里插入图片描述

时钟设置

由时钟控制器提供的ADCCLK时钟和PCLK2(APB2时钟)同步。 RCC控制器为ADC时钟提供一个
专用的可编程预分频器。

一般设置PCLK2为72MHz,为了不超过14MHz(超过14MHz的话会不准),分频设置为6或8分频。分频可通过下面的RCC_CFGR寄存器相应位进行设置
在这里插入图片描述

ADC通道类别

STM32 将 ADC 的通道分为 2 个组:规则通道组和注入通道组。规则通道相当于正常运行的程序,而注入通道呢,就相当于中断。如下图:

  • 规则通道组由至多16个通道组成。规则通道和它们的转换顺序在ADC_SQRx寄存器中选择。规则组中转换的总数应写入ADC_SQR1寄存器的L[3:0]位中。
  • 注入通道组由至多4个通道组成。注入通道和它们的转换顺序在ADC_JSQR寄存器中选择。注入组里的转换总数目应写入ADC_JSQR寄存器的L[1:0]位中。

规则通道组就是一般的显示,而注入通道组就是在需要时才显示出来。

例如,你在室外放了 5 个温度探头,室内放了 3 个温度探头; 你需要时刻监视室外温度即可,但偶尔想看看室内的温度;此时你可以使用规则通道组循环扫描室外的 5 个探头并显示 AD 转换结果,当你想看室内温度时,通过一个按钮启动注入转换组(3 个室内探头)并暂时显示室内温度,当你放开这个按钮后,系统又会回到规则通道组继续检测室外温度。如果没有规则组和注入组的划分,当你按下按钮后,需要从新配置 AD 循环扫描的通道,然后在释放按钮后需再次配置 AD 循环扫描的通道

在这里插入图片描述

通道转换方式

不开启SCAN:

  • 单次转换:转换到下一个通道,停止,等待下一次开启转换(停下的意思是不再扫描,之前扫描的不再改变)
  • 连续转换:转换到下一个通道,不停止,回到第一步继续(即不断扫描一个通道)

开启SCAN:

  • 单次转换:从第一个通道开始,转换整个序列后停止,等待下一次开启转换。
  • 连续转换:持续不断地扫描一个序列。

开不开启SCAN就是所谓的扫描模式

示例:以序列为CH0,CH1,CH2,CH3为例
不开启SCAN:

  • 单次转换:开启,转换到CH0,停止。等待下一次开启再次扫描CH0(不管第几次开启)
  • 连续转换:开启后,转换到CH0,持续不断扫描CH0。

开启SCAN:

  • 单次转换:从CH0开始,轮流转换到CH1,CH2,CH3整个序列后停止,等待下一次开启转换。
  • 连续转换:持续不断地扫描CH0,CH1,CH2,CH3。

ADC相应中断

规则和注入组转换结束时能产生中断。它们都有独立的中断使能位。

ADC1和ADC2的中断映射在同-一个中断向量上,而ADC3的中断有自己的中断向量。

ADC_SR寄存器中有2个其他标志,但是它们没有相关联的中断;

  • JSTRT(注入组通道转换的启动)
  • STRT(规则组通道转换的启动)
中断事件事件标志使能控制位
规则组转换结束EOCEOCIE
注入组转换结束JEOCJEOCIE
设置了模拟看门狗状态位AWDAWDIE

通道采样时间

ADC使用若干个ADC_CLK周期对输入电压采样,采样时间可以通过ADC_SMPR1和ADC_SMPR2寄存器中的SMP[2:0]位更改。每个通道可以分别用不同的时间采样。

总转换时间如下计算:
T= 采样时间+ 12.5个周期
例如:
当ADC_CLK=14MHz,采样时间为1.5周期
T= 1.5 + 12.5 = 14周期 = 1μs

当使用触发的注入转换时,必须保证触发事件的间隔长于注入序列。例如:序列长度为28个ADC时钟周期(即2个具有1.5个时钟间隔采样时间的转换),触发之间最小的间隔必须是29个ADC时钟周期

校准

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

通过设置ADC_CR2寄存器的CAL位启动校准。一旦校准结束, CAL位被硬件复位,可以开始正常转换。建议在上电时执行一次ADC校准。校准阶段结束后,校准码储存在ADC_DR中。

注意:
1 建议在每次上电后执行一次校准。
2 启动校准前, ADC必须处于关电状态(ADON=’0’)超过至少两个ADC时钟周期。

配置步骤

以PA1口为例:
1) 开启 PA 口时钟和 ADC1 时钟,设置 PA1 为模拟输入。
2) 复位 ADC1,同时设置 ADC1 分频因子。
3) 初始化 ADC1 参数, 设置 ADC1 的工作模式以及规则序列的相关信息。
4) 使能 ADC 并校准。
5)配置规则通道参数。
6) 开启软件转换。
7) 等待转换完成后,读取 ADC 值。

相关结构体

typedef struct
{
  uint32_t ADC_Mode;     //ADC工作模式 (独立或双重模式)                
  FunctionalState ADC_ScanConvMode;  //是否使用扫描模式     
  FunctionalState ADC_ContinuousConvMode; //单次或连续转换
  uint32_t ADC_ExternalTrigConv;          //触发方式:软件或外部触发
  uint32_t ADC_DataAlign;                 //对齐方式:左或右
  uint8_t ADC_NbrOfChannel;           //规则通道序列长度    
}ADC_InitTypeDef;

代码示例

ACD初始化

以PA1口为例:

void  Adc_Init(void)
{ 	
	ADC_InitTypeDef ADC_InitStructure; 
	GPIO_InitTypeDef GPIO_InitStructure;//相关结构体初始化

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1, ENABLE );//使能ADC1通道时钟
 
    RCC_ADCCLKConfig(RCC_PCLK2_Div6); //72M/14M=5.14,ADC最大时间不能超过14M,因此分频因子至少为6

	//PA1 作为模拟通道输入引脚                         
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;		//模拟输入引脚
	GPIO_Init(GPIOA, &GPIO_InitStructure);	

    ADC_DeInit(ADC1);  //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值(缺省值:即默认值)

	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;	//ADC工作模式:ADC1和ADC2工作在独立模式
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;	//模数转换工作在单通道模式
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;	//模数转换工作在单次转换模式
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;	//转换由软件而不是外部触发启动
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;	//ADC数据右对齐
	ADC_InitStructure.ADC_NbrOfChannel = 1;	//顺序进行规则转换的ADC通道的数目
	
	ADC_Init(ADC1, &ADC_InitStructure);	//根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器   

    ADC_Cmd(ADC1, ENABLE);	//使能指定的ADC1
	
	ADC_ResetCalibration(ADC1);	//使能复位校准  
	
	while(ADC_GetResetCalibrationStatus(ADC1));	//等待复位校准结束(判断标志位)
	
	ADC_StartCalibration(ADC1);	 //开启AD校准
 
	while(ADC_GetCalibrationStatus(ADC1));	 //等待校准结束
}				  

获取数据

u16 Get_Adc(u8 ch)   //ch:通道值 0~3
{
  	//设置指定ADC的规则组通道,一个序列,采样时间
	ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 );	//ADC1,ADC通道,采样时间为239.5周期	  			    
  
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);		//使能指定的ADC1的软件转换启动功能	
	 
	while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束

	return ADC_GetConversionValue(ADC1);	//返回最近一次ADC1规则组的转换结果
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值