数模转换器 - ADC 实验

罗大富 BigRich大约 5 分钟ESP32Python

前面我们介绍使用 PWM 输出不同电压值,类似于模拟信号输出。如果需要 ESP32 检测外部输入的模拟信号该怎么办?这就是本节课要学习的 ADC,通过 ADC 将模拟信号转换为数字信号给 ESP32 处理。

实验原理

在学习 ADC 之前,我们要首先学习什么是模拟信号,什么是数字信号。

模拟信号(Analog Signal):模拟信号是连续变化的量或者信号,生活中接触到的信号基本都是模拟信号,温度变化,天体运动等等,这些都是连续的信息,都是模拟信号。模拟信号,简单的说就是用电信号模拟出其他的信号,比如用电信号模拟出图像,模拟出声音的声波。

数字信号(Digital Signal):数字信号是时间离散、数值离散的信号,数字信号存在采样,还存在量化,只能取到一些不连续的固定值,这也是数字信号和模拟信号之间可以进行相互转换的原因。

所以,总结就是模拟信号时间连续,幅值连续,数字信号时间离散,幅值离散。模拟电路就是使用、处理模拟信号的电路;数字电路就是使用、处理数字信号的电路。

我们举个简单的例子:

  1. 指针时钟显示的就是时间的模拟信号,他表示时间是连续变化的,
  2. 数字时钟显示的就是时间的数字信号,时间的显示是按照固定增量变化的,他可以显示 1、2、3,但是无法显示 1.1、2.1、等,所以在数字电路中使用的数字信号一般只能取 0 或 1,把 0 对应为低电平,把 1 对应为高电平,说白了就是有或者没有

数字信号是在模拟信号的基础上依次经过 采样量化编码而形成的。具体地说,采样 就是把输入的模拟信号按适当的时间间隔得到各个时刻的样本值;量化 是把经采样测得的各个时刻的值用二进制码来表示;编码则是把量化生成的二进制数排列在一起形成顺序脉冲序列。

ADC(Analog to Digital Converter)即模数转换器,它可以将模拟信号转换为数字信号。由于单片机只能识别二进制数字,所以外界模拟信号常常会通过 ADC 转换成其可以识别的数字信号。常见的应用就是将变化的电压转成数字信号。

注意

使用默认配置时,ADC 引脚上的输入电压必须介于 0.0V 和 1.0V 之间(任何高于 1.0V 的值都将读为 4095)。如果需要增加测量范围,需要配置衰减器。

硬件电路设计

物料清单(BOM 表):

材料名称数量
LED1
1kΩ 电阻1
电位器1
面包板1
杜邦线若干

电位器相当于一个滑动变阻器,两端引脚阻值是固定的,中间引脚对任何一端的引脚阻值是可变的,他等效于从中间把电位器分成两个串联的电阻,串联总阻值是确定的,一端接输入电源,一端接地

软件程序设计

ADC 在 machine 的 ADC 模块中,我们也是只需要了解其构造对象函数和使用方法即可。

构造方法 machine.ADC(pin, attn):

  • 参数 pin:Pin 对象,
  • 参数 attn:配置衰减器增加电压测量范围。

使用方法:

import time
from machine import Pin, ADC

# 在 26 引脚创建 ADC 对象
adc = ADC(Pin(26))

# 获取 ADC 值
# 测量精度为 12 位,返回 0-4095(表示 0-1V)
val = adc.read()
# 返回 0-65535 范围内的整数。返回值表示 ADC 获取的原始读数,按比例缩放,最小值为 0,最大值为 65535。
val_u16 = adc.read_u16()

# 配置衰减器,能增加电压测量范围,参数可以是 ADC_ATTN_0DB(0dB 衰减,最大输出电压为 1 V, 默认配置)
# ADC_ATTN_2_5DB(2.5dB 衰减,最大输出电压为 1.34 V)、
# ADC_ATTN_6DB(6dB 衰减,最大输出电压为 2 V)、
# ADC_ATTN_11DB(11dB 衰减,最大输出电压为 3.3 V)
adc.atten(ADC.ATTN_11DB)

因此,在 shell 环境中打印出当前值的程序可以这么写:

import time
from machine import Pin, ADC

# 在 26 引脚创建 ADC 对象
adc = ADC(Pin(26))

# 配置衰减器,配置测量量程为 3.3V
adc.atten(ADC.ATTN_11DB)

while True:
    print(f'adc:{adc.read()}')
    time.sleep(0.1)

我们可以在 shell 控制台,鼠标右击,选择 显示绘图器,他可以把 shell 中输出的数字可视化,这样就可以看到 adc 的图像变化:

结合上一节课学习的 PWM,我们可以实现用电位器控制 LED 的亮灭,代码如下:

import time
from machine import Pin, ADC, PWM

# 在 26 引脚创建 ADC 对象, 并配置衰减器,配置测量量程为3.3V
adc = ADC(Pin(26, Pin.IN),atten=ADC.ATTN_11DB)
# 创建 LED PWM 控制对象
led = PWM(Pin(13, Pin.OUT), freq=1000)

while True:
    led.duty_u16(adc.read_u16())
    time.sleep(0.1)
上次编辑于:
贡献者: Luo