9. ADC
9.1 什么是ADC
ADC 全称为模拟-数字转换器,是一种用于将模拟信号转换为数字信号的模拟数字转换器。我们知道,模拟信号是连续的,其取值可以在一定范围内任意变化,如声音、光信号等。而数字信号则是离散的二进制信号,如计算机中的数据0和1,仅能取有限的值。
ADC的工作原理是将模拟信号通过采样转换为离散的数字信号,然后再通过量化、编码等处理,最终得到对应的数字表示。ADC采样的频率越高,得到的数字信号就越接近原来的模拟信号,也就是保真度越高,但是需要更多的资源和计算功耗。
ADC 通常用于从外部模拟传感器中读取模拟信号,并将其转换为数字信号供嵌入式系统或计算机进行处理,例如测量温度、湿度、压力等物理量。
9.2 ESP32S3的ADC介绍
ESP32-S3 集成了两个 12 位 SAR ADC,共支持 20 个模拟通道输入,可测量最多来自 20 个管脚的模拟信号以及内部电压等内部信号。为了实现更低功耗,ESP32-S3 的 ULP 协处理器也可以在睡眠方式下测量电压,此时,可通过设置阈值或其他触发方式唤醒 CPU。
ADC可以转换的电压范围由VREF决定,对于ESP32-S3通常是0到3.3V,开发板是设置为3.3V。但需要注意的是,ESP32具体的最大额定输入电压可能略有不同,检查相应数据手册的具体信息非常重要,通常会建议使用衰减器(Attenuation)功能或者额外的硬件如电压分压器来保证输入电压在规定范围内。
ESP32-S3内部还带了一个温度传感器,用于生成一个随温度变化的电压。内部 ADC 将传感器电压转化为一个数字量,温度传感器的测量范围为–20 °C 到 110 °C。温度传感器适用于监测芯片内部温度的变化,该温度值会随着微控制器时钟频率或 IO 负载的变化而变化。一般来讲,芯片内部温度会高于外部温度。
支持ADC采集的引脚如下:
9.3 ADC 的基本参数
ADC 的基本参数通常包括以下几个:
- 分辨率:指 ADC 的数字输出位数,也称为量化位数。例如,12 位 ADC 具有 4096 个离散的数字输出。
- 采样速率:指 ADC 可以进行采样的最大速率。对于 ESP32-S3,最大采样速率为 2.5 MS/s。
- 输入范围:指 ADC 可以测量输入信号的电压范围。对于 ESP32-S3,输入范围为 0-3.3V。
- 噪声:指 ADC 在采集时分辨率的误差和干扰的影响。噪声越小,ADC 测量结果越精准。
- 稳定性:指 ADC 输出的稳定性。稳定性好的 ADC 输出变化小,测量结果更加准确。
9.4 使用ADC流程
使用 ESP32 的 ADC(模数转换器)功能在 MicroPython 中的流程如下:
- 导入相关的模块和库
from machine import ADC
- 初始化 ADC 对象
adc = ADC(machine.Pin(pin_number))
其中 pin_number 是连接到 ESP32 的引脚编号。
- 配置 ADC 的参考电压和分辨率(可选步骤)
# 设置参考电压,默认为 3.3V(使用 11dB 衰减)
adc.atten(adc.ATTENUATION_11DB)
# 设置分辨率,默认为 12 位(0-4095)
# adc.width(ADC.WIDTH_12BIT)
2
3
4
5
可以使用 atten() 方法来设置 ADC 的参考电压,默认为 3.3V。
要读取高于参考电压的电压,请使用atten 关键字参数应用输入衰减。有效值(和近似线性测量范围)为:
- ADC.ATTN_0DB: 无衰减(100mV-950mV))
- ADC.ATTN_2_5DB: 2.5dB衰减(100mV-1250mV)
- ADC.ATTN_6DB: 6dB衰减(150mV-1750mV)
- ADC.ATTN_11DB: 11dB衰减(150mV-2450mV)
可以使用 width() 方法来设置 ADC 测量结果的分辨率,默认为 12 位(0-4095)。
为了兼容性, ADC对象还提供与支持的ADC分辨率匹配的常量:
- ADC.WIDTH_9BIT = 9
- ADC.WIDTH_10BIT = 10
- ADC.WIDTH_11BIT = 11
- ADC.WIDTH_12BIT = 12
- 读取 ADC 的值:
adc_value = adc.read()
b
2
使用 read() 方法从 ADC 中读取当前的测量值。该方法返回根据设置的分辨率范围的原始ADC值,例如,对于12位分辨率为0-4095,表示测量结果。5. 关闭 ADC:
adc.deinit()
当你不再需要使用 ADC 时,可以通过调用 deinit() 方法来关闭 ADC。
需要注意以下几点:
- 根据硬件的具体情况,只有GPIO1到GPIO20这些引脚支持 ADC 功能。
- ADC 测量值的范围和精度取决于参考电压和分辨率的设置。你可以根据需要进行适当的设置。
- 如果你需要连续读取 ADC 的值,可以使用 read_timed() 方法来定时读取 ADC 值。
其余方法请参考官方 MicroPython文档:
http://www.86x.org/en/latet/esp32/quickref.html#adc-analog-to-digital-conversion
9.5 硬件连接与准备
本示例将GPIO1作为ADC读取引脚,通过GPIO1测试外部电压,再使用板载的串口0打印出ADC读取到的值,并换算成实际电压显示。
9.6 ADC验证
import time
from machine import Pin, ADC
adc_in = Pin(1, Pin.IN)
# 在 GPIO1 引脚创建 ADC 对象
adc = ADC(adc_in)
# 配置衰减器,配置测量量程为 3.3V
adc.atten(ADC.ATTN_11DB)
while True:
print(f'adc:{adc.read()}')
time.sleep(0.1)
2
3
4
5
6
7
8
9
10
11
12
13
我们可以在 shell 控制台,鼠标右击,选择 显示绘图器,他可以把 shell 中输出的数字可视化,这样就可以看到 adc 的图像变化: