MCPWM 捕获:测量输入脉冲

捕获是独立的 MCPWM 路径:捕获定时器为捕获通道 GPIO 的边沿打时间戳,不需要 PWM 定时器、操作器、比较器或生成器,适用于回波脉冲、转速计、霍尔传感器和 RC 接收机。

它适合"把外部世界发生的时刻带进芯片里"。当你关心的是脉宽、周期、相位差或转速,而不是输出 PWM,本页就是 MCPWM 的另一条主线入口。

测量脉宽

同时捕获两个边沿,保存上升沿时间戳,再用下降沿时间戳减去它。1 MHz 分辨率下,差值的单位直接是微秒。

mcpwm_cap_timer_handle_t cap_timer = NULL;
mcpwm_cap_channel_handle_t cap_channel = NULL;
ESP_ERROR_CHECK(mcpwm_new_capture_timer(
    &(mcpwm_capture_timer_config_t) {
        .group_id = 0,
        .clk_src = MCPWM_CAPTURE_CLK_SRC_DEFAULT,
        .resolution_hz = 1000000,
    }, &cap_timer));
ESP_ERROR_CHECK(mcpwm_new_capture_channel(cap_timer,
    &(mcpwm_capture_channel_config_t) {
        .gpio_num = 6,
        .prescale = 1,
        .flags.pos_edge = true,
        .flags.neg_edge = true,
    }, &cap_channel));

仅分配对象并不会开始测量。还需要使能通道并启动捕获定时器:

ESP_ERROR_CHECK(mcpwm_capture_channel_enable(cap_channel));
ESP_ERROR_CHECK(mcpwm_capture_timer_enable(cap_timer));
ESP_ERROR_CHECK(mcpwm_capture_timer_start(cap_timer));

mcpwm_capture_channel_enable()mcpwm_capture_timer_enable() 负责捕获所需的系统服务准备,二者都尚未开始测量。mcpwm_capture_timer_start() 才真正启动计数器,边沿开始被打上时间戳。

捕获到的边沿值通过回调送达应用,详见下一节。

捕获上升沿与下降沿时间戳,相减得到高电平脉宽。

捕获上升沿和下降沿时间戳,相减得到高电平脉宽。

两个配置结构体分开讲解:

捕获定时器配置

  • group_id — 捕获定时器从哪个 MCPWM 组分配。

  • clk_src — 捕获定时器的时钟源。MCPWM_CAPTURE_CLK_SRC_DEFAULT 适合绝大多数应用。当默认时钟源可能被关闭时需要显式选择其他源——例如低功耗场景下,若所选时钟被关断,捕获定时器会停止,时间戳就会失真。

  • resolution_hz — 捕获定时器的 Tick 频率。一个 Tick 持续 1 / resolution_hz 秒,1 MHz 即微秒级分辨率,直接决定每次捕获时间戳的精度。

  • allow_pd — 允许睡眠时关闭 MCPWM 电源域,在睡眠前后备份并恢复捕获寄存器,代价是额外占用 RAM。

捕获通道配置

  • gpio_num — 承载输入信号的 GPIO。

  • prescale — 捕获前对输入信号分频,有效输入频率为捕获时钟除以 prescale。提高它可扩展可测周期范围,但会降低时间分辨率。

  • pos_edgeneg_edge — 捕获哪些边沿。示例同时捕获两个边沿,这正是脉宽测量所需的。

  • invert_cap_signal — 捕获前反相输入信号,让引脚上的逻辑 1 在捕获外设看来是 0,反之亦然。

  • intr_priority — 捕获回调使用的中断优先级。不设置(0)时由驱动选择较低优先级。

备注

捕获驱动会把 GPIO 配置为输入,但不会设置任何上拉或下拉电阻。如果输入信号并非主动驱动到两个电平,请调用 gpio_set_pull_mode() 选择上拉或下拉方向,让引脚空闲时保持在你期望的电平。

捕获事件回调

事件数据告知边沿类型和锁存计数值。真实应用中应将耗时工作留给任务。

static uint32_t rise_tick;
static bool IRAM_ATTR on_capture(mcpwm_cap_channel_handle_t channel,
                                 const mcpwm_capture_event_data_t *edata,
                                 void *user_data)
{
    if (edata->cap_edge == MCPWM_CAP_EDGE_POS) {
        rise_tick = edata->cap_value;
    } else {
        uint32_t width_ticks = edata->cap_value - rise_tick;
        // 使用 ISR 安全方式将 width_ticks 通知任务
    }
    return false;
}

ESP_ERROR_CHECK(mcpwm_capture_channel_register_event_callbacks(cap_channel,
    &(mcpwm_capture_event_callbacks_t) { .on_cap = on_capture }, NULL));

通过 mcpwm_capture_timer_get_resolution() 获取实际分辨率后,再将 Tick 转换为时间。在捕获时钟与 MCPWM 组时钟共享的芯片上,应保持一致的请求分辨率顺序创建捕获和 PWM 定时器。

若要测转速或周期,可记录两次同类边沿(例如两次上升沿)的时间戳,相减得到周期 Tick 数,再结合实际分辨率换算为频率或转速。

实用控制

mcpwm_capture_channel_trigger_soft_catch() 生成软件捕获事件,常用于测试,也可借此把重要软件事件的发生时刻落到捕获时间轴上,与硬件边沿时间戳对齐;该调用同样会触发回调。mcpwm_capture_get_latched_value() 在不注册回调的情况下也能读取最新时间戳。

mcpwm_capture_timer_stop() 使计数器停止,mcpwm_capture_channel_disable() 可关闭单个输入,停止定时器则关闭整个测量引擎。删除对象前,先调用 mcpwm_capture_timer_disable() 撤销 mcpwm_capture_timer_enable() 做的准备工作。

捕获定时器同步

捕获定时器默认自由运行,计数值的“零点”是任意的,时间戳只能互相比较。同步让运行中的捕获定时器在同步边沿到来时加载一个指定计数值,从而把时间戳对应到有意义的参考系。

最常见的场景是让捕获定时器与 PWM 定时器对齐相位:以 PWM 定时器每周期零(TEZ)发出的同步为源、计数值设为 0,捕获定时器每个周期归零,捕获时间戳就直接表示周期内的相位。这在电机控制或功率变换中尤为重要——霍尔、编码器或电流检测的反馈边沿只有落在 PWM 周期的具体相位才有意义。

同步源与 PWM 定时器共用(GPIO、软件、定时器三种,须与捕获定时器同组),接收端用 mcpwm_capture_timer_set_phase_on_sync() 配置:

ESP_ERROR_CHECK(mcpwm_capture_timer_set_phase_on_sync(cap_timer,
    &(mcpwm_capture_timer_sync_phase_config_t) {
        .sync_src = timer_a_sync,  // 由 mcpwm_new_timer_sync_src() 创建的同步源
        .count_value = 0,
        .direction = MCPWM_TIMER_DIRECTION_UP,
    }));

软件同步与 GPIO 同步源也可让捕获定时器建立已知起点或对齐外部参考,同步源的创建与其余用法详见 同步

API 参考

MCPWM 捕获驱动函数

Header File

  • components/esp_driver_mcpwm/include/driver/mcpwm_cap.h

  • This header file can be included with:

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

    REQUIRES esp_driver_mcpwm
    

    or

    PRIV_REQUIRES esp_driver_mcpwm
    

Functions

esp_err_t mcpwm_new_capture_timer(const mcpwm_capture_timer_config_t *config, mcpwm_cap_timer_handle_t *ret_cap_timer)

Create MCPWM capture timer.

参数:
  • config -- [in] MCPWM capture timer configuration

  • ret_cap_timer -- [out] Returned MCPWM capture timer handle

返回:

  • ESP_OK: Create MCPWM capture timer successfully

  • ESP_ERR_INVALID_ARG: Create MCPWM capture timer failed because of invalid argument

  • ESP_ERR_NO_MEM: Create MCPWM capture timer failed because out of memory

  • ESP_ERR_NOT_FOUND: Create MCPWM capture timer failed because can't find free resource

  • ESP_FAIL: Create MCPWM capture timer failed because of other error

esp_err_t mcpwm_del_capture_timer(mcpwm_cap_timer_handle_t cap_timer)

Delete MCPWM capture timer.

参数:

cap_timer -- [in] MCPWM capture timer, allocated by mcpwm_new_capture_timer()

返回:

  • ESP_OK: Delete MCPWM capture timer successfully

  • ESP_ERR_INVALID_ARG: Delete MCPWM capture timer failed because of invalid argument

  • ESP_FAIL: Delete MCPWM capture timer failed because of other error

esp_err_t mcpwm_capture_timer_enable(mcpwm_cap_timer_handle_t cap_timer)

Enable MCPWM capture timer.

参数:

cap_timer -- [in] MCPWM capture timer handle, allocated by mcpwm_new_capture_timer()

返回:

  • ESP_OK: Enable MCPWM capture timer successfully

  • ESP_ERR_INVALID_ARG: Enable MCPWM capture timer failed because of invalid argument

  • ESP_ERR_INVALID_STATE: Enable MCPWM capture timer failed because timer is enabled already

  • ESP_FAIL: Enable MCPWM capture timer failed because of other error

esp_err_t mcpwm_capture_timer_disable(mcpwm_cap_timer_handle_t cap_timer)

Disable MCPWM capture timer.

参数:

cap_timer -- [in] MCPWM capture timer handle, allocated by mcpwm_new_capture_timer()

返回:

  • ESP_OK: Disable MCPWM capture timer successfully

  • ESP_ERR_INVALID_ARG: Disable MCPWM capture timer failed because of invalid argument

  • ESP_ERR_INVALID_STATE: Disable MCPWM capture timer failed because timer is disabled already

  • ESP_FAIL: Disable MCPWM capture timer failed because of other error

esp_err_t mcpwm_capture_timer_start(mcpwm_cap_timer_handle_t cap_timer)

Start MCPWM capture timer.

参数:

cap_timer -- [in] MCPWM capture timer, allocated by mcpwm_new_capture_timer()

返回:

  • ESP_OK: Start MCPWM capture timer successfully

  • ESP_ERR_INVALID_ARG: Start MCPWM capture timer failed because of invalid argument

  • ESP_FAIL: Start MCPWM capture timer failed because of other error

esp_err_t mcpwm_capture_timer_stop(mcpwm_cap_timer_handle_t cap_timer)

Stop MCPWM capture timer.

参数:

cap_timer -- [in] MCPWM capture timer, allocated by mcpwm_new_capture_timer()

返回:

  • ESP_OK: Stop MCPWM capture timer successfully

  • ESP_ERR_INVALID_ARG: Stop MCPWM capture timer failed because of invalid argument

  • ESP_FAIL: Stop MCPWM capture timer failed because of other error

esp_err_t mcpwm_capture_timer_get_resolution(mcpwm_cap_timer_handle_t cap_timer, uint32_t *out_resolution)

Get MCPWM capture timer resolution, in Hz.

参数:
  • cap_timer -- [in] MCPWM capture timer, allocated by mcpwm_new_capture_timer()

  • out_resolution -- [out] Returned capture timer resolution, in Hz

返回:

  • ESP_OK: Get capture timer resolution successfully

  • ESP_ERR_INVALID_ARG: Get capture timer resolution failed because of invalid argument

  • ESP_FAIL: Get capture timer resolution failed because of other error

esp_err_t mcpwm_capture_timer_set_phase_on_sync(mcpwm_cap_timer_handle_t cap_timer, const mcpwm_capture_timer_sync_phase_config_t *config)

