模数转换器 (ADC) 校准驱动程序

[English]

简介

在 ESP32-C6 中,模数转换器 (ADC) 比较输入的模拟电压和参考电压,以确定每一位数字输出结果。ESP32-C6 设计的 ADC 参考电压为 1100 mV。然而,不同芯片的真实参考电压可能会略有变化,范围在 1000 mV 到 1200 mV 之间。本文介绍了 ADC 校准驱动程序,可以降低参考电压不同带来的影响,获取更准确的输出结果。

功能概述

下文将分节概述安装和使用 ADC 校准驱动程序的基本步骤:

  • 创建校准方案 - 介绍如何创建和删除校准方案句柄。

  • 结果转换 - 介绍如何将原始 ADC 结果转换为校准后的结果。

  • 线程安全 - 列出由驱动程序认证为线程安全的 API。

  • 减少噪声 - 介绍一种常见的降低噪声的方法。

创建校准方案

ADC 校准驱动程序会提供 ADC 校准方案。对于驱动程序来说,每个 ADC 校准方案对应一个 ADC 校准句柄 adc_cali_handle_t

使用 adc_cali_check_scheme() 可以查看芯片支持的校准方案。若已了解芯片支持的校准方案,可以跳过该步骤,直接调用对应函数创建校准方案句柄。

使用自定义 ADC 校准方案时,可以选择调整函数 adc_cali_check_scheme(),或直接跳过该步骤,调用自定义函数创建校准方案句柄。

ADC 校准曲线拟合方案

ESP32-C6 支持 ADC_CALI_SCHEME_VER_CURVE_FITTING 方案。要创建此方案,请先根据以下配置选项,设置 adc_cali_curve_fitting_config_t

  • adc_cali_curve_fitting_config_t::unit_id,表示 ADC 原始结果来自哪个 ADC 单元。

  • adc_cali_curve_fitting_config_t::chan,表示获取 ADC 原始结果的 ADC 通道。校准方案不仅因衰减程度而异,还与通道选择有关。

  • adc_cali_curve_fitting_config_t::atten,表示 ADC 原始结果的衰减程度。

  • adc_cali_curve_fitting_config_t::bitwidth,表示 ADC 原始结果的位宽。

设置完上述配置结构体后,请调用 adc_cali_create_scheme_curve_fitting() 创建曲线拟合方案句柄。 由于 ESP_ERR_INVALID_ARGESP_ERR_NO_MEM 等原因,该函数调用可能失败。函数返回 ESP_ERR_NOT_SUPPORTED 时,说明你的开发板没有烧录校准方案所需的 eFuse 位。

创建曲线拟合方案句柄
ESP_LOGI(TAG, "calibration scheme version is %s", "Curve Fitting");
adc_cali_curve_fitting_config_t cali_config = {
    .unit_id = unit,
    .atten = atten,
    .bitwidth = ADC_BITWIDTH_DEFAULT,
};
ESP_ERROR_CHECK(adc_cali_create_scheme_curve_fitting(&cali_config, &handle));

ADC 校准使用完毕后,请调用 adc_cali_delete_scheme_curve_fitting(),删除校准方案句柄。

删除曲线拟合方案句柄
ESP_LOGI(TAG, "delete %s calibration scheme", "Curve Fitting");
ESP_ERROR_CHECK(adc_cali_delete_scheme_curve_fitting(handle));

备注

要使用自定义校准方案,可以通过提供创建函数,创建自己的校准方案句柄。请参阅 components/esp_adc/interface/adc_cali_interface.h 中的函数表 adc_cali_scheme_t,了解 ESP ADC 校准接口。

结果转换

对驱动程序进行完上述配置和初始化工作后,可以调用 adc_cali_raw_to_voltage(),将原始 ADC 结果转换为校准结果,校准结果以 mV 为单位。该函数可能因参数无效而调用失败。如果函数返回 ESP_ERR_INVALID_STATE,说明校准方案尚未创建。因此你需要创建一个校准方案句柄,通过 adc_cali_check_scheme() 可以了解当前芯片支持的校准方案;你也可以提供自定义校准方案,创建对应的校准方案句柄。

获取电压

ESP_ERROR_CHECK(adc_cali_raw_to_voltage(adc_cali_handle, adc_raw[0][0], &voltage[0][0]));
ESP_LOGI(TAG, "ADC%d Channel[%d] Cali Voltage: %d mV", ADC_UNIT_1 + 1, EXAMPLE_ADC1_CHAN0, voltage[0][0]);

线程安全

驱动程序会确保工厂函数 esp_adc_cali_new_scheme() 的线程安全,使用时,可以直接从不同的 RTOS 任务中调用此类函数,无需额外锁保护。

其他以 adc_cali_handle_t 作为第一个位置参数的函数均非线程安全,在没有设置互斥锁保护的任务中,应避免从多个任务中调用这类函数。

减少噪声

ESP32-C6 ADC 对噪声敏感,可能导致 ADC 读数出现较大偏差。根据不同使用场景,要减少噪声影响,你可能需要将旁路电容(如 100 nF 陶瓷电容)连接到 ADC 使用的输入管脚。此外,也可以通过多次采样,进一步减轻噪声的影响。

API 参考

Header File

  • components/esp_adc/include/esp_adc/adc_cali.h

  • This header file can be included with:

    #include "esp_adc/adc_cali.h"
    
  • This header file is a part of the API provided by the esp_adc component. To declare that your component depends on esp_adc, add the following to your CMakeLists.txt:

    REQUIRES esp_adc
    

    or

    PRIV_REQUIRES esp_adc
    

Functions

esp_err_t adc_cali_check_scheme(adc_cali_scheme_ver_t *scheme_mask)

Check the supported ADC calibration scheme.

参数

scheme_mask -- [out] Supported ADC calibration scheme(s)

返回

  • ESP_OK: On success

  • ESP_ERR_INVALID_ARG: Invalid argument

  • ESP_ERR_NOT_SUPPORTED: No supported calibration scheme

esp_err_t adc_cali_raw_to_voltage(adc_cali_handle_t handle, int raw, int *voltage)

Convert ADC raw data to calibrated voltage.

参数
  • handle -- [in] ADC calibration handle

  • raw -- [in] ADC raw data

  • voltage -- [out] Calibrated ADC voltage (in mV)

返回

  • ESP_OK: On success

  • ESP_ERR_INVALID_ARG: Invalid argument

  • ESP_ERR_INVALID_STATE: Invalid state, scheme didn't registered

Type Definitions

typedef struct adc_cali_scheme_t *adc_cali_handle_t

ADC calibration handle.

Enumerations

enum adc_cali_scheme_ver_t

ADC calibration scheme.

Values:

enumerator ADC_CALI_SCHEME_VER_LINE_FITTING

Line fitting scheme.

enumerator ADC_CALI_SCHEME_VER_CURVE_FITTING

Curve fitting scheme.

Header File

  • components/esp_adc/include/esp_adc/adc_cali_scheme.h

  • This header file can be included with:

    #include "esp_adc/adc_cali_scheme.h"
    
  • This header file is a part of the API provided by the esp_adc component. To declare that your component depends on esp_adc, add the following to your CMakeLists.txt:

    REQUIRES esp_adc
    

    or

    PRIV_REQUIRES esp_adc