1.ADC概述
模数转换器
(Analog to Digital Converter
,简称
ADC)
是一种数据转换器,用于将连续的模拟信号转
换为数字形式,以便数字系统能够处理。
![](https://img-blog.csdnimg.cn/direct/087e3a9459bc4131ae52b2a872f38636.png)
![](https://img-blog.csdnimg.cn/direct/80b1a772b04d4c2fbcac138c93df6456.png)
模拟信号是什么?
模拟信号是连续变化的信号,可以在任意时间内取得任意值。例如,声音、光线等自然界中的信号
都是模拟信号,其值在一定范围内连续变化。
模拟信号可以直接传输和处理,但在长距离传输或复杂系统中容易受到噪声和失真的影响,因此需
要谨慎处理和放大。在音频处理、模拟电路、传感器测量等领域应用很多
![](https://img-blog.csdnimg.cn/direct/1f42266778834bca805ad8b3986610b1.png)
数字信号是什么?
数字信号是离散的,只能在离散的时间点上取值。这些值通常用二进制数字来表示,例如
0
和
1
。
数字信号可以通过数字系统进行高效传输和处理,因为它们更不容易受到干扰和失真的影响。数字
信号可以轻松地存储、复制、处理和传输,且在处理过程中可以利用各种数字算法进行处理。
数字信号在计算机系统、通信系统、数字音频、数字图像等领域中得到广泛应用,现代电子设备中
几乎所有的数据处理都涉及到数字信号。
转换过程:
转换过程:
![](https://img-blog.csdnimg.cn/direct/0a0898b496a14df08c8603c2f87de9c7.png)
2.STM32 ADC简介
STM32F407ZGT6
有
3
个
ADC
,可配置
12
位、
10
位、
8
位或
6
位分辨率,
ADC
有
19
个 通道 (其中外部通道16
个)。各通道的
A/D
转换可以单次、连续、扫描或间断模式执行。
ADC
的结果可以
左对齐或右对齐方式存储在
16
位数据寄存器中。详细说明可查看《
stm32f4xx
参考手册》,第
11
章
-
图 34
STM32F407ZGT6
包含有
3
个
ADC
。
STM32F4
的
ADC
最大的转换速率为
2.4Mhz
,也就是 转换
时间为
0.41us
(在
ADCCLK=36M,
采样周期为
3
个
ADC
时钟下得到),不要让
ADC
的时 钟超过
36M
,否则将导致结果准确度下降。
2.1 电压输入范围
ADC
输入范围为:
VREF-
≤
VIN
≤
VREF+
。在设计原理图的时候一般把
VSSA
和
VREF-
接地,把
VREF+
和
VDDA
接
3V3
,得到
ADC
的输入电压范围为:
0~3.3V
。
![](https://img-blog.csdnimg.cn/direct/f242039e72d24792908e792230784e2e.png)
2.2 输入通道
我们确定好
ADC
输入电压之后,那么电压怎么输入到
ADC
?这里我们引入通道的概念,
STM32
的
ADC
多达
19
个通道,其中外部的
16
个通道就是框图中的
ADCx_IN0
、
ADCx_IN1
⋯
ADCx_IN5
。 这
16 个通道对应着不同的IO
口,具体是哪一个
IO
口可以从手册查询到。
还有三个内部通道:芯片内部的温度传感器、备用电源
VBAT
、内部参考 电压
VREFINT
。
![](https://img-blog.csdnimg.cn/direct/cfb03ffb4f6846da878a77ecfc35ed87.png)
2.3 规则通道和注入通道
外部的
16
个通道在转换的时候又分为规则通道和注入通道,其中规则通道最多有
16
路,注入通 道
最多有
4
路。那这两个通道有什么区别?在什么时候使用?
规则通道
平时一般使用的就是这个通道,它们的优先级较低,通常用于常规的采样任务。
注入通道
注入,可以理解为插入,注入通道则用于在规则通道的基础上提供更高的优先级采样。注入通道的
数据采样可以在规则通道采样进行的同时进行,具有更高的优先级。通常用于对某些事件或条件的快
速响应,例如紧急事件采样或高优先级传感器的采样。
如果在规则通道转换过程中,有注入通道插队,那么就要先转换完注 入通道,等注入通道转换完
成后,再回到规则通道的转换流程。这点跟中断程序很像,所以,注入通道只有在规则通道存在时才 会出现。
举例:
假设你正在使用
STM32
控制一个温度传感器。你需要定期地(每
1
秒)采集温度数据,并且有时候
需要在突发事件发生时(比如温度快速升高)立即采集更多的数据。
对于规则通道
:你会设置
ADC
在每秒钟采样一次,通过规则通道来获取温度数据。这是一种周期性
的采样方式,对于大多数情况下的温度监测来说是足够的。
对于注入通道
:你可以设置
ADC
来在检测到温度突然升高时,立即进行更高优先级的采样,以获取
更频繁的温度数据,以便更快地做出响应。
2.4 触发源
ADC
转换可以由
ADC
控制寄 存器
2: ADC_CR2
的
ADON
这个位来控制,写
1
的时候开始转换,写
0
的时候停止转换,这个 是最简单也是最好理解的开启
ADC
转换的控制方式。
除了这种普通的控制方法,
ADC
还支持外部事件触发转换,这个触发包括内部定时器触发 和外部
IO
触发。触发源有很多,具体选择哪一种触发源,由
ADC
控制寄存器
2:ADC_CR2
的
EXTSEL[3:0]
和
JEXTSEL[3:0]
位来控制。
EXTSEL[3:0]
用于选择规则通道的触发源,
JEXTSEL[3:0]
用于选择注入通道的触发源。
选定好触发源之后,触发源是否要激活,则由
ADC
控制寄存器
2:ADC_CR2
的
EXTTRIG
和
JEXTTRIG
这两位来激活。
如果使能了外部触发事件,我们还可以通过设置
ADC
控制寄存器
2:ADC_CR2
的
EXTEN[1:0]
和
JEXTEN[1:0]
来控制触发极性,可以有
4
种状态,分别是:
禁止触发检测、上升沿检测、下降沿 检测以及上升沿和下降沿均检测。
2.5 转换时间
ADC 时钟
ADC 输入时钟ADC_CLK 由PCLK2 经过分频产生,最大值是36MHz,分频 因子由ADC 通用控制
寄存器ADC_CCR 的ADCPRE[1:0] 设置,可设置的分频系数有2、4、6 和 8
对于我们的芯片来说,APB2=84Mhz,而ADC最大时钟频率为36Mhz,如果分频系数为2,则
84Mhz/2=42Mhz>36Mhz , 所以一般情况下为4分频,即84/4=21Mhz
采样时间
![](https://img-blog.csdnimg.cn/direct/95bdc7651f56456bbf334bd146c9dc19.png)
![](https://img-blog.csdnimg.cn/direct/ecc47cdc4ce540b0aaf160e631a48040.png)
ADC
需要若干个
ADC_CLK
周期完成对输入的电压进行采样,采样的周期数可通过
ADC
采样时 间
寄存器
ADC_SMPR1
和
ADC_SMPR2
中的
SMP[2:0]
位设置,
ADC_SMPR2
控制的是通道
0~9
,
ADC_SMPR1
控制的是通道
10~17
。每个通道可以分别用不同的时间采样。其中采样周期最小是
3
个。
ADC
的总转换时间跟
ADC
的输入时钟和采样时间有关,公式为:
Tconv =
采样时间
+ 12
个周期
其中:
Tcovn
为总转换时间,采样时间是根据每个通道的
SMP
位的设置来决定的。例如,
当
ADCCLK=21Mhz
的时候,并设置
3
个周期的采样时间,则得到
Tcovn=3+12=15
个周期
=0.71us
。
(为什么要加
12
个周期呢?这个额外的
延迟周期
是指
ADC
转换开始时,
ADC
开始进行样本保持,直
到样本保持电路中的电压稳定下来,以确保所采集的数据是准确的,这个过程需要一定的时间,可参
考手册
11.3.6
时序图)
2.6 数据寄存器
一切准备就绪后,
ADC
转换后的数据根据转换组的不同,规则组的数据放在
ADC_DR
寄存器, 注
入组的数据放在
JDRx
规则数据寄存器ADC_DR
ADC
规则组数据寄存器
ADC_DR
只有一个,是一个
32
位的寄存器,只有
低
16
位有效
并且只是 用
于独立模式存放转换完成数据。因为
ADC
的最大精度是
12
位,
ADC_DR
是
16
位有效,这样 允许
ADC
存放数据时候选择左对齐或者右对齐,具体是以哪一种方式存放,由
ADC_CR2
的
11
位
ALIGN
设置。假如设置
ADC
精度为
12
位,如果设置数据为左对齐,那
AD
转换完成数据存 放在
ADC_DR
寄
存器的
[4:15]
位内;如果为右对齐,则存放在
ADC_DR
寄存器的
[0:11]
位内。
规则通道可以有
16
个这么多,可规则数据寄存器只有一个,如果使用多通道转换,那转换的数 据
就全部都挤在了
DR
里面,前一个时间点转换的通道数据,就会被下一个时间点的另外一个通 道转换
的
数据覆盖掉
,所以当通道转换完成后就应该把数据取走,或者开启
DMA
模式,把数据 传输到内存里
面,不然就会造成数据的覆盖。最常用的做法就是开启
DMA
传输。
![](https://img-blog.csdnimg.cn/direct/50425fcc0ec24a7899979ec10eee5e96.png)
注入数据寄存器ADC_JDRx
ADC
注入组最多有
4
个通道,刚好注入数据寄存器也有
4
个,每个通道对应着自己的寄存器,不
会跟规则寄存器那样产生数据覆盖的问题。
ADC_JDRx
是
32
位的,低
16
位有效,高
16
位保留, 数据
同样分为左对齐和右对齐,具体是以哪一种方式存放,由
ADC_CR2
的
11
位
ALIGN
设置。
2.7 中断
数据转换结束后,可以产生中断,中断分为四种:规则通道转换结束中断,注入转换通道转换结束
中断,模拟看门狗中断和溢出中断。
转换结束中断
转换结束中断很好理解,跟我们平时接触的中断一样,有相应的中断标志位和中断使能位
模拟看门狗中断
当被
ADC
转换的模拟电压低于低阈值或者高于高阈值时,就会产生中断,前提是我们开启了模 拟
看门狗中断,其中低阈值和高阈值由
ADC_LTR
和
ADC_HTR
设置。例如我们设置高阈值是
2.5V
,那 么模拟电压超过2.5V
的时候,就会产生模拟看门狗中断,反之低阈值也一样。
溢出中断
如果发生
DMA
传输数据丢失,会置位
ADC
状态寄存器
ADC_SR
的
OVR
位,如果同时使能了 溢出
中断,那在转换结束后会产生一个溢出中断。
2.8 DMA请求
规则和注入通道转换结束后,除了产生中断外,还可以产生
DMA
请求,把转换好的数据直接存储
在内存里面
3.ADC 初始化结构体
通过前面的学习,我们知道标准库函数对每个外设都建立了一个初始化结构体
xxx_InitTypeDef(xxx
为外设名称
)
,结构体成 员用于设置外设工作参数,并由标准库函数
xxx_Init()
调用这些设定参数进入
设置外设相应的寄 存器,达到配置外设工作环境的目的。
结构体
xxx_InitTypeDef
和库函数
xxx_Init
配合使用是标准库精髓所在, 理解了结构体
xxx_InitTypeDef
每个成员意义基本上就可以对该外设运用自如了。结构体
xxx_InitTypeDef
定义 在
stm32f4xx_xxx.h
文件中,库函数
xxx_Init
定义在
stm32f4xx_xxx.c
文件中。
ADC_InitTypeDef 结构体
/**
* @brief ADC Init structure definition
*/
typedef struct
{
uint32_t ADC_Resolution; //ADC 分辨率选择
FunctionalState ADC_ScanConvMode;//ADC 扫描选择
FunctionalState ADC_ContinuousConvMode; //ADC 连续转换模式选择
uint32_t ADC_ExternalTrigConvEdge; //ADC 外部触发极性
uint32_t ADC_ExternalTrigConv; //ADC 外部触发选择
uint32_t ADC_DataAlign; //输出数据对齐方式
uint8_t ADC_NbrOfConversion; //转换通道数目
}ADC_InitTypeDef;
- ADC_Resolution:配置ADC 的分辨率,可选的分辨率有12 位、10 位、8 位和6 位。分辨率越高,AD 转换数据
- 精度越高,转换时间也越长;分辨率越低,AD 转换数据精度越低,转换时间也越短。
- ScanConvMode:可选参数为ENABLE 和DISABLE,配置是否使用扫描。如果是单通道AD 转换 使用
- DISABLE,如果是多通道AD 转换使用ENABLE。
- ADC_ContinuousConvMode:可选参数为ENABLE 和DISABLE,配置是启动自动连续转换还是单 次转换。使用
- ENABLE 配置为使能自动连续转换;使用DISABLE 配置为单次转换,转换一次后 停止需要手动控制才重新启动
- 转换。
- ADC_ExternalTrigConvEdge:外部触发极性选择,如果使用外部触发,可以选择触发的极性,可 选有禁止触发
- 检测、上升沿触发检测、下降沿触发检测以及上升沿和下降沿均可触发检测。
- ADC_ExternalTrigConv:外部触发选择,ADC 功能框图中列举了很多外部触发条件,可 根据项目需求配置触发
- 来源。实际上,我们一般使用软件自动触发。
- ADC_DataAlign: 转换结果数据对齐模式, 可选右对齐ADC_DataAlign_Right 或者左对齐
- ADC_DataAlign_Left。一般我们选择右对齐模式。
- ADC_NbrOfChannel:ADC 转换通道数目。
ADC
除了有
ADC_InitTypeDef
初始化结构体外,还有一个
ADC_CommonInitTypeDef
通用初始化 结构
体。
ADC_CommonInitTypeDef
结构体内容决定三个
ADC
共用的工作环境,比如模式选择、
ADC
时 钟等等。
typedef struct
{
uint32_t ADC_Mode;
uint32_t ADC_Prescaler;
uint32_t ADC_DMAAccessMode;
uint32_t ADC_TwoSamplingDelay;
}ADC_CommonInitTypeDef;
- ADC_Mode:ADC 工作模式选择,有独立模式、双重模式以及三重模式。
- ADC_Prescaler:ADC 时钟分频系数选择,ADC 时钟是有PCLK2 分频而来,分频系数决定ADC 时钟频率,可
- 选的分频系数为2、4、6 和8。ADC 最大时钟配置为36MHz。ADC_DMAAccessMode:DMA 模式设置,只有在双重或者三重模式才需要设置,可以设置三种 模式,具体可参
- 考参考手册说明。
- ADC_TwoSamplingDelay:2 次采样阶段之前的延迟,对双重和三重采样有效。
4.单通道采集实验一
硬件设计
![](https://img-blog.csdnimg.cn/direct/8be5681d50ff47418377c29bc699125e.png)
![](https://img-blog.csdnimg.cn/direct/0e927166cfb94109bcd0184e89cc55d6.png)
TPAD
为电容触摸按键信号,连接在电容触摸按键上。
STM_ADC
和
STM_DAC
则分别连接在
PA5
和
PA4
上,用于
ADC
采集或
DAC
输出。
编程思路
1. 初始化配置ADC 目标引脚为模拟输入模式;
2. 使能ADC 时钟;
3. 配置通用ADC 为独立模式,采样4 分频;
4. 设置目标ADC 为12 位分辨率,1 通道的连续转换,不需要外部触发;
5. 设置ADC 转换通道顺序及采样时间;
6. 配置使能ADC 转换完成中断,在中断内读取转换完数据;
7. 启动ADC 转换;
8. 使能软件触发ADC 转换。
ADC 转换结果数据使用中断方式读取,这里没有使用DMA 进行数据传输。
![](https://img-blog.csdnimg.cn/direct/66496ebb205d49709ed7f150cdddd72d.png)
![](https://img-blog.csdnimg.cn/direct/17da981a4df5479cb29082c09224ea4e.png)
![](https://img-blog.csdnimg.cn/direct/ce66bc1d034642218fbc89a6cfd09410.png)
![](https://img-blog.csdnimg.cn/direct/1546c6092d7045cbb47cfde9f7f5a01d.png)
5.单通道采集实验二
我们的板子上有一个光敏电阻,读取其值
![](https://img-blog.csdnimg.cn/direct/20876e1766e64512b160460c4af3541c.png)
![](https://img-blog.csdnimg.cn/direct/da5b37a96a6440c2ade3cd28b8a0bab2.png)