模拟比较器
简介
模拟比较器是一种用于比较信号源与内部参考电压或外部参考信号的外设。
当用于比较模拟信号时,集成模拟比较器可以低成本替代运算放大器。不同于运算放大器的连续比较,ESP 模拟比较器由时钟源驱动,其采样频率取决于时钟的频率。
ESP32-H2 上的模拟比较器有 1 个单元,单元中的通道如下:
UNIT0
源通道:GPIO11
外部参考通道:GPIO10
内部参考通道:电压范围是 VDD 的 0% ~ 70%,步长为 VDD 的 10%
功能概述
本文中的以下章节涵盖了安装及操作模拟比较器单元的基本步骤:
资源分配 - 涵盖了应设置哪些参数以获取单元句柄,以及完成工作后如何回收资源。
进一步配置 - 涵盖了可能需要指定的其他配置及其用途。
启用和禁用单元 - 涵盖了如何启用和禁用单元。
电源管理 - 描述了不同时钟源对功耗的影响。
IRAM 安全 - 列出了在 cache 被禁用时也能起效的函数。
线程安全 - 列出了驱动程序中线程安全的 API。
Kconfig 选项 - 列出了支持的 Kconfig 选项,这些选项可以对驱动程序产生不同影响。
资源分配
模拟比较器单元由 ana_cmpr_handle_t
表示,每个单元都可支持内部或外部的参考信号。
通过调用 ana_cmpr_new_unit()
来获取单元句柄以分配资源。在分配单元时需要指定 ana_cmpr_config_t
配置:
ana_cmpr_config_t::unit
选择模拟比较器单元。ana_cmpr_config_t::clk_src
选择模拟比较器的时钟源,这将影响采样频率。请注意,模拟比较器的时钟源来自 IO MUX,与 Sigma-Delta 调制器 (SDM) 和毛刺过滤器 (Glitch Filter) 等 GPIO 扩展外设共享时钟源。如果为多个 GPIO 扩展外设指定不同的时钟源,则配置将失败。这些外设的默认时钟源是相同的,通常选择soc_periph_ana_cmpr_clk_src_t::ANA_CMPR_CLK_SRC_DEFAULT
即可。ana_cmpr_config_t::ref_src
选择内部参考电压或外部参考信号为参考信号源。ana_cmpr_config_t::cross_type
选择哪种类型的跨零信号可以触发中断。
函数 ana_cmpr_new_unit()
可能因内存不足、参数无效等各种错误而失败。如果不再需要先前创建的模拟比较器单元,可通过调用 ana_cmpr_del_unit()
来回收资源,从而释放底层硬件通道的资源供其他用途。在删除模拟比较器单元句柄之前,首先应通过 ana_cmpr_disable()
禁用句柄,或者确保尚未通过 ana_cmpr_enable()
启用该单元。
#include "driver/ana_cmpr.h"
ana_cmpr_handle_t cmpr = NULL;
ana_cmpr_config_t config = {
.unit = 0,
.clk_src = ANA_CMPR_CLK_SRC_DEFAULT,
.ref_src = ANA_CMPR_REF_SRC_INTERNAL,
.cross_type = ANA_CMPR_CROSS_ANY,
};
ESP_ERROR_CHECK(ana_cmpr_new_unit(&config, &cmpr));
// ...
ESP_ERROR_CHECK(ana_cmpr_del_unit(cmpr));
进一步配置
ana_cmpr_set_internal_reference()
- 选择ana_cmpr_ref_source_t::ANA_CMPR_REF_SRC_INTERNAL
作为参考源时,该函数可以指定内部参考电压。
需要由 ana_cmpr_internal_ref_config_t::ref_volt
来指定电压。该电压受 VDD 电源电压限制,只能支持固定百分比的 VDD。目前在 ESP32-H2 上,内部参考电压范围是 VDD 的 0% ~ 70%,步长为 VDD 的 10%。
#include "driver/ana_cmpr.h"
ana_cmpr_internal_ref_config_t ref_cfg = {
.ref_volt = ANA_CMPR_REF_VOLT_50_PCT_VDD,
};
ESP_ERROR_CHECK(ana_cmpr_set_internal_reference(cmpr, &ref_cfg));
ana_cmpr_set_debounce()
- 设置去抖配置。
通过 ana_cmpr_debounce_config_t::wait_us
可设置中断等待时间。跨零中断触发后,中断将暂时禁用 ana_cmpr_debounce_config_t::wait_us
微秒,这样可以避免信号源跨越参考信号时频繁触发中断。因此,等待时间应与信号源和参考信号之间的相对频率成反比。如果中断等待时间设置得太短,则无法完全避免抖动,但如果设置得太长,则可能会错过下一个跨越中断。
#include "driver/ana_cmpr.h"
ana_cmpr_debounce_config_t dbc_cfg = {
.wait_us = 1,
};
ESP_ERROR_CHECK(ana_cmpr_set_debounce(cmpr, &dbc_cfg));
ana_cmpr_set_cross_type()
- 设置信号源跨越类型。
初始跨越类型在 ana_cmpr_new_unit()
中设置。即便在中断服务程序 (ISR) 的上下文中,此函数也可以更新跨越类型。
#include "driver/ana_cmpr.h"
ESP_ERROR_CHECK(ana_cmpr_set_cross_type(cmpr, ANA_CMPR_CROSS_POS));
ana_cmpr_register_event_callbacks()
- 注册回调函数。
目前支持 ana_cmpr_event_callbacks_t::on_cross
。当发生跨越事件(由 ana_cmpr_config_t::cross_type
指定)时,将调用该回调函数。
#include "driver/ana_cmpr.h"
static bool IRAM_ATTR example_ana_cmpr_on_cross_callback(ana_cmpr_handle_t cmpr,
const ana_cmpr_cross_event_data_t *edata,
void *user_ctx)
{
// ...
return false;
}
ana_cmpr_event_callbacks_t cbs = {
.on_cross = example_ana_cmpr_on_cross_callback,
};
ESP_ERROR_CHECK(ana_cmpr_register_event_callbacks(cmpr, &cbs, NULL));
备注
当启用 CONFIG_ANA_CMPR_ISR_IRAM_SAFE 时,应添加属性 IRAM_ATTR
,确保回调上下文和涉及的数据位于内部 RAM 中(详情请参阅 IRAM 安全)。
启用和禁用单元
ana_cmpr_enable()
- 启用模拟比较器单元。ana_cmpr_disable()
- 禁用模拟比较器单元。
启用模拟比较器单元与跨越事件中断后,若同时启用了电源管理(详见 电源管理),则将获得电源管理锁。在 启用 状态下,只能调用 ana_cmpr_set_internal_reference()
和 ana_cmpr_set_debounce()
,其他函数可在禁用单元后调用。
调用 ana_cmpr_disable()
则会执行与上述过程相反的操作。
电源管理
当启用电源管理时(即开启 CONFIG_PM_ENABLE),系统会在进入 Light-sleep 模式前调整 APB 频率,因此模拟比较器的分辨率也可能随之更改。
通过获取类型为 ESP_PM_NO_LIGHT_SLEEP
的电源管理锁,驱动程序可以防止系统更改 APB 频率。只要驱动程序创建的模拟比较器单元实例选择 ANA_CMPR_CLK_SRC_DEFAULT
或 ANA_CMPR_CLK_SRC_XTAL
作为其时钟源,驱动程序会确保通过 ana_cmpr_enable()
启用通道,并获取电源管理锁。同理,当为该通道调用 ana_cmpr_disable()
时,驱动程序会释放锁。
IRAM 安全
默认情况下,当 cache 因写入或擦除 flash 等原因而被禁用时,模拟比较器的中断服务将会延迟,造成警报中断无法及时执行。在实时应用程序中通常需要避免这一情况发生。
Kconfig 选项 CONFIG_ANA_CMPR_ISR_IRAM_SAFE 支持:
即使 cache 被禁用也能启用中断服务。
将 ISR 使用的所有函数放入 IRAM。 1
将驱动程序对象放入 DRAM(以防它被分配到 PSRAM上)。
启用上述 Kconfig 选项以保证在禁用 cache 时可以正常使用函数,但这会增加 IRAM 消耗。
另一个 Kconfig 选项 CONFIG_ANA_CMPR_CTRL_FUNC_IN_IRAM 也支持将常用的 IO 控制函数放入 IRAM 中,以保证在禁用 cache 时可以正常使用函数。IO 控制函数如下所示:
线程安全
驱动程序会确保工厂函数 ana_cmpr_new_unit()
的线程安全。使用时,可以直接从不同的 RTOS 任务中调用此类函数,无需额外锁保护。
驱动程序设置了临界区,以防函数同时在任务和 ISR 中被调用。因此,以下函数支持在 ISR 上下文运行:
其他以 ana_cmpr_handle_t
为第一个位置参数的函数均非线程安全,因此应避免从多个任务中调用这类函数。
Kconfig 选项
CONFIG_ANA_CMPR_ISR_IRAM_SAFE 控制默认的 ISR 句柄在 cache 被禁用时是否可以正常工作,详见 IRAM 安全。
CONFIG_ANA_CMPR_CTRL_FUNC_IN_IRAM 控制模拟比较器控制函数的存放位置(IRAM 或 flash),详见 IRAM 安全。
CONFIG_ANA_CMPR_ENABLE_DEBUG_LOG 用于启用调试日志输出。启用此选项将增加固件的二进制文件大小。
应用示例
peripherals/analog_comparator 展示了模拟比较器的基本用法以及其他用途(如迟滞比较器和 SPWM 发生器)。
API 参考
Header File
This header file can be included with:
#include "driver/ana_cmpr.h"
This header file is a part of the API provided by the
esp_driver_ana_cmpr
component. To declare that your component depends onesp_driver_ana_cmpr
, add the following to your CMakeLists.txt:REQUIRES esp_driver_ana_cmpr
or
PRIV_REQUIRES esp_driver_ana_cmpr
Functions
-
esp_err_t ana_cmpr_new_unit(const ana_cmpr_config_t *config, ana_cmpr_handle_t *ret_cmpr)
Allocating a new analog comparator unit handle.
- 参数
config -- [in] The config of the analog comparator unit
ret_cmpr -- [out] The returned analog comparator unit handle
- 返回
ESP_OK Allocate analog comparator unit handle success
ESP_ERR_NO_MEM No memory for the analog comparator structure
ESP_ERR_INVALID_ARG NULL pointer of the parameters or wrong unit number
ESP_ERR_INVALID_STATE The unit has been allocated or the clock source has been occupied
-
esp_err_t ana_cmpr_del_unit(ana_cmpr_handle_t cmpr)
Delete the analog comparator unit handle.
- 参数
cmpr -- [in] The handle of analog comparator unit
- 返回
ESP_OK Delete analog comparator unit handle success
ESP_ERR_INVALID_ARG NULL pointer of the parameters or wrong unit number
ESP_ERR_INVALID_STATE The analog comparator is not disabled yet
-
esp_err_t ana_cmpr_set_internal_reference(ana_cmpr_handle_t cmpr, const ana_cmpr_internal_ref_config_t *ref_cfg)
Set internal reference configuration.
备注
This function only need to be called when
ana_cmpr_config_t::ref_src
is ANA_CMPR_REF_SRC_INTERNAL.备注
This function is allowed to run within ISR context including intr callbacks
备注
This function will be placed into IRAM if
CONFIG_ANA_CMPR_CTRL_FUNC_IN_IRAM
is on, so that it's allowed to be executed when Cache is disabled- 参数
cmpr -- [in] The handle of analog comparator unit
ref_cfg -- [in] Internal reference configuration
- 返回
ESP_OK Set denounce configuration success
ESP_ERR_INVALID_ARG NULL pointer of the parameters
ESP_ERR_INVALID_STATE The reference source is not
ANA_CMPR_REF_SRC_INTERNAL
-
esp_err_t ana_cmpr_set_debounce(ana_cmpr_handle_t cmpr, const ana_cmpr_debounce_config_t *dbc_cfg)
Set debounce configuration to the analog comparator.
备注
This function is allowed to run within ISR context including intr callbacks
备注
This function will be placed into IRAM if
CONFIG_ANA_CMPR_CTRL_FUNC_IN_IRAM
is on, so that it's allowed to be executed when Cache is disabled- 参数
cmpr -- [in] The handle of analog comparator unit
dbc_cfg -- [in] Debounce configuration
- 返回
ESP_OK Set denounce configuration success
ESP_ERR_INVALID_ARG NULL pointer of the parameters
-
esp_err_t ana_cmpr_set_cross_type(ana_cmpr_handle_t cmpr, ana_cmpr_cross_type_t cross_type)
Set the source signal cross type.
备注
The initial cross type is configured in
ana_cmpr_new_unit
, this function can update the cross type备注
This function is allowed to run within ISR context including intr callbacks
备注
This function will be placed into IRAM if
CONFIG_ANA_CMPR_CTRL_FUNC_IN_IRAM
is on, so that it's allowed to be executed when Cache is disabled- 参数
cmpr -- [in] The handle of analog comparator unit
cross_type -- [in] The source signal cross type that can trigger the interrupt
- 返回
ESP_OK Set denounce configuration success
ESP_ERR_INVALID_ARG NULL pointer of the parameters
-
esp_err_t ana_cmpr_register_event_callbacks(ana_cmpr_handle_t cmpr, const ana_cmpr_event_callbacks_t *cbs, void *user_data)
Register analog comparator interrupt event callbacks.
备注
This function can only be called before enabling the unit
- 参数
cmpr -- [in] The handle of analog comparator unit
cbs -- [in] Group of callback functions
user_data -- [in] The user data that will be passed to callback functions directly
- 返回
ESP_OK Register callbacks success
ESP_ERR_INVALID_ARG NULL pointer of the parameters
ESP_ERR_INVALID_STATE The analog comparator has been enabled
-
esp_err_t ana_cmpr_enable(ana_cmpr_handle_t cmpr)
Enable the analog comparator unit.
- 参数
cmpr -- [in] The handle of analog comparator unit
- 返回
ESP_OK Enable analog comparator unit success
ESP_ERR_INVALID_ARG NULL pointer of the parameters
ESP_ERR_INVALID_STATE The analog comparator has been enabled
-
esp_err_t ana_cmpr_disable(ana_cmpr_handle_t cmpr)
Disable the analog comparator unit.
- 参数
cmpr -- [in] The handle of analog comparator unit
- 返回
ESP_OK Disable analog comparator unit success
ESP_ERR_INVALID_ARG NULL pointer of the parameters
ESP_ERR_INVALID_STATE The analog comparator has disabled already
-
esp_err_t ana_cmpr_get_gpio(ana_cmpr_unit_t unit, ana_cmpr_channel_type_t chan_type, int *gpio_num)
Get the specific GPIO number of the analog comparator unit.
- 参数
unit -- [in] The handle of analog comparator unit
chan_type -- [in] The channel type of analog comparator, like source channel or reference channel
gpio_num -- [out] The output GPIO number of this channel
- 返回
ESP_OK Get GPIO success
ESP_ERR_INVALID_ARG NULL pointer of the parameters or wrong unit number or wrong channel type
Structures
-
struct ana_cmpr_config_t
Analog comparator unit configuration.
Public Members
-
ana_cmpr_unit_t unit
Analog comparator unit
-
ana_cmpr_clk_src_t clk_src
The clock source of the analog comparator, which decide the resolution of the comparator
-
ana_cmpr_ref_source_t ref_src
Reference signal source of the comparator, select using ANA_CMPR_REF_SRC_INTERNAL or ANA_CMPR_REF_SRC_EXTERNAL. For internal reference, the reference voltage should be set to
internal_ref_volt
, for external reference, the reference signal should be connect toANA_CMPRx_EXT_REF_GPIO
-
ana_cmpr_cross_type_t cross_type
The crossing types that can trigger interrupt
-
int intr_priority
The interrupt priority, range 0~7, if set to 0, the driver will try to allocate an interrupt with a relative low priority (1,2,3) otherwise the larger the higher, 7 is NMI
-
uint32_t io_loop_back
Enable this field when the other signals that output on the comparison pins are supposed to be fed back. Normally used for debug/test scenario
-
struct ana_cmpr_config_t::[anonymous] flags
Analog comparator driver flags
-
ana_cmpr_unit_t unit
-
struct ana_cmpr_internal_ref_config_t
Analog comparator internal reference configuration.
Public Members
-
ana_cmpr_ref_voltage_t ref_volt
The internal reference voltage. It can be specified to a certain fixed percentage of the VDD power supply, currently supports 0%~70% VDD with a step 10%
-
ana_cmpr_ref_voltage_t ref_volt
-
struct ana_cmpr_debounce_config_t
Analog comparator debounce filter configuration.
Public Members
-
uint32_t wait_us
The wait time of re-enabling the interrupt after the last triggering, it is used to avoid the spurious triggering while the source signal crossing the reference signal. The value should regarding how fast the source signal changes, e.g., a rapid signal requires a small wait time, otherwise the next crosses may be missed. (Unit: micro second)
-
uint32_t wait_us
-
struct ana_cmpr_event_callbacks_t
Group of Analog Comparator callbacks.
备注
The callbacks are all running under ISR environment
备注
When CONFIG_ANA_CMPR_ISR_IRAM_SAFE is enabled, the callback itself and functions called by it should be placed in IRAM. The variables used in the function should be in the SRAM as well.
Public Members
-
ana_cmpr_cross_cb_t on_cross
The callback function on cross interrupt
-
ana_cmpr_cross_cb_t on_cross
Header File
components/esp_driver_ana_cmpr/include/driver/ana_cmpr_types.h
This header file can be included with:
#include "driver/ana_cmpr_types.h"
This header file is a part of the API provided by the
esp_driver_ana_cmpr
component. To declare that your component depends onesp_driver_ana_cmpr
, add the following to your CMakeLists.txt:REQUIRES esp_driver_ana_cmpr
or
PRIV_REQUIRES esp_driver_ana_cmpr
Structures
-
struct ana_cmpr_cross_event_data_t
Analog comparator cross event data.
Public Members
-
ana_cmpr_cross_type_t cross_type
The cross type of the target signal to the reference signal. Will either be ANA_CMPR_CROSS_POS or ANA_CMPR_CROSS_NEG Always be ANA_CMPR_CROSS_ANY if target does not support independent interrupt (like ESP32H2)
-
ana_cmpr_cross_type_t cross_type
Macros
-
ANA_CMPR_UNIT_0
- Deprecated:
Analog comparator unit 0
Type Definitions
-
typedef int ana_cmpr_unit_t
Analog comparator unit.
-
typedef struct ana_cmpr_t *ana_cmpr_handle_t
Analog comparator unit handle.
-
typedef soc_periph_ana_cmpr_clk_src_t ana_cmpr_clk_src_t
Analog comparator clock source.
-
typedef bool (*ana_cmpr_cross_cb_t)(ana_cmpr_handle_t cmpr, const ana_cmpr_cross_event_data_t *edata, void *user_ctx)
Prototype of Analog comparator event callback.
- Param cmpr
[in] Analog Comparator handle, created from
ana_cmpr_new_unit()
- Param edata
[in] Point to Analog Comparator event data. The lifecycle of this pointer memory is inside this function, user should copy it into static memory if used outside this function. (Currently not use)
- Param user_ctx
[in] User registered context, passed from
ana_cmpr_register_event_callbacks()
- Return
Whether a high priority task has been waken up by this callback function
Enumerations
-
enum ana_cmpr_ref_source_t
Analog comparator reference source.
Values:
-
enumerator ANA_CMPR_REF_SRC_INTERNAL
Analog Comparator internal reference source, related to VDD
-
enumerator ANA_CMPR_REF_SRC_EXTERNAL
Analog Comparator external reference source, from
ANA_CMPR0_EXT_REF_GPIO
-
enumerator ANA_CMPR_REF_SRC_INTERNAL
-
enum ana_cmpr_channel_type_t
Analog comparator channel type.
Values:
-
enumerator ANA_CMPR_SOURCE_CHAN
Analog Comparator source channel, which is used to input the signal that to be compared
-
enumerator ANA_CMPR_EXT_REF_CHAN
Analog Comparator external reference channel, which is used as the reference signal
-
enumerator ANA_CMPR_SOURCE_CHAN
-
enum ana_cmpr_cross_type_t
Analog comparator interrupt type.
Values:
-
enumerator ANA_CMPR_CROSS_DISABLE
Disable the cross event interrupt
-
enumerator ANA_CMPR_CROSS_POS
Positive cross can trigger event interrupt
-
enumerator ANA_CMPR_CROSS_NEG
Negative cross can trigger event interrupt
-
enumerator ANA_CMPR_CROSS_ANY
Any cross can trigger event interrupt
-
enumerator ANA_CMPR_CROSS_DISABLE
-
enum ana_cmpr_ref_voltage_t
Analog comparator internal reference voltage.
Values:
-
enumerator ANA_CMPR_REF_VOLT_0_PCT_VDD
Internal reference voltage equals to 0% VDD
-
enumerator ANA_CMPR_REF_VOLT_10_PCT_VDD
Internal reference voltage equals to 10% VDD
-
enumerator ANA_CMPR_REF_VOLT_20_PCT_VDD
Internal reference voltage equals to 20% VDD
-
enumerator ANA_CMPR_REF_VOLT_30_PCT_VDD
Internal reference voltage equals to 30% VDD
-
enumerator ANA_CMPR_REF_VOLT_40_PCT_VDD
Internal reference voltage equals to 40% VDD
-
enumerator ANA_CMPR_REF_VOLT_50_PCT_VDD
Internal reference voltage equals to 50% VDD
-
enumerator ANA_CMPR_REF_VOLT_60_PCT_VDD
Internal reference voltage equals to 60% VDD
-
enumerator ANA_CMPR_REF_VOLT_70_PCT_VDD
Internal reference voltage equals to 70% VDD
-
enumerator ANA_CMPR_REF_VOLT_0_PCT_VDD
- 1
ana_cmpr_event_callbacks_t::on_cross
回调函数,以及由其调用的其他函数也应放置在 IRAM 中,请妥善处理。