MCPWM 比较器:将比例转换为边沿

当定时器计数达到 cmp_ticks 时,比较器产生事件;生成器再将该事件转换为 GPIO 电平变化。通常在向上计数 PWM 中,比较 Tick 数就是高电平时间。

比较器的实际意义是把"我想要多宽、多晚、多早出现一个边沿"转换成硬件里的具体时刻。运行中的占空比调节,通常就是不断更新比较器阈值。

设置 30% 占空比

从已有操作器创建比较器,再设置阈值。对 定时器 中 50 Tick 的周期,15 Tick 即为 30%。下图展示了比较事件在 Tick 15 处触发——生成器可用此事件结束高电平脉冲。

定时器向上计数;比较器在 Tick 15 触发。生成器将其转换为下降沿。

定时器向上计数;比较器在 Tick 15 触发。生成器将其转换为下降沿。

mcpwm_cmpr_handle_t comparator = NULL;
mcpwm_comparator_config_t comparator_config = {
    .flags.update_cmp_on_tez = true, // 仅在周期边界改变占空比
};
ESP_ERROR_CHECK(mcpwm_new_comparator(oper, &comparator_config, &comparator));
ESP_ERROR_CHECK(mcpwm_comparator_set_compare_value(comparator, 15));

比较器配置除 flags 外只有一个字段:

  • intr_priorityon_reach 回调使用的中断优先级。不设置(0)时由驱动选择较低优先级;当回调需要抢占其他中断时可适当提高。

  • flags — 即下文介绍的更新点。示例启用了 update_cmp_on_tez,这也是在周期边界改变占空比的常见做法。

运行时百分比占空比的计算公式为 period_ticks * percent / 100,结果必须不超过定时器周期。

这也是为什么改变占空比应优先改比较器,而不是改生成器动作:动作定义的是波形规则,比较器定义的是当前边沿位置。前者更像拓扑,后者更像运行参数。

为何要推迟更新

立即更新比较器可能改变当前周期中的边沿。update_cmp_on_tez 会等待计数归零,update_cmp_on_tep 会等待计数到达峰值,update_cmp_on_sync 则等待同步事件。在向上计数或向下计数模式下,峰值即周期边界,与归零点几乎重合,因此 tez 与 tep 对应同一个更新点;仅在向上-向下计数模式下,峰值处于周期中点,tez 与 tep 才是两个不同的更新点。电机和电源转换通常应使用推迟更新。

两个比较器实现脉冲放置

一个比较器每周期产生一个边沿。在同一操作器中使用两个比较器,可在周期内任意位置放置脉冲——一个比较器打开脉冲,另一个关闭。适用于采样窗口、触发信号或非对称死区补偿。

这类需求在电机控制里很常见,例如想把 ADC 采样窗口放在开关噪声较小的位置,或者给外部器件输出一个不位于 PWM 边界的同步脉冲。

mcpwm_cmpr_handle_t cmp_a, cmp_b;
mcpwm_new_comparator(oper, &comparator_config, &cmp_a);
mcpwm_new_comparator(oper, &comparator_config, &cmp_b);
mcpwm_comparator_set_compare_value(cmp_a, 10);
mcpwm_comparator_set_compare_value(cmp_b, 30);

比较事件也可用于精确的软件时间标记

on_reach 回调在比较值到达时触发,适用于软件需要观察 PWM 周期中精确位置的场景。应在启动时间关键型工作前注册。回调在 ISR 上下文运行,应保持简短。

static bool IRAM_ATTR on_compare(mcpwm_cmpr_handle_t cmpr,
                                 const mcpwm_compare_event_data_t *edata,
                                 void *user_ctx)
{
    // 通知任务或仅执行 ISR 安全工作
    return false;
}

mcpwm_comparator_event_callbacks_t callbacks = { .on_reach = on_compare };
ESP_ERROR_CHECK(mcpwm_comparator_register_event_callbacks(comparator,
                                                          &callbacks, NULL));

比较器的种类

操作器比较器 通过 mcpwm_new_comparator() 创建,其比较事件驱动生成器,从而塑造 PWM 输出。

API 参考

MCPWM 比较器驱动函数

Header File

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

  • This header file can be included with:

    #include "driver/mcpwm_cmpr.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_comparator(mcpwm_oper_handle_t oper, const mcpwm_comparator_config_t *config, mcpwm_cmpr_handle_t *ret_cmpr)

Create MCPWM comparator.

参数:
  • oper -- [in] MCPWM operator, allocated by mcpwm_new_operator(), the new comparator will be allocated from this operator

  • config -- [in] MCPWM comparator configuration

  • ret_cmpr -- [out] Returned MCPWM comparator

返回:

  • ESP_OK: Create MCPWM comparator successfully

  • ESP_ERR_INVALID_ARG: Create MCPWM comparator failed because of invalid argument

  • ESP_ERR_NO_MEM: Create MCPWM comparator failed because out of memory

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

  • ESP_FAIL: Create MCPWM comparator failed because of other error

esp_err_t mcpwm_del_comparator(mcpwm_cmpr_handle_t cmpr)

Delete MCPWM comparator.

参数:

cmpr -- [in] MCPWM comparator handle, allocated by mcpwm_new_comparator()

返回:

  • ESP_OK: Delete MCPWM comparator successfully

  • ESP_ERR_INVALID_ARG: Delete MCPWM comparator failed because of invalid argument

  • ESP_FAIL: Delete MCPWM comparator failed because of other error

esp_err_t mcpwm_comparator_register_event_callbacks(mcpwm_cmpr_handle_t cmpr, const mcpwm_comparator_event_callbacks_t *cbs, void *user_data)

Set event callbacks for MCPWM comparator.

备注

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

参数:
  • cmpr -- [in] MCPWM comparator handle, allocated by mcpwm_new_comparator()

  • 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_FAIL: Set event callbacks failed because of other error

esp_err_t mcpwm_comparator_set_compare_value(mcpwm_cmpr_handle_t cmpr, uint32_t cmp_ticks)

Set MCPWM comparator's compare value.

参数:
  • cmpr -- [in] MCPWM comparator handle, allocated by mcpwm_new_comparator()

  • cmp_ticks -- [in] The new compare value

返回:

  • ESP_OK: Set MCPWM compare value successfully

  • ESP_ERR_INVALID_ARG: Set MCPWM compare value failed because of invalid argument (e.g. the cmp_ticks is out of range)

  • ESP_ERR_INVALID_STATE: Set MCPWM compare value failed because the operator doesn't have a timer connected

  • ESP_FAIL: Set MCPWM compare value failed because of other error

Structures

struct mcpwm_comparator_config_t

MCPWM comparator configuration.

Public Members

int intr_priority

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

struct mcpwm_comparator_config_t::extra_mcpwm_comparator_flags flags

Extra configuration flags for comparator

struct extra_mcpwm_comparator_flags

Extra configuration flags for comparator.

Public Members

uint32_t update_cmp_on_tez

Whether to update compare value when timer count equals to zero (tez)

uint32_t update_cmp_on_tep

Whether to update compare value when timer count equals to peak (tep)

uint32_t update_cmp_on_sync

Whether to update compare value on sync event

struct mcpwm_comparator_event_callbacks_t

Group of supported MCPWM compare event callbacks.

备注

The callbacks are all running under ISR environment

Public Members

mcpwm_compare_event_cb_t on_reach

ISR callback function which would be invoked when counter reaches compare value


此文档对您有帮助吗?