超详细!!STM32-ADC模数转换器-驱动内部温度传感器

一、模数转换器概述

  在STM32微控制器系列中,ADC(Analog-to-Digital Converter)是一个重要的外设模块,它允许微控制器将模拟信号转换成数字信号以进行处理。模拟信号–>数字信号。
   MCU只能处理数字量(10011001),如果需要MCU区分模拟输入信号时,MCU直接做不了,需要将模拟信号通过模数转换器,转成数字量供MCU处理。模数转换器一般用在各类传感器〈光敏电阻)上,还有部分用在音视频处理上。

二、模数转换器分类

(1)并联比较型

超详细!!STM32-ADC模数转换器-驱动内部温度传感器_第1张图片

(2)逐次逼近型(天平称重原理类型)

  转换开始前先将所有寄存器清零。开始转换以后,时钟脉冲首先将寄存器最高位置成1,使输出数字为100···0。这个数码被D/A转换器转换成相应的模拟电压Uo,送到比较器中与Ui进行比较。
  若Ui   若Ui>Uo,说明数字还不够大,应将这一位保留。然后,再按同样的方式将下一次高位置成1 ,再继续进行比较。(加砝码)
  并且经过比较以后确定这个1是否应该保留。这样逐位比较下去,一直到最低位为止。比较完毕后,寄存器中的状态就是所要求的数字量输出。

三、模数转换器主要参数

   分辨率:它表明A/D对模拟信号的分辨能力,由它确定能被A/D辨别的最小模拟量变化。通常为8,10,12,16位等。如电压为0~3.3v,分辨率为4096,则可识别最小A/D模拟量变化为 3.3/ 4096 v。
   转换时间:转换时间是A/D完成一次转换所需要的时间。一般转换速度。越快越好。

四、STM32中的模数转换器

  分辨率12位(最高)ADC是逐次趋近型模数转换器。它具有多达19个复用通道,可测量来自16众外部源、两个内部源和VBAT通道的信号。这些通道的A/D转换可在单次、连续、扫描或不连续采样模式下进行。ADC的结果存储在一个左对齐或右对齐的16位数据寄存器中。
  ADC具有模拟看门狗特性,允许应用检测输入电压是否超过了用户自定义的阈值上限或下限。

1. 主要特性:

   ●12位分辨率
   ● 转换结束、注入转换结束和发生模拟看门狗事件时产生中断
   ● 单次和连续转换模式
   ● 从通道0到通道n的自动扫描模式
   ● 自校准
   ● 带内嵌数据一致性的数据对齐
   ● 采样间隔可以按通道分别编程
   ● 规则转换和注入转换均有外部触发选项
   ● 间断模式
   ● 双重模式(带2个或以上ADC的器件)

2. 框图:

超详细!!STM32-ADC模数转换器-驱动内部温度传感器_第2张图片
超详细!!STM32-ADC模数转换器-驱动内部温度传感器_第3张图片

3. 功能分析:

(1) ADC开关控制

  可通过将 ADC_CR2寄存器中的 ADON位置1来为ADC供电。首次将ADON位置1时,会将ADC 从掉电(低功耗)模式中唤醒。SWSTART或JSWSTART位置1时,启动AD 转换。
  可通过将 ADON位清零来停止转换,并使ADC进入掉电(低功耗)模式。在此模式下ADC 几乎不耗电(只有几A)。
超详细!!STM32-ADC模数转换器-驱动内部温度传感器_第4张图片

(2) ADC时钟

ADC具有两个时钟方案:
  用于数字接口的时钟:(用于寄存器读/写访问)此时钟等效于APB2时钟。可以通过 RCC APB2外设时钟使能寄存器(RCC_APB2ENR)分别为每个ADC使能/禁止数字接口时钟。
  用于模拟电路的时钟:ADCCLK,所有ADC共用此时钟来自于经可编程预分频器分频的APB2时钟,该预分频器允许ADC在fpclk2/2、/4、/6或/8下工作。有关ADCCLK的最大值,请参见数据手册。

(3)通道选择

  有16条复用通道。可以将转换分为两组:规则转换(规则组)和注入转换(注入组)。每个组包含一个转换序列,该序列可按任意顺序在任意通道上完成。例如,可按以下顺序对序列进行转换: ADC_IN3、ADC_IN8、ADC_IN2、ADC_IN2、ADC_INO、ADC_IN2、ADC_IN2、ADC_IN15。
  一个规则转换组最多由16个转换构成。必须在ADC_SQRx寄存器中选择转换序列的规则通道及其顺序。规则转换组中的转换总数必须写入ADC_SQR1寄存器中的 L[3:0]位。
超详细!!STM32-ADC模数转换器-驱动内部温度传感器_第5张图片

  一个注入转换组最多由4个转换构成。必须在 ADC_JSQR寄存器中选择转换序列的注入通道及其顺序。注入转换组中的转换总数必须写入ADC_JSQR寄存器中的L[1:0]位。
在这里插入图片描述

  如果在转换期间修改 ADC_SQRx或 ADC_JSQR寄存器,将复位当前转换并向ADC发送一个新的启动脉冲,以转换新选择的组。

(4)转换模式

●单次转换模式:

在单次转换模式下,ADC执行一次转换。CONT位为0时,可通过以下方式启动此模式:
在这里插入图片描述

适用规则通道:将 ADC_CR2寄存器中的 SWSTART位置1。
适用注入通道:将JSWSTART位置1。
适用规则通道或注入通道:外部触发,完成所选通道的转换之后。

如果转换了规则通道:
   转换数据存储在16位 ADC_DR寄存器中—EOC(转换结束)标志置1。
   EOCIE位置1时将产生中断。
如果转换了注入通道:
  转换数据存储在16位 ADC_JDR1寄存器中一JEOC(注入转换结束)标志置1。
  JEOCIE位置1时将产生中断。
然后,ADC停止。

●连续转换模式:(仅适用于规则通道)

  在连续转换模式下, ADC 结束一个转换后立即启动一个新的转换。 CONT 位为 1 时,可通过外部触发或将 ADC_CR2 寄存器中的 SWSTRT 位置 1 来启动此模式。
在这里插入图片描述
每次转换之后:
  上次转换的数据存储在16 位 ADC_DR 寄存器中。
  EOC(转换结束)标志置 1。
  EOCIE 位置1时将产生中断。
  注意: 无法连续转换注入通道。连续模式下唯一的例外情况是,注入通道配置为在规则通道之后自动转换(使用 JAUTO 位),请参见自动注入一节。

●扫描模式: (此模式用于扫描一组模拟通道)

  通过将 ADC_CR1寄存器中的 SCAN位置1来选择扫描模式。将此位置1后,ADC会扫描在ADC_SQRx寄存器(对于规则通道)或ADC_JSQR寄存器(对于注入通道)中选择的所有通道。为组中的每个通道都执行一次转换。每次转换结束后,会自动转换该组中的下一个通道。如果将CONT位置1,规则通道转换不会在组中最后一个所选通道处停止,而是再次从第一个所选通道继续转换。
超详细!!STM32-ADC模数转换器-驱动内部温度传感器_第6张图片

  如果将 DMA位置1,则在每次规则通道转换之后,均使用直接存储器访问(DMA)控制器将转换自规则通道组的数据(存储在ADC_DR寄存器中)传输到SRAM。

在以下情况下,ADC_SR寄存器中的EOC位置1:
  如果EOCS位清零,在每个规则组序列转换结束时
  如果 EOCS位置1,在每个规则通道转换结束时
  从注入通道转换的数据始终存储在 ADC_IDRx寄存器中。

(5)注入通道管理

●触发注入(类似于中断,优先级:注入组 >规则组)
  要使用触发注入,必须将 ADC_CR1寄存器中的 JAUTO位清零。
  1.通过外部触发或将ADC_CR2寄存器中的 SWSTART位置1来启动规则通道组转换。
  2.如果在规则通道组转换期间出现外部注入触发或者JSWSTART位置1,则当前的转换会复位,并且注入通道序列会切换为单次扫描模式。
  3.然后,规则通道组的规则转换会从上次中断的规则转换处恢复。
  如果在注入转换期间出现规则事件,注入转换不会中断,但在注入序列结束时会执行规则序列。图37 显示了相应的时序图。
  注意:使用触发注入时,必须确保触发事件之间的间隔长于注入序列。例如,如果序列长度为30个ADC时钟周期(即,采样时间为3个时钟周期的两次转换),则触发事件的最小间隔不能小于31个ADC时钟周期。

●自动注入(相当于注入组的连续转换,但必须跟在规则组的连续转换之后转换)
  如果将JAUTO位置1,则注入组中的通道会在规则组通道之后自动转换。
  这可用于转换最多由20个转换构成的序列,这些转换在ADC_SQRx和 ADC_JSQR寄存器中编程。
  在此模式下,必须禁止注入通道上的外部触发。如果CONT位和 JAUTO位均已置1,则在转换规则通道之后会继续转换注入通道。

;注意:不能同时使用自动注入和不连续采样模式。

(6)数据对齐

  ADC_CR2寄存器中的ALIGN位用于选择转换后存储的数据的对齐方式。可选择左对齐或右对齐两种方式,如图38和图39所示。
  注入通道组的转换数据将减去 ADC_JOFRx寄存器中写入的用户自定义偏移量,因此结果可以是一个负值。SEXT位表示扩展的符号值。
  对于规则组中的通道,不会减去任何偏移量,因此只有十二个位有效。

超详细!!STM32-ADC模数转换器-驱动内部温度传感器_第7张图片

(7)独立通道的采样时间设置

  ADC会在数个ADC_CLK周期内对输入电压进行采样,可使用ADC_SMPR1 和 ADC_SMPR2寄存器中的SMP[2:0]位修改周期数。每个通道均可以使用不同的采样时间进行采样。
超详细!!STM32-ADC模数转换器-驱动内部温度传感器_第8张图片

总转换时间的计算公式如下:
Tconv =采样时间+12个周期
示例:若ADC_CLK = 30 MHz 且采样时间=3个周期时:
Tconv= 3 + 12= 15 个周期 =15/30 us =0.5 us

(8)快速转换模式

  可通过降低ADC分辨率来执行快速转换。RES位用于选择数据寄存器中可用的位数。每种分辨率的最小转换时间如下:
12位:3+12= 15 ADCCLK周期
10位:3+ 10= 13 ADCCLK周期
8位:3+8= 11 ADCCLK周期
6位:3+6= 9 ADCCLK周期

五、实验

1. 实验内容:

通过ADC采集STM32内部温度传感器。

2. 实验分析:

  温度传感器可用于测量器件的环境温度。对于STM32F40x和 STM32F41x器件,温度传感器内部连接到ADC1_IN16 通道,使用ADC1 将传感器输出电压转换为数字值。
  不使用时可将传感器置于掉电模式。
  注意:必须将TSVREFE位置1才能同时对两个通道进行转换。ADC1_IN16或ADC1_IN18(温度传感器)和ADC1_IN17 (VREFINT)。
超详细!!STM32-ADC模数转换器-驱动内部温度传感器_第9张图片

超详细!!STM32-ADC模数转换器-驱动内部温度传感器_第10张图片

3. 温度转换公式:

超详细!!STM32-ADC模数转换器-驱动内部温度传感器_第11张图片

超详细!!STM32-ADC模数转换器-驱动内部温度传感器_第12张图片

假设现有采集到的AD值为adVal。按照公式:
0- 3.3V按照12bitADC进行采样==区间为0-4095 ,相当于将3.3V分为4096份,每一个份的电压值为3.3V /4096 =0.0008056640625 V。
VSENSE= adVal*3.3V/4096。

Tempture=( adVal * 3.3V / 4096 - 0.76 ) /2.5 +25。

4. 软件配置流程:

  1. 打开ADC1时钟。
  2. 使能温度传感器通道。
  3. 配置ADC分频。
  4. 配置好CR1、CR2。
  5. 构造规则组–转换序列长度1,序列顺序16。
  6. 设置ADC_IN16通道采样时间。
  7. 使能ADC。
  8. 将CR2中的SWSTART位置1–开始转换
  9. 等待EOC完成标志。
  10. 读取转换结果。
  11. 失能ADC。

5. 代码实现:

void ADC1_IN16_Init (void)
{
	RCC->APB2ENR |=(0x1 <<8);//1.打开ADC1时钟
	ADC->CCR |=(0x1 <<23);  //2.使能温度传感器通道
	ADC->CCR &=~(0x3 <<16);  //3.配置ADC分频 
	ADC->CCR |= (0x1 <<16); //4分频84Mhz /4=21Mhz 
	
 //4.配置好CR1、CR2
	ADC1->CR1 =0;//整体清零
	/*
	*12bit分辨率
	*禁止规则通道不连续采样*禁止扫描模式
	*/
	ADC1->CR2 =0;//整体清零
	ADC1->CR2l=(0xl<<10);//每个规则通道转换,将Eoc置一
	/*
	*禁止规则通道外部触发
	*数据右对齐
	*单次转换*/
	
//5.构造规则组-转换序列长度1,序列顺序16
	ADC1->SQR1 &=~ (0xF <<20);//规则序列长度=1
	ADC1->SQR3 &=~ (0x1F <<0);
	ADC1->SQR3 |=(16<<0);//第一次转换通道16
	ADC1->SMPR1 |=(0x7<<18);//6.设置ADc IN16通道采样时间 480 + 12=23.4us
	
}

ul6 ADC1_ReadDate (void)
{
	ul6 adval;
	ADC1->CR2 |=(0x1 <<0);//7.使能ADC
	ADC1->CR2 |=(0x1<< 30); //8.将CR2中的SWSTAET位置1--开始转换
	
	while( !(ADC1->SR &(0x1<<1)) );//9.等待EOC置1
	ADC1->SR &=~(0x1 <<1);//清除EOC标志
	ad = ADC1->DR; //10.读取转换结果
	ADC1->CR2 &= ~(0x1 <<0);//11.失能ADC
	
	return adval;
}


//-------------------------主函数main.c内容
void main(void)
{
	u16 r_adval;
	float tempture;
	ADC1_IN16_Init();
	
	while(1)
	{
	  r_adval =ADC1_ReadDate();
	  tempture=(r_adval * 3.3 / 4096-0.76) /2.5 +25;
	  printf("tempture=%f\n",tempture);
	  delay_ms(500);
	}

}

你可能感兴趣的:(stm32,嵌入式硬件,单片机)