ADC基本概念
STM32上的微控制器(MCU)只能处理数字量,如果需要MCU区分多值输入信号(连续的模拟信号)时,MCU直接做不了,需要将多值信号通过模数转换器,转成数字量供MCU处理。模数转换器一般用在各类传感器上,还有部分用在音视频处理上。
ADC:模数转换 把连续的模拟量(例如温度 湿度 气压 光照强度 土壤氮磷钾…)转换为离散的数字量—传感器
DAC:数模转换 把离散的数字量转换为连续的模拟量
ADC基本原理
ADC分为两个步骤:采样数据+转换。
ADC有两种模式:并联比较型+逐次趋近型,在STM32上的ADC为逐次趋近型,例如:一个12位的传感器、转换电压值(0~3.3v)、数字量=1000 电压=(1000/4096)*3.3v
并联比较型ADC
由三个部分组成,分压电路+比较器+编码器
E:参考电压
Ux:模拟电压
举例:E=8V,Ux=3V, C比较器就会发现参考电压和模拟电压值相等,C机会输出有效信号,最终编码器输出数字量3
逐次趋近型
跟C语言二进制的勾选法一样,先将最高位置1,判断是否大于最高位权重,如果是就保持置1,否则置0。从权重高的位逐次趋近于低位进行勾选,如果每次减去上一个权重结果再除以得到2结果,不小于当前位置的权重就将当前权重置1,否则置0。
STM32中的ADC为12位,所以转换结果范围是0~4095。
STM32F407VG系列上的ADC
一共有3个12位的ADC,他们都属于片上外设,挂载在APB2的时钟线上。
12 位 ADC 是逐次趋近型模数转换器。它具有多达 19 个复用通道,可测量来自 16 个外部源、两个内部源和 Vbat通道的信号。这些通道的 ADC可在单次、连续、扫描或不连续采样模式下进行。 ADC 的结果存储在一个左对齐或右对齐的 16 位数据寄存器中。
12 位 ADC:转换结果范围 0~4095
16个外部通道:与IO口相关的
IN16:温度传感器
IN17:参考电压
IN18:Vbat 电源电压
数据对齐:一般选择右对齐。如果选择左对齐,DR寄存器是16位的,处理数据时需要对寄存器数据右移4位进行输出处理。
ADC框架图
ADC的主要特性
ADC的时钟
在STM32F407VG平台上ADC挂靠在APB2 时钟,大小84MHz。
ADCCLK经过对APB时钟分频得到的,可进行2/4/6/8分频
器件的工作电压 (VDD) 要求介于1.8V到3.6V之间
1.8v~2.4v:慢速运行
2.4v~3.6v:全速运行
关于ADCCLK最大值的说明在数据手册5.3.20
所以全速运行下,ADC的标准频率为30MHz,最小频率为0.6MHz,最大时钟为36MHz。
ADC的通道介绍
ADC可选择规则通道和注入通道进行数据转换。
规则通道:按照顺序依次有序的进行转换
注入通道:类似中断,注入通道有数据需要转换就立马进行转换
规则序列最多16个 注入序列最多4个
同一个ADC下规则序列下的通道不能同时进行转换的,因为只有一个规则数据寄存器,一般情况下选择规则通道
同一个ADC下注入序列下的通道是可以同时进行转换的,有四个注入数据寄存器,一般不使用注入序列
ADC单次转换模式
如果选择单次转换,ADC只转换一次值然后就停止。
以规则通道为例:
在单次转换模式下, ADC 执行一次转换。 CONT 位为 0 时,
将 ADC_CR2 寄存器中的 SWSTART 位置 1(仅适用于规则通道)开启转换。
完成所选通道的转换之后:
1.转换数据存储在 16 位 ADC_DR 寄存器中
2.EOC(转换结束)标志置 1
3.EOCIE 位置 1 时将产生中断
然后, ADC 停止。
ADC连续转换模式
以规则通道为例:
在连续转换模式下, ADC 结束一个转换后立即启动一个新的转换。 CONT 位为 1 时,可通过外部触发或将 ADC_CR2 寄存器中的 SWSTRT 位置 1 来启动此模式(仅适用于规则通道)
1.转换数据存储在 16 位 ADC_DR 寄存器中
2.EOC(转换结束)标志置 1
3.EOCIE 位置 1 时将产生中断
然后、ADC不会停止,继续下一次转换。
ADC扫描模式
适用与多通道转换时
通过将 ADC_CR1 寄存器中的 SCAN 位置 1 来选择扫描模式。将此位置 1 后, ADC 会扫描在 ADC_SQRx 寄存器(对于规则通道)或 ADC_JSQR 寄存器(对于注入通道)中选择的所有通道。为组中的每个通道都执行一次转换。每次转换结束后,会自动转换该组中的下一个通道。如果将 CONT 位置 1,规则通道转换不会在组中最后一个所选通道处停止,而是再次从第一个所选通道继续转换。
所以,如果扫描一次就结束,需要将CONT位置1.
采样时间及快速模式
如果传感器没有给到转换时间、建议可以大一点的采样周期。
例如:转换时间10us 主频21MHz
采样时间(周期)该如何选择
一个周期=1/21 us 总时长:10us
10/(1/21)=210周期
ADC配置相关寄存器
ADC转换程序设计流程及思路
1.打开时钟(GPIOx ADCn)
2.GPIOx配置—模拟输入
3.扫描模式
4.分辨率(12位)
5.单次/连续模式
6.结束转换选择(EOCS)
7.数据对齐
8.采样时间
9.转换总数
10.转换顺序(第几次转换)
11.ADC分频选择
12.使能ADC
13.获取转换值的函数(开启转换 判断标志位 读取DR的值)
可以使用中断也可以不用中断
以单通道的光敏模块为例,获取当前的光照强度
1.根据器件原理图以及器件的参考资料
光敏电阻模块对环境光线最敏感,一般用来检测周围环境的光线的亮度,触发单片机或继电器模块等;
模块在环境光线亮度达不到设定阈值时, DO 端输出高电平,当外界环境光线亮度超过设定阈值时, DO端输出低电平;
DO 输出端可以与单片机直接相连,通过单片机来检测高低电平,由此来检测环境的光线亮度改变;
DO 输出端可以直接驱动继电器模块,由此可以组成一个光控开关。
2.配置寄存器以及GPIO口输入
PB1引脚接光敏模块的模拟输出端口,PB1配置为模拟输入。PB1对应的是ADC12_IN9通道。
根据数据手册第三章找到PB1对应的ADC通道号
void adc_config(void)
{
RCC->AHB1ENR |= (1<<1);//打开PB时钟
RCC->APB2ENR |= (1<<9);//打开ADC2的时钟
//配置IO口为模拟输入模式
GPIOB->MODER |= (3<<2);//PB1端口配置为模拟输入模式
//配置ADC2寄存器
ADC2->CR1 &= ~(1<<8);//关闭扫描模式
ADC2->CR1 &= ~(1<<11);//规则通道不连续采样
ADC2->CR1 &= ~(3<<24);//分辨率选择12
ADC2->CR2 &= ~(1<<1);//单次转换
ADC2->CR2 |= (1<<10);//EOCS置1,每次转换结束EOC位置1
ADC2->CR2 &= ~(1<<11);//数据右对齐
ADC2->SMPR2 |= (7<<27);//通道9选择采样时间为480个周期
ADC2->SQR1 &= ~(15<<20);//规则序列长度选择1,1次转换
ADC2->SQR3 |= (9<<0);//第一次转换通道9数据
ADC->CCR |= (1<<16);//ADC进行4分频
ADC2->CR2 |= (1<<0);//ADC使能
}
void get_adc_value(void)
{
u32 value=0;
ADC2->CR2 |= (1<<30);//开启规则通道
while(!(ADC2->SR & (1<<1)));//转换结束
value=ADC2->DR;
printf("光照强度=%d\r\n",value);
}
主函数内调用函数
#include "main.h"
int main()
{
Usart1_Config();
adc_config();
while(1)
{
get_adc_value();
delay_ms(500);
}
}