其他分享
首页 > 其他分享> > ESP32学习笔记(22)——ADC接口使用

ESP32学习笔记(22)——ADC接口使用

作者:互联网

一、概述

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

支持以下通道:
ADC1:

  • 8通道:GPIO32 - GPIO39

ADC2:

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

ESP-IDF 编程指南——ADC

1.1 ADC限制

1.2 ADC 采样模式

每个 ADC 单元支持两种工作模式,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 应该在读取之前配置。

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;
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;
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 atten
    esp_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 ADC
    if (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出坑记录

标签:CHANNEL,22,ESP32,ADC2,ADC,ADC1,channel,adc
来源: https://blog.csdn.net/qq_36347513/article/details/117567677