STM32 F407 ADC控制器寄存器使用详解
前言:
当我们需要获取外部的环境信息会用到传感器,如光敏传感器,毒气检测,酒精传感器,雨滴传感器等等。
这些传感器都会将外界环境的物理量转化为电压模拟量;我们单片机就需要通过引脚来获取这些模拟量,但是单片机的CPU只能处理数字量,因此要将这些模拟量再转换为数字量,进行数据换算后,得到对应的信息。
STM32芯片中就有能将模拟量转换为数字量的外设 — ADC
ADC原理:
ADC原理可以分为两个部分 : 采样 + 转换
采样:采集模拟量的精度
转换:逐次逼近型,将参考电压等分为数小份累加方式与目标电压进行比较,直到相等
再将该数字量分数保存在ADC_DR寄存器中。
ADC控制器框图
框图下面的硬件触发转换内容,在此不进行展开
ADC主要参数:
参考电压:每个ADC转换器都会有一个参考电压,stm32f407为3.3v
分辨率/精度:每个ADC转换器都会有精度,精度即将参考电压划分分数的多少
stm32f407内部ADC,可配置 12 位、 10 位、 8 位或 6 位分辨率
一般使用12位分辨率,即将3.3v分为4096分 — 0.805mv
如果stm32芯片内部精度不够,可以外界高精度ADC转换芯片
如果外接高于参考电压的模拟量时怎么做?
引入IO口前,外加一个分压电阻进行降压,ADC转换数字量后再进行回换算。
ADC模式选择:
一般会选择单次转换模式,如果是多通道则开启扫描模式
即 单次 + 扫描
原因:单次转换模式可控性更高,不需要转换就停止,减少资源消耗
规则组与注入组:
通常情况下,使用规则组即可满足使用~
注入组和规则组的区别:
注入组可以将4个通道转换完成后放入4个DR数据寄存器
而规则组只能将每个通道转换完成后的数据放入同1个DR数据寄存器中
注入组可以分为触发注入和自动注入
触发注入 注入通道可以打断规则通道
自动注入 注入通道会自动接在规则通道后面
ADC转换覆盖问题:
ADC在多通道序列转换中,开启转换后,第一个通道转换完成,将通道1的转换数字量存放到DR数据寄存器并且EOC标志位置1,(ADC控制不会管EOC是否清零)紧接着立马开始第二个通道的转换。
因此若不及时读走DR中通道1的数字量,当通道2转换完成,就会以通道2的数字量把原来DR的数据覆盖掉。
所以在代码程序设计中,我们要在EOC置1后,把DR数据读走或者使用DMA。
ADC编程思路:
这里使用的是查询等待的方法
也可以使用ADC中断,在中断中读取DR数字量
ADC控制初始化函数
{
/*IO口控制器配置*/
/*ADC控制器配置*/}
获取ADC转换数据函数
{
//开启ADC转换
//等待EOC置1
//读取DR寄存器数字量到变量中
//返回变量
}
ADC寄存器相关配置说明:
SR:
位2: 注入组转换结束标志
位1: 规则组转换结束标志
0:转换未完成1:转换已完成
—– 注意EOCS位
CR1:
位25/24: ADC精度 //12位
位8: 扫描模式 //多通道时开启
位5: 中断使能位 //若使用中断时开启
CR2:
位30: 开始转换规则组通道
位11: 数据右对齐
位10: EOCS位
0:一个序列中通道全部转换结束后EOC位置1
1:一个序列中每一个通道转换结束EOC位都会置1位1: 连续转换和单次转换选择
位0: 开启ADC使能
SMPRx: 设置各个通道的采样时间 //480个周期
SQRx: 设置规则组一多少个转换并且排序
CCR:
位23: 使能芯片内部温度传感器和参考电压通道
位16/17: 时钟分频 //4分频
芯片内部的温度传感器:
芯片内部温度传感器挂载在ADC 16号通道(F407系列)
不同系列有所差别,可以通过 数据手册查看公式中的具体数值
程序代码中的使用:
0.805是3.3V/4096再转化为mV单位的结果
Vsense 就是0.805乘转换温度通道后的数字量
ADC初始化部分代码:
单次 + 扫描 模式
通道10&通道12&通道16
/*ADC控制器配置*/
//ADC时钟使能
RCC->APB2ENR |= (1<<8);
//CR1
ADC1->CR1 &= ~(3<<24); //12位分辨率
ADC1->CR1 |= (1<<8); //扫描模式
//CR2
ADC1->CR2 &= ~(1<<11); //数据右对齐
ADC1->CR2 &= ~(1<<1); //单次转换模式
ADC1->CR2 |= (1<<10); //EOCS位,每个通道转换完成EOC都会置1
//SMPRx
ADC1->SMPR1 |= (7<<6); //通道12 480个周期的采样时间
ADC1->SMPR1 |= (7<<0); //通道10 480个周期的采样时间
ADC1->SMPR1 |= (7<<18); //通道16 480个周期的采样时间
//SQRx
ADC1->SQR1 &= ~(0xf<<20);
ADC1->SQR1 |= (2<<20); //3个转换通道
ADC1->SQR3 &= ~(0x1f<<0);
ADC1->SQR3 |= (12<<0); //第一个转换 通道12
ADC1->SQR3 &= ~(0x1f<<5);
ADC1->SQR3 |= (10<<5); //第二个转换 通道10
ADC1->SQR3 &= ~(0x1f<<10);
ADC1->SQR3 |= (16<<10); //第三个转换 通道16
//CCR
ADC->CCR &= ~(3<<16); //2分频ADC 42MHz
ADC->CCR |= (1<<23); //使能温度传感器
//使能ADC1
ADC1->CR2 |= (1<<0);
作者:汪款学嵌入式