一、概述

ESP32 集成了 2 个 12 位逐次逼近模数转换器 (SARADC),支持 18 个测量通道(模拟使能引脚)。

支持以下通道:
ADC1:

  • 8通道:GPIO32 - GPIO39

ADC2:

  • 10个通道:GPIO0、GPIO2、GPIO4、GPIO12-GPIO15、GOIO25-GPIO27

ESP-IDF 编程指南——ADC

1.1 ADC限制

  • Wi-Fi 驱动程序使用了 ADC2。因此,应用程序只能在未启动 Wi-Fi 驱动程序时使用 ADC2
  • 某些 ADC2 引脚用作捆扎引脚(GPIO 0,2,15),因此无法自由使用。
    ESP32 DevKitC : 由于外部自动编程电路,无法使用 GPIO 0。
    ESP-WROVER-KIT : GPIO 0, 2, 4 和 15 由于不同用途的外部连接而无法使用。

1.2 ADC 采样模式

每个 ADC 单元支持两种工作模式,ADC 单次采样模式和ADC连续采样(DMA)模式。

  • ADC 单次采样模式适用于低频采样操作。
  • ADC 连续采样(DMA)模式适用于高频连续采样动作。

二、API说明

以下 ADC 接口位于 driver/esp32/include/driver/adc.hdriver/include/driver/adc_common.hesp_adc_cal/include/esp_adc_cal.h

2.1 adc1_config_width

2.2 adc1_config_channel_atten

2.3 adc1_get_raw

2.4 esp_adc_cal_check_efuse

2.5 esp_adc_cal_characterize

2.6 esp_adc_cal_raw_to_voltage

三、编程流程

3.1 设置精度、衰减倍数和通道引脚

ADC 应该在读取之前配置。

  • 对于 ADC1,通过调用函数adc1_config_width()和配置所需的精度和衰减adc1_config_channel_atten()
  • 对于 ADC2,将衰减配置为adc2_config_channel_atten()。每次读取时都会配置ADC2的读取宽度。
  • 精度
    ESP32的内置12位ADC可以在9位到12位的精度之间调整。
typedef enum {ADC_WIDTH_BIT_9  = 0, /*!< ADC capture width is 9Bit*/ADC_WIDTH_BIT_10 = 1, /*!< ADC capture width is 10Bit*/ADC_WIDTH_BIT_11 = 2, /*!< ADC capture width is 11Bit*/ADC_WIDTH_BIT_12 = 3, /*!< ADC capture width is 12Bit*/ADC_WIDTH_MAX,
} adc_bits_width_t;
  • 衰减倍数
    不同的衰减倍数对应不同的检测电压范围。

    ADC的默认满量程电压为1.1V。要读取更高的电压(最高为引脚最大电压,通常为3.3V),则需要将该ADC通道的信号衰减设置为> 0dB。

    当VDD_A为3.3V时:

    • 0dB衰减(ADC_ATTEN_0db)表示参考电压为1.1V
    • 2.5dB衰减(ADC_ATTEN_2_5db)表示参考电压为1.5V
    • 6dB衰减(ADC_ATTEN_6db)表示参考电压为2.2V
    • 11dB衰减(ADC_ATTEN_11db)表示参考电压为3.9V
typedef enum {ADC_ATTEN_DB_0   = 0,  /*!<No input attenumation, ADC can measure up to approx. 800 mV. */ADC_ATTEN_DB_2_5 = 1,  /*!<The input voltage of ADC will be attenuated, extending the range of measurement to up to approx. 1100 mV. */ADC_ATTEN_DB_6   = 2,  /*!<The input voltage of ADC will be attenuated, extending the range of measurement to up to  approx. 1350 mV. */ADC_ATTEN_DB_11  = 3,  /*!<The input voltage of ADC will be attenuated, extending the range of measurement to up to  approx. 2600 mV. */ADC_ATTEN_MAX,
} adc_atten_t;
  • 通道引脚
    两个12位的ADC,其中ADC1(8个通道,连接到GPIO 32-39)和ADC2(10个通道,连接到GPIO 0、2、4、12-15和25-27)。
typedef enum {ADC1_CHANNEL_0 = 0, /*!< ADC1 channel 0 is GPIO36 */ADC1_CHANNEL_1,     /*!< ADC1 channel 1 is GPIO37 */ADC1_CHANNEL_2,     /*!< ADC1 channel 2 is GPIO38 */ADC1_CHANNEL_3,     /*!< ADC1 channel 3 is GPIO39 */ADC1_CHANNEL_4,     /*!< ADC1 channel 4 is GPIO32 */ADC1_CHANNEL_5,     /*!< ADC1 channel 5 is GPIO33 */ADC1_CHANNEL_6,     /*!< ADC1 channel 6 is GPIO34 */ADC1_CHANNEL_7,     /*!< ADC1 channel 7 is GPIO35 */ADC1_CHANNEL_MAX,
} adc1_channel_t;typedef enum {ADC2_CHANNEL_0 = 0, /*!< ADC2 channel 0 is GPIO4 */ADC2_CHANNEL_1,     /*!< ADC2 channel 1 is GPIO0 */ADC2_CHANNEL_2,     /*!< ADC2 channel 2 is GPIO2 */ADC2_CHANNEL_3,     /*!< ADC2 channel 3 is GPIO15 */ADC2_CHANNEL_4,     /*!< ADC2 channel 4 is GPIO13 */ADC2_CHANNEL_5,     /*!< ADC2 channel 5 is GPIO12 */ADC2_CHANNEL_6,     /*!< ADC2 channel 6 is GPIO14 */ADC2_CHANNEL_7,     /*!< ADC2 channel 7 is GPIO27 */ADC2_CHANNEL_8,     /*!< ADC2 channel 8 is GPIO25 */ADC2_CHANNEL_9,     /*!< ADC2 channel 9 is GPIO26 */ADC2_CHANNEL_MAX,
} adc2_channel_t;