Set sync phase for MCPWM capture timer.

参数:
  • cap_timer -- [in] MCPWM capture timer, allocated by mcpwm_new_capture_timer()

  • config -- [in] MCPWM capture timer sync phase configuration

返回:

  • ESP_OK: Set sync phase for MCPWM capture timer successfully

  • ESP_ERR_INVALID_ARG: Set sync phase for MCPWM capture timer failed because of invalid argument

  • ESP_FAIL: Set sync phase for MCPWM capture timer failed because of other error

esp_err_t mcpwm_new_capture_channel(mcpwm_cap_timer_handle_t cap_timer, const mcpwm_capture_channel_config_t *config, mcpwm_cap_channel_handle_t *ret_cap_channel)

Create MCPWM capture channel.

备注

The created capture channel won't be enabled until calling mcpwm_capture_channel_enable

参数:
  • cap_timer -- [in] MCPWM capture timer, allocated by mcpwm_new_capture_timer(), will be connected to the new capture channel

  • config -- [in] MCPWM capture channel configuration

  • ret_cap_channel -- [out] Returned MCPWM capture channel

返回:

  • ESP_OK: Create MCPWM capture channel successfully

  • ESP_ERR_INVALID_ARG: Create MCPWM capture channel failed because of invalid argument

  • ESP_ERR_NO_MEM: Create MCPWM capture channel failed because out of memory

  • ESP_ERR_NOT_FOUND: Create MCPWM capture channel failed because can't find free resource

  • ESP_FAIL: Create MCPWM capture channel failed because of other error

esp_err_t mcpwm_del_capture_channel(mcpwm_cap_channel_handle_t cap_channel)

Delete MCPWM capture channel.

参数:

cap_channel -- [in] MCPWM capture channel handle, allocated by mcpwm_new_capture_channel()

返回:

  • ESP_OK: Delete MCPWM capture channel successfully

  • ESP_ERR_INVALID_ARG: Delete MCPWM capture channel failed because of invalid argument

  • ESP_FAIL: Delete MCPWM capture channel failed because of other error

esp_err_t mcpwm_capture_channel_enable(mcpwm_cap_channel_handle_t cap_channel)

Enable MCPWM capture channel.

备注

This function will transit the channel state from init to enable.

备注

This function will enable the interrupt service, if it's lazy installed in mcpwm_capture_channel_register_event_callbacks().

参数:

cap_channel -- [in] MCPWM capture channel handle, allocated by mcpwm_new_capture_channel()

返回:

  • ESP_OK: Enable MCPWM capture channel successfully

  • ESP_ERR_INVALID_ARG: Enable MCPWM capture channel failed because of invalid argument

  • ESP_ERR_INVALID_STATE: Enable MCPWM capture channel failed because the channel is already enabled

  • ESP_FAIL: Enable MCPWM capture channel failed because of other error

esp_err_t mcpwm_capture_channel_disable(mcpwm_cap_channel_handle_t cap_channel)

Disable MCPWM capture channel.

参数:

cap_channel -- [in] MCPWM capture channel handle, allocated by mcpwm_new_capture_channel()

返回:

  • ESP_OK: Disable MCPWM capture channel successfully

  • ESP_ERR_INVALID_ARG: Disable MCPWM capture channel failed because of invalid argument

  • ESP_ERR_INVALID_STATE: Disable MCPWM capture channel failed because the channel is not enabled yet

  • ESP_FAIL: Disable MCPWM capture channel failed because of other error

esp_err_t mcpwm_capture_channel_register_event_callbacks(mcpwm_cap_channel_handle_t cap_channel, const mcpwm_capture_event_callbacks_t *cbs, void *user_data)

Set event callbacks for MCPWM capture channel.

备注

The first call to this function needs to be before the call to mcpwm_capture_channel_enable

备注

User can deregister a previously registered callback by calling this function and setting the callback member in the cbs structure to NULL.

参数:
  • cap_channel -- [in] MCPWM capture channel handle, allocated by mcpwm_new_capture_channel()

  • cbs -- [in] Group of callback functions

  • user_data -- [in] User data, which will be passed to callback functions directly

返回:

  • ESP_OK: Set event callbacks successfully

  • ESP_ERR_INVALID_ARG: Set event callbacks failed because of invalid argument

  • ESP_ERR_INVALID_STATE: Set event callbacks failed because the channel is not in init state

  • ESP_FAIL: Set event callbacks failed because of other error

esp_err_t mcpwm_capture_channel_trigger_soft_catch(mcpwm_cap_channel_handle_t cap_channel)

Trigger a catch by software.

参数:

cap_channel -- [in] MCPWM capture channel handle, allocated by mcpwm_new_capture_channel()

返回:

  • ESP_OK: Trigger software catch successfully

  • ESP_ERR_INVALID_ARG: Trigger software catch failed because of invalid argument

  • ESP_ERR_INVALID_STATE: Trigger software catch failed because the channel is not enabled yet

  • ESP_FAIL: Trigger software catch failed because of other error

esp_err_t mcpwm_capture_get_latched_value(mcpwm_cap_channel_handle_t cap_channel, uint32_t *value)

Get the last captured value of the MCPWM capture channel.

备注

To convert the count value to a time, user can use mcpwm_capture_timer_get_resolution to get the resolution of the capture timer.

参数:
  • cap_channel -- [in] MCPWM capture channel handle, allocated by mcpwm_new_capture_channel()

  • value -- [out] Returned capture value

返回:

  • ESP_OK: Get capture value successfully

  • ESP_ERR_INVALID_ARG: Get capture value failed because of invalid argument

  • ESP_FAIL: Get capture value failed because of other error

Structures

struct mcpwm_capture_timer_config_t

MCPWM capture timer configuration structure.

Public Members

int group_id

Specify from which group to allocate the capture timer

mcpwm_capture_clock_source_t clk_src

MCPWM capture timer clock source

uint32_t resolution_hz

Resolution of capture timer

struct mcpwm_capture_timer_config_t::extra_mcpwm_capture_timer_flags flags

Extra configuration flags for timer

struct extra_mcpwm_capture_timer_flags

Extra configuration flags for capture timer.

Public Members

uint32_t allow_pd

Set to allow power down. When this flag set, the driver will backup/restore the MCPWM registers before/after entering/exist sleep mode. By this approach, the system can power off MCPWM's power domain. This can save power, but at the expense of more RAM being consumed.

struct mcpwm_capture_timer_sync_phase_config_t

MCPWM Capture timer sync phase configuration.

Public Members

mcpwm_sync_handle_t sync_src

The sync event source

uint32_t count_value

The count value that should lock to upon sync event

mcpwm_timer_direction_t direction

The count direction that should lock to upon sync event

struct mcpwm_capture_channel_config_t

MCPWM capture channel configuration structure.

Public Members

int gpio_num

GPIO used capturing input signal

int intr_priority

MCPWM capture interrupt priority, if set to 0, the driver will try to allocate an interrupt with a relative low priority (1,2,3)

uint32_t prescale

Prescale of input signal, effective frequency = cap_input_clk/prescale

struct mcpwm_capture_channel_config_t::extra_capture_channel_flags flags

Extra configuration flags for capture channel

struct extra_capture_channel_flags

Extra configuration flags for capture channel.

Public Members

uint32_t pos_edge

Whether to capture on positive edge

uint32_t neg_edge

Whether to capture on negative edge

uint32_t invert_cap_signal

Invert the input capture signal

struct mcpwm_capture_event_callbacks_t

Group of supported MCPWM capture event callbacks.

备注

The callbacks are all running under ISR environment

Public Members

mcpwm_capture_event_cb_t on_cap

Callback function that would be invoked when capture event occurred


此文档对您有帮助吗?