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_edge和neg_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,
}));
sync_src— 同步源,设为NULL可解除同步。count_value— 同步边沿到达时加载的计数值。direction— 加载后的计数方向,捕获定时器只向上计数,固定为MCPWM_TIMER_DIRECTION_UP。
软件同步与 GPIO 同步源也可让捕获定时器建立已知起点或对齐外部参考,同步源的创建与其余用法详见 同步。
API 参考
MCPWM 捕获驱动函数
Header File
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_mcpwmcomponent. To declare that your component depends onesp_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 channelconfig -- [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
cbsstructure 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_resolutionto 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.
-
uint32_t allow_pd
-
int group_id
-
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
-
mcpwm_sync_handle_t sync_src
-
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.
-
int gpio_num
-
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
-
mcpwm_capture_event_cb_t on_cap