3.2 读取转换结果

adc1_get_raw()和读取 ADC 转换结果adc2_get_raw()。ADC2 的读取宽度应设置为参数adc2_get_raw()而不是在配置函数中。

也可以通过调用专用函数通过 ADC1 读取内部霍尔效应传感器hall_sensor_read()。请注意,即使霍尔传感器也是 ESP32 内部的,从它读取使用 ADC1 的通道 0 和 3(GPIO 36 和 39)。不要将任何其他东西连接到这些引脚,也不要更改它们的配置。否则可能会影响来自传感器的低值信号的测量。

此 API 提供了配置 ADC1 以从ULP读取的便捷方法。为此,请调用函数adc1_ulp_enable(),然后如上所述设置精度和衰减。

还有另一个特定功能adc_vref_to_gpio()用于将内部参考电压路由到 GPIO 引脚。

四、应用实例

4.1 ADC1单次采集

读取 ADC1 通道 7 (GPIO 35) 上的电压,输入电压为 0 至 1.1 V(0 dB 衰减)
具体代码查看 esp-idf\examples\peripherals\adc 中的例程

#include <driver/adc.h>static const adc_channel_t channel = ADC1_CHANNEL_7;     //GPIO35 if ADC1
...adc1_config_width(ADC_WIDTH_BIT_12);adc1_config_channel_atten(channel, ADC_ATTEN_DB_0);int val = adc1_get_raw(channel);

4.2 ADC2单次采集

读取 ADC2 通道 7 (GPIO 27) 上的电压
具体代码查看 esp-idf\examples\peripherals\adc2 中的例程

#include <driver/adc.h>
...int read_raw;adc2_config_channel_atten( ADC2_CHANNEL_7, ADC_ATTEN_0db );esp_err_t r = adc2_get_raw( ADC2_CHANNEL_7, ADC_WIDTH_12Bit, &read_raw);if ( r == ESP_OK ) {printf("%d\n", read_raw );} else if ( r == ESP_ERR_TIMEOUT ) {printf("ADC2 used by Wi-Fi.\n");}

读取可能会因为与 Wi-Fi 冲突而失败,如果该 API 的返回值为ESP_ERR_INVALID_STATE,则读取结果无效。

4.3 ADC DMA

具体代码查看 components/driver/test/adc_dma_test 中的例程

4.4 ADC校准

具体代码查看 esp-idf\examples\peripherals\adc 中的例程
在特定衰减下表征 ADC:

#include "driver/adc.h"
#include "esp_adc_cal.h"
...//Characterize ADC at particular attenesp_adc_cal_characteristics_t *adc_chars = calloc(1, sizeof(esp_adc_cal_characteristics_t));esp_adc_cal_value_t val_type = esp_adc_cal_characterize(unit, atten, ADC_WIDTH_BIT_12, DEFAULT_VREF, adc_chars);//Check type of calibration value used to characterize ADCif (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) {printf("eFuse Vref");} else if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) {printf("Two Point");} else {printf("Default");}

读取 ADC,然后将读数转换为电压:

#include "driver/adc.h"
#include "esp_adc_cal.h"
...uint32_t reading =  adc1_get_raw(ADC1_CHANNEL_5);uint32_t voltage = esp_adc_cal_raw_to_voltage(reading, adc_chars);

将 ADC 参考电压路由到 GPIO,因此可以手动测量(对于默认 Vref):

#include "driver/adc.h"
...esp_err_t status = adc_vref_to_gpio(ADC_UNIT_1, GPIO_NUM_25);if (status == ESP_OK) {printf("v_ref routed to GPIO\n");} else {printf("failed to route v_ref\n");}

4.5 读取内部霍尔效应传感器

#include <driver/adc.h>
...adc1_config_width(ADC_WIDTH_BIT_12);int val = hall_sensor_read();

• 由 Leung 写于 2021 年 6 月 4 日

• 参考:ESP32 开发笔记(三)源码示例 4_ADC_LightR 利用ADC读取光敏电阻实现光线传感
    ESP32-ADC学习
    ESP32S2的ADC出坑记录

