
计算机、数字通讯等数字系统是处理数字信号的电路系统。 然而,在实际应用中,遇到的大都是连续变化的模拟量,因此,需要一种接口电路将模拟信号转换为数字信号。A/D转换器正是基于这种要求应运而生的。
A/D转换器具有四个功能:采样、保持、量化、编码。
采样: 按相等的时间间隔从模拟信号上截取一系列离散电压瞬时值。
保持: 由于后续的量化过程需要一定的时间τ,对于随时间变化的模拟输入信号,要求瞬时采样值在时间τ内保持不变,这样才能保证转换的正确性和转换精度,这个过程就是采样保持。正是有了采样保持,实际上采样后的信号是阶梯形的连续函数。
量化: 按分层原理,将截取的值数量化。分层值N越大,量化值越接近于实际值。N也表示用几位二进制位表示模拟信号的数值。
编码: 将量化的数值用二进制数表示出来。
逐次逼近法每进行一次比较,即决定一个码的去留(0或1)需要8个时钟脉冲,所以8位转换器完成一次转换 大约需要8*8=64个CLK。
STM32 ADC主要特征
12位分辨率
多达18个通道,可测量16个外部和2个内部信号源
ADC的输入时钟不得超过14MHz,它是由PCLK2经分频产生
转换结束、注入转换结束和发生模拟看门狗事件时产生中断
单次和连续转换模式
从通道0到通道n的自动扫描模式
带内嵌数据一致性的数据对齐
采样间隔可以按通道分别编程
规则转换和注入转换均有外部触发选项
间断模式
双重模式(带2个或以上ADC的器件)
ADC转换时间:
STM32F103xx 增强型产品: 时钟为56MHz 时为 1us( 时钟为 72MHz 为 1.17us)
ADC供电要求:2.4V到3.6V
ADC输入范围:VREF- ≤ VIN ≤ VREF+
规则通道转换期间有DMA请求产生
ADC功能描述
由时钟控制器提供的ADCCLK时钟和PCLK2 (APB2时钟) 同步。
RCC 控制器为 ADC 时钟提供一个专用的可编程预分频器
可以把多个转换组织成两组:规则组和注入组
规则组由多达 16 个转换组成
注入组由多达 4 个转换组成
在任意多个通道上以任意顺序进行的一系列转换构成成组转换

模拟看门狗
如果被ADC转换的 模拟电压低于低阀值或高于高阀值 , AWD模拟看门狗状态位被设置。阀值位于ADC_HTR和 ADC_LTR寄存器的最低12个有效位中。通过设置 ADC_CR1寄存器的AWDIE位以允许产生相应中断。
需要注意的是:阀值独立于由ADC_CR2寄存器上的 ALIGN位选择的数据对齐模式。比较是在对齐之前完成 的。也就是说,在数据保存到数据寄存器之前,就已经 完成了比较。


ADC的使用过程
配置
校准
启动
采样
转换
读取转换结果
为什么要校准?
内部电容器组的变化会造成的准精度误差
ADC有一个内置自校准模式,可以对误差进行校准
在校准期间,在每个电容器上都会计算出一个误差修正码 ( 数字值) ,这个码用于消除在随后的转换中每个电容器上产生的误差
什么时候要校准?
在上电时执行一次 ADC 校准
采样是获得需要进行转换的输入模拟电压
采样需要一定的时间以达到稳定状态
采样的时间要充足
ADC使用若干个ADC_CLK周期对输入电压采样,周期数可配置
每个通道可以分别用不同的时间采样
总转换时间计算
TCONV = 采样时间 + 12.5 个周期
例: ADCCLK=14MHz ,采样时间为 1.5 周期
TCONV = 1.5 + 12.5 = 14 周期 = 1 微秒