ESP32学习笔记(22)——ADC接口使用相关推荐

  1. ESP32学习笔记(20)——SPI(从机)接口使用

    一.SPI简介 SPI(Serial Peripheral Interface) 协议是由摩托罗拉公司提出的通讯协议,即串行外围设备接口,是一种高速全双工的通信总线.它被广泛地使用在 ADC.LCD ...

  2. ESP32学习笔记(19)——SPI(主机)接口使用

    一.SPI简介 SPI(Serial Peripheral Interface) 协议是由摩托罗拉公司提出的通讯协议,即串行外围设备接口,是一种高速全双工的通信总线.它被广泛地使用在 ADC.LCD ...

  3. ESP32学习笔记(7)——SmartConfig接口使用(ESP-Touch和AirKiss)

    一.概述 SmartConfig是TI开发的一种配置技术,用于将新的Wi-Fi设备连接到Wi-Fi网络.它使用移动应用程序将网络凭据从智能手机或平板电脑广播到未配置的Wi-Fi设备. 该技术的优点是设 ...

  4. ESP32学习笔记(27)——BLE GAP主机端扫描

    一.背景 1.1 低功耗蓝牙(BLE)协议栈 链路层(LL) 控制设备的射频状态,有五个设备状态:待机.广播.扫描.初始化和连接. 广播 为广播数据包,而 扫描 则是监听广播. GAP通信中角色,中心 ...

  5. Java学习笔记22:并发(2)

    Java学习笔记22:并发(2) 图源:PHP中文网 终止任务 终止线程有一种非常简单的方式:设置一个多线程共享的标记位,子线程用轮询的方式检查这个标记位,如果该标记位显示取消状态,就让子线程退出执行 ...

  6. ESP32学习笔记(49)——RFID RC522使用

    一.简介 MF RC522 是应用于 13.56MHz 非接触式通信中高集成度读写卡系列芯片中的一员.是 NXP 公司针对"三表"应用推出的一款低电压.低成本.体积小的非接触式读写 ...

  7. ESP32学习笔记(一) 芯片型号介绍

    ESP32学习笔记(一) 芯片型号介绍 目录: ESP32学习笔记(一) 芯片型号介绍 ESP32学习笔记(二) 开发环境搭建 VSCode+platformio ESP32学习笔记(三) 硬件资源介 ...

  8. ESP32学习笔记(30)——BLE GATT服务端自定义服务和特征

    一.简介 1.1 低功耗蓝牙(BLE)协议栈 链路层(LL) 控制设备的射频状态,有五个设备状态:待机.广播.扫描.初始化和连接. 广播 为广播数据包,而 扫描 则是监听广播. GAP通信中角色,中心 ...

  9. [ESP32]学习笔记03

    今天我们使用ESP32自带的LEDC外设制作一个LED呼吸灯 目录 前言 一.呼吸灯是什么 二.首先我们在Blink实例的基础上建立工程 1.引入库添加宏定义 2.修改主函数 最后我们看一下呼吸灯的效 ...

  10. ESP32学习笔记(14)——HTTP服务器

    一.HTTP简介 HTTP(Hyper Text Transfer Protocol) 超文本传输协议,是一种建立在 TCP 上的无状态连接,整个基本的工作流程是客户端发送一个 HTTP 请求,说明客 ...

最新文章

  1. ICCV2021|单目3D目标检测真的需要伪激光雷达吗?
  2. python3 pyinstaller 打包后执行文件运行错误 No such file or directory 和 Cannot load native module 解决方法
  3. Android之去掉RecycleView和NestedScrollView边缘效果
  4. oracle同一个示例两个用户的数据同步_分享两个shell脚本--一键统计Oracle数据库用户信息...
  5. mysql存储过程 try_mysql存储过程之异常处理篇
  6. View如何设置16进制颜色值
  7. 4.1 Spark SQL概述
  8. [转载]JUnit3 与 JUnit4 的区别
  9. 软件测试车载项目,车载娱乐系统(测试模式)
  10. openoffic需要的jar包
  11. HTML5之插入图片
  12. 机器学习笔记一. 特征工程
  13. 实验吧编程WP(一)
  14. java编写websocket客户端
  15. 机器视觉_HALCON_示例实践_1.检测圆形
  16. 应用在LED植物照明中的LED照明灯
  17. 仪器保养 | 安捷伦DSO-X 2002A示波器自检测/自校准
  18. vs2005+wince开发
  19. 开源 串口调试助手 BaoYuanSerial 使用教程
  20. WebService是什么

热门文章

  1. 学生开发者对于微软技术的反馈
  2. starling 笔记
  3. 使用easypoi将数据导入excel中
  4. ubuntu系统20.4搭建c语言环境,ubuntu 20.04 中文环境和英文环境切换
  5. laplace变换 z变换本质
  6. 基本逻辑思维(命题,语言,定律)
  7. 使用canvas绘制一个动态的表盘
  8. 《信号与系统》奥本海姆第二版中文版勘误
  9. 如何从Lytro 相机中获取图像阵列
  10. mysql_check_mysql CHECK约束 语法