每个 ADC 有 18 个转换通道; 16 个外部通道、 2 个内部通道(温度传感器、内部参考电压)如图 3.7 所示。 STM32 的 ADC 是 12 位逐次逼近型的模拟数字转换器。它有 18 个通道,可测量 16 个外部和 2 个内部信号源。各通道的 A/D 转换可以单次、连续、扫描或 间断模式执行。ADC 的结果可以左对齐或右对齐方式存储在 16 位数据寄存器中。模拟看门狗特性允许应用程序检测输入电压是否超出用户定义的高/ 低阀值。
STM32 将 ADC 的转换分为 2 个通道组:规则通道组和注入通道组。规则通道相当于你
正常运行的程序,而注入通道呢,就相当于中断。在你程序正常执行的时候,中断是可以打
断你的执行的。同这个类似,注入通道的转换可以打断规则通道的转换,在注入通道被转换
完成之后,规则通道才得以继续转换。
STM32 其 ADC 的规则通道组最多包含 16 个转换,而注入通道组最多包含 4 个通道。
STM32 的 ADC 在单次转换模式下,只执行一次转换,该模式可以通过 ADC_CR2 寄存器
的 ADON 位(只适用于规则通道)启动,也可以通过外部触发启动(适用于规则通道和注入
通道),这是 CONT 位为 0 。
以规则通道为例,一旦所选择的通道转换完成,转换结果将被存在 ADC_DR 寄存器中,
EOC (转换结束)标志将被置位,如果设置了 EOCIE ,则会产生中断。然后 ADC 将停止,直
到下次启动。
ADC使用步骤
1)开启GPIO端口时钟,设置端口为模拟输入。
STM32F103RBT6的ADC通道0在PA0上,所以,我们先要使能PORTA的时钟,然后设置PA0为模拟输入。
2)使能ADC1时钟,并设置分频因子。
要使用ADC1,第一步就是要使能ADC1的时钟,在使能完时钟之后, 进行一次ADC1的复位。接着我们就可以通过RCC_CFGR设置ADC1的分频因子。分频因子要确保ADC1的时钟(ADCCLK)不要超过14Mhz。
3)设置ADC1的工作模式。
在设置完分频因子之后,我们就可以开始ADC1的模式配置了,设置单次转换模式、触发方式选择、数据对齐方式等都在这一步实现。
4)设置ADC1规则序列的相关信息。
接下来我们要设置规则序列的相关信息,我们这里只有一个通道通道,并且是单次转换的,所以设置规则序列中通道数为1,然后设置0的采样周期。
5)开启AD转换器,并校准。
在设置完了以上信息后,我们就开启AD转换器,执行复位校准和AD校准 ,注意这两步是必须的!不校准将导致结果很不准确。
6)读取ADC值。
在上面的校准完成之后,ADC就算准备好了。接下来我们要做的就是设置规则序列0里面的通道,然后启动ADC转换。在转换结束后,读取 ADC1_DR里面的值就是了。
通过以上几个步骤的设置,就可以正常的使用STM32的ADC1来执行AD转换操作了。
/****************初始化函数********************
* ADC2初始化
******************************************************/
void Adc2Init(void)
{
RCC->APB2ENR |= 1 << 10; //ADC1时钟使能
RCC->APB2RSTR |= 1 << 10; //ADC1复位
RCC->APB2RSTR &= ~(1 << 10); //复位结?
ADC2->CR1 &= 0xf0ffff; //工作模式清零
ADC2->CR1 |= 0 << 16; //独立工作模式
ADC2->CR1 &= ~(1 << 8); //非扫描模式
ADC2->CR2 &= ~(1 << 1); //单次转换模式
ADC2->CR2 &= ~(7 << 17);
ADC2->CR2 |= 7 << 17; //SWSTART:软件控制转换
ADC2->CR2 |= 1 << 20; //使用外部触发(SWSTART),必须使用一个事件来触发
ADC2->CR2 &= ~(1 << 11); //右对齐
ADC2->SQR1 &= ~(0xf << 20);
ADC2->SQR1 &= 0 << 20; //1个转换在规则序列中,也就是只转换规则序列1
ADC2->SMPR2 &= ~(7 << 3); //通道1采样时间清空
ADC2->SMPR2 |= 7 << 3; //通道1 239.5周期,提高采用时间可以提高精确度
ADC2->CR2 |= 1 << 0; //开启AD转换器
ADC2->CR2 |= 1 << 3; //使能复位校准
while( ADC2->CR2 & 1 << 3 )
; //等待校准结束
ADC2->CR2 |= 1 << 2; //开启AD校准
while( ADC2->CR2 & 1 << 2 )
; //等待校准结束
}

/****************获取电压值函数********************
* ADC转化为电压值
* adcx: 1表示ADC1; 2表示ADC2
* ch: 通道值
* 返回电压值
******************************************************/
float GetVoltage(u8 adcx, u8 ch)
{
u16 adcValue = 0;
float vol = 0;
adcValue = GetAdc( adcx, ch );
vol = 3.3 * (float)adcValue / 4096;
return vol;
}