电机控制脉宽调制器 (MCPWM)

[English]

从这里开始

MCPWM 将计数器转换为时序精确的输出边沿。当 LEDC 的简单 PWM 已无法满足需求时,可使用 MCPWM:电机桥需要互补输出和死区,逆变器需要同步相位,传感器则需要精确测量脉宽。

最小可用的 MCPWM 设计由四个对象构成:定时器 提供时间基准,操作器 管理波形资源,比较器 决定边沿位置,生成器 驱动 GPIO。其他模块均在此基础上扩展。

构建一路 PWM 输出

初次生成 PWM 输出时,请按下图从左至右创建对象。主线上各阶段按角色配色:时间基准(蓝色)、操作器核心(紫色)、波形配置(青色)、启用与输出(绿色)。琥珀色节点为基础输出正常后按需添加的扩展,红色节点为安全制动。只有在所有输出动作均已配置完成后,才启动定时器。

        flowchart LR
    T1["1. 创建定时器<br/>mcpwm_new_timer"]:::time
    O1["2. 创建操作器<br/>mcpwm_new_operator"]:::core
    LINK["3. 连接时间基准<br/>mcpwm_operator_connect_timer"]:::core
    C1["4. 创建比较器<br/>mcpwm_new_comparator"]:::wave
    G1["5. 创建生成器<br/>mcpwm_new_generator"]:::wave
    A1["6. 描述边沿<br/>mcpwm_generator_set_action_on_*_event"]:::wave
    RUN["7. 启用并启动<br/>mcpwm_timer_enable<br/>mcpwm_timer_start_stop"]:::run
    PIN["GPIO 输出 PWM"]:::output

    T1 --> O1 --> LINK --> C1 --> G1 --> A1 --> RUN --> PIN

    DT["死区<br/>mcpwm_generator_set_dead_time"]:::optional
    BR["故障与制动<br/>mcpwm_new_*_fault<br/>mcpwm_operator_set_brake_on_fault"]:::safety
    SY["相位同步<br/>mcpwm_new_*_sync_src<br/>mcpwm_timer_set_phase_on_sync"]:::optional
    CA["载波调制<br/>mcpwm_operator_apply_carrier"]:::optional

    A1 -. 扩展 .-> DT
    O1 -. 保护 .-> BR
    T1 -. 对齐 .-> SY
    O1 -. 调制 .-> CA

    classDef time fill:#dbeafe,stroke:#2563eb,color:#172554
    classDef core fill:#ede9fe,stroke:#7c3aed,color:#2e1065
    classDef wave fill:#cffafe,stroke:#0891b2,color:#164e63
    classDef run fill:#dcfce7,stroke:#16a34a,color:#14532d
    classDef output fill:#bbf7d0,stroke:#15803d,color:#14532d
    classDef optional fill:#fef3c7,stroke:#d97706,color:#78350f
    classDef safety fill:#fee2e2,stroke:#dc2626,color:#7f1d1d
    

下面这段代码创建一路 20 kHz、30% 占空比的 PWM 输出,可作为阅读后续各页前的整体参考。它展示了对象的创建顺序,也说明了运行时最常改动的其实是比较器,而不是重新配置整条链路。

mcpwm_timer_handle_t timer = NULL;
mcpwm_oper_handle_t oper = NULL;
mcpwm_cmpr_handle_t comparator = NULL;
mcpwm_gen_handle_t generator = NULL;

// 1 MHz → 1 tick = 1 µs
// 50 ticks → 50 µs 周期 → 20 kHz
ESP_ERROR_CHECK(mcpwm_new_timer(
    &(mcpwm_timer_config_t) {
        .group_id = 0,
        .clk_src = MCPWM_TIMER_CLK_SRC_DEFAULT,
        .resolution_hz = 1000000,
        .period_ticks = 50,
        .count_mode = MCPWM_TIMER_COUNT_MODE_UP,
    },
    &timer));

ESP_ERROR_CHECK(mcpwm_new_operator(
    &(mcpwm_operator_config_t) {
        .group_id = 0,
    },
    &oper));
ESP_ERROR_CHECK(mcpwm_operator_connect_timer(oper, timer));

ESP_ERROR_CHECK(mcpwm_new_comparator(
    oper,
    &(mcpwm_comparator_config_t) {
        .flags.update_cmp_on_tez = true,
    },
    &comparator));
// 15 / 50 = 30% 占空比
ESP_ERROR_CHECK(mcpwm_comparator_set_compare_value(comparator, 15));

ESP_ERROR_CHECK(mcpwm_new_generator(
    oper,
    &(mcpwm_generator_config_t) {
        .gen_gpio_num = 18,
    },
    &generator));

// 定时器归零 → 输出 HIGH;比较器匹配 → 输出 LOW
ESP_ERROR_CHECK(mcpwm_generator_set_action_on_timer_event(
    generator,
    MCPWM_GEN_TIMER_EVENT_ACTION(
        MCPWM_TIMER_DIRECTION_UP,
        MCPWM_TIMER_EVENT_EMPTY,
        MCPWM_GEN_ACTION_HIGH)));
ESP_ERROR_CHECK(mcpwm_generator_set_action_on_compare_event(
    generator,
    MCPWM_GEN_COMPARE_EVENT_ACTION(
        MCPWM_TIMER_DIRECTION_UP,
        comparator,
        MCPWM_GEN_ACTION_LOW)));

ESP_ERROR_CHECK(mcpwm_timer_enable(timer));
ESP_ERROR_CHECK(mcpwm_timer_start_stop(timer, MCPWM_TIMER_START_NO_STOP));

// 运行时修改比较值即可调整占空比,无需重建生成器动作。
// 25 / 50 = 50% 占空比
ESP_ERROR_CHECK(mcpwm_comparator_set_compare_value(comparator, 25));

定时器的 resolution_hzperiod_ticks 确定时序刻度;比较器的 compare_value 在该刻度中选择边沿位置;生成器动作 API 决定在定时器边界或比较器越过阈值时输出何种电平。这种分工也便于调参:改变定时器可调整频率,改变比较器可调整占空比或边沿位置,改变生成器动作可调整极性或波形形状。

波形配置完成后,调用 mcpwm_timer_enable()mcpwm_timer_start_stop()。运行时应通过 mcpwm_comparator_set_compare_value() 更新比较器,而不是重新配置生成器动作。仅在应用需要时添加对应扩展:半桥使用死区,安全路径使用故障与制动,相位对齐使用同步,隔离式驱动使用载波。

功能地图

目标

先看哪些页

关键 API

典型应用

输出单路 PWM

定时器 -> 操作器 -> 比较器

生成器

mcpwm_new_timer()

mcpwm_new_comparator()

mcpwm_generator_set_action_on_*_event

舵机、调光、基础功率控制

输出互补半桥 PWM

生成器 中的死区小节 + 故障

mcpwm_generator_set_dead_time()

mcpwm_operator_set_brake_on_fault()

半桥、逆变桥臂

多路同频对齐或移相

同步

mcpwm_timer_set_phase_on_sync()

mcpwm_new_timer_sync_src()

多相电机、并联变换器

测量输入脉宽或周期

捕获

mcpwm_new_capture_timer()

mcpwm_capture_channel_register_event_callbacks()

HC-SR04、转速计、RC 输入

外设间硬件联动

ETM

mcpwm_timer_new_etm_event()

mcpwm_new_event_comparator()

ADC 触发、跨外设定时链路

本指南中每个页面介绍一个 MCPWM 模块:

资源与生命周期

所有对象都属于一个 MCPWM 组。连接的定时器与操作器必须位于同一组;GPIO 故障源和 GPIO 同步源也只能在本组中使用。硬件资源有限,创建时可能返回 ESP_ERR_NOT_FOUND

每个对象都由 mcpwm_new_*() 工厂函数创建并返回一个不透明句柄,由对应的 mcpwm_del_*() 函数释放,例如 mcpwm_new_timer()mcpwm_del_timer()。先创建父对象,再创建子对象;释放时按相反顺序执行:先删除生成器/比较器,再删除操作器,最后删除定时器。删除定时器前必须禁用它;删除捕获定时器前必须删除其通道。

组时钟分频器由定时器共享,部分芯片的捕获定时器也共享它。按目标分辨率单调顺序(从高到低或从低到高)创建对象,可避免分频冲突。详见 高级主题

术语速查

  • TEZ: Timer equals zero,定时器计数等于零时触发的事件。

  • TEP: Timer equals peak,定时器计数达到峰值时触发的事件。

  • 定时器(Timer): MCPWM 的时间基准,决定频率和 Tick 刻度。

  • 操作器(Operator): 连接定时器与输出逻辑的容器,管理比较器、生成器、制动、死区和载波。

  • 比较器(Comparator): 当计数达到阈值时发出事件,常用于决定边沿位置和占空比。

  • 生成器(Generator): 根据定时器/比较器/故障/同步事件输出 GPIO 电平。

  • 死区(Dead Time): 在半桥上下管切换之间插入的非重叠时间,避免直通。

  • 故障(Fault): 进入保护路径的异常源,可来自 GPIO 或软件。

  • 制动(Brake): 故障触发后的输出安全策略。

  • CBC: Cycle By Cycle,故障有效时制动,清除后在周期边界自动恢复。

  • OST: One Shot,一次制动后保持锁存,需软件显式恢复。

  • 同步(Sync): 在同步边沿把定时器加载到指定计数值和方向,以实现对齐或移相。

  • 捕获(Capture): 对输入边沿打时间戳,用于测脉宽、周期或转速。

应用示例

API 参考

通用类型

Header File

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

  • This header file can be included with:

    #include "driver/mcpwm_types.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
    

Structures

struct mcpwm_timer_event_data_t

MCPWM timer event data.

Public Members

uint32_t count_value

MCPWM timer count value

mcpwm_timer_direction_t direction

MCPWM timer count direction

struct mcpwm_brake_event_data_t

MCPWM brake event data.

struct mcpwm_fault_event_data_t

MCPWM fault event data.

struct mcpwm_compare_event_data_t

MCPWM compare event data.

Public Members

uint32_t compare_ticks

Compare value

mcpwm_timer_direction_t direction

Count direction

struct mcpwm_capture_event_data_t

MCPWM capture event data.

Public Members

uint32_t cap_value

Captured value

mcpwm_capture_edge_t cap_edge

Capture edge

Type Definitions

typedef struct mcpwm_timer_t *mcpwm_timer_handle_t

Type of MCPWM timer handle.

typedef struct mcpwm_oper_t *mcpwm_oper_handle_t

Type of MCPWM operator handle.

typedef struct mcpwm_cmpr_t *mcpwm_cmpr_handle_t

Type of MCPWM comparator handle.

typedef struct mcpwm_gen_t *mcpwm_gen_handle_t

Type of MCPWM generator handle.

typedef struct mcpwm_fault_t *mcpwm_fault_handle_t

Type of MCPWM fault handle.

typedef struct mcpwm_sync_t *mcpwm_sync_handle_t

Type of MCPWM sync handle.

typedef struct mcpwm_cap_timer_t *mcpwm_cap_timer_handle_t

Type of MCPWM capture timer handle.

typedef struct mcpwm_cap_channel_t *mcpwm_cap_channel_handle_t

Type of MCPWM capture channel handle.

typedef bool (*mcpwm_timer_event_cb_t)(mcpwm_timer_handle_t timer, const mcpwm_timer_event_data_t *edata, void *user_ctx)

MCPWM timer event callback function.

Param timer:

[in] MCPWM timer handle

Param edata:

[in] MCPWM timer event data, fed by driver

Param user_ctx:

[in] User data, set in mcpwm_timer_register_event_callbacks()

Return:

Whether a high priority task has been waken up by this function

typedef bool (*mcpwm_brake_event_cb_t)(mcpwm_oper_handle_t oper, const mcpwm_brake_event_data_t *edata, void *user_ctx)

MCPWM operator brake event callback function.

Param oper:

[in] MCPWM operator handle

Param edata:

[in] MCPWM brake event data, fed by driver

Param user_ctx:

[in] User data, set in mcpwm_operator_register_event_callbacks()

Return:

Whether a high priority task has been waken up by this function

typedef bool (*mcpwm_fault_event_cb_t)(mcpwm_fault_handle_t fault, const mcpwm_fault_event_data_t *edata, void *user_ctx)

MCPWM fault event callback function.

Param fault:

MCPWM fault handle

Param edata:

MCPWM fault event data, fed by driver

Param user_ctx:

User data, set in mcpwm_fault_register_event_callbacks()

Return:

whether a task switch is needed after the callback returns

typedef bool (*mcpwm_compare_event_cb_t)(mcpwm_cmpr_handle_t comparator, const mcpwm_compare_event_data_t *edata, void *user_ctx)

MCPWM comparator event callback function.

Param comparator:

MCPWM comparator handle

Param edata:

MCPWM comparator event data, fed by driver

Param user_ctx:

User data, set in mcpwm_comparator_register_event_callbacks()

Return:

Whether a high priority task has been waken up by this function

typedef bool (*mcpwm_capture_event_cb_t)(mcpwm_cap_channel_handle_t cap_channel, const mcpwm_capture_event_data_t *edata, void *user_ctx)

MCPWM capture event callback function.

Param cap_channel:

MCPWM capture channel handle

Param edata:

MCPWM capture event data, fed by driver

Param user_ctx:

User data, set in mcpwm_capture_channel_register_event_callbacks()

Return:

Whether a high priority task has been waken up by this function

Header File

  • components/esp_hal_mcpwm/include/hal/mcpwm_types.h

  • This header file can be included with:

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

    REQUIRES esp_hal_mcpwm
    

    or

    PRIV_REQUIRES esp_hal_mcpwm
    

Type Definitions

typedef soc_periph_mcpwm_timer_clk_src_t mcpwm_timer_clock_source_t

MCPWM timer clock source.

typedef soc_periph_mcpwm_capture_clk_src_t mcpwm_capture_clock_source_t

MCPWM capture clock source.

typedef soc_periph_mcpwm_carrier_clk_src_t mcpwm_carrier_clock_source_t

MCPWM carrier clock source.

Enumerations

enum mcpwm_timer_direction_t

MCPWM timer count direction.

Values:

enumerator MCPWM_TIMER_DIRECTION_UP

Counting direction: Increase

enumerator MCPWM_TIMER_DIRECTION_DOWN

Counting direction: Decrease

enum mcpwm_timer_event_t

MCPWM timer events.

Values:

enumerator MCPWM_TIMER_EVENT_EMPTY

MCPWM timer counts to zero (i.e. counter is empty)

enumerator MCPWM_TIMER_EVENT_FULL

MCPWM timer counts to peak (i.e. counter is full)

enumerator MCPWM_TIMER_EVENT_INVALID

MCPWM timer invalid event

enum mcpwm_timer_count_mode_t

MCPWM timer count modes.

Values:

enumerator MCPWM_TIMER_COUNT_MODE_PAUSE

MCPWM timer paused

enumerator MCPWM_TIMER_COUNT_MODE_UP

MCPWM timer counting up

enumerator MCPWM_TIMER_COUNT_MODE_DOWN

MCPWM timer counting down

enumerator MCPWM_TIMER_COUNT_MODE_UP_DOWN

MCPWM timer counting up and down

enum mcpwm_timer_start_stop_cmd_t

MCPWM timer commands, specify the way to start or stop the timer.

Values:

enumerator MCPWM_TIMER_STOP_EMPTY

MCPWM timer stops when next count reaches zero

enumerator MCPWM_TIMER_STOP_FULL

MCPWM timer stops when next count reaches peak

enumerator MCPWM_TIMER_START_NO_STOP

MCPWM timer starts counting, and don't stop until received stop command

enumerator MCPWM_TIMER_START_STOP_EMPTY

MCPWM timer starts counting and stops when next count reaches zero

enumerator MCPWM_TIMER_START_STOP_FULL

MCPWM timer starts counting and stops when next count reaches peak

enum mcpwm_generator_action_t

MCPWM generator actions.

Values:

enumerator MCPWM_GEN_ACTION_KEEP

Generator action: Keep the same level

enumerator MCPWM_GEN_ACTION_LOW

Generator action: Force to low level

enumerator MCPWM_GEN_ACTION_HIGH

Generator action: Force to high level

enumerator MCPWM_GEN_ACTION_TOGGLE

Generator action: Toggle level

enum mcpwm_operator_brake_mode_t

MCPWM operator brake mode.

Values:

enumerator MCPWM_OPER_BRAKE_MODE_CBC

Brake mode: CBC (cycle by cycle)

enumerator MCPWM_OPER_BRAKE_MODE_OST

Brake mode: OST (one shot)

enumerator MCPWM_OPER_BRAKE_MODE_INVALID

MCPWM operator invalid brake mode

enum mcpwm_capture_edge_t

MCPWM capture edge.

Values:

enumerator MCPWM_CAP_EDGE_POS

Capture on the positive edge

enumerator MCPWM_CAP_EDGE_NEG

Capture on the negative edge

enum mcpwm_timer_etm_event_type_t

MCPWM timer specific events that supported by the ETM module.

Values:

enumerator MCPWM_TIMER_ETM_EVENT_TEZ

The timer reaches zero

enumerator MCPWM_TIMER_ETM_EVENT_TEP

The timer reaches peak

enumerator MCPWM_TIMER_ETM_EVENT_MAX

Maximum number of timer events

enum mcpwm_comparator_etm_event_type_t

MCPWM comparator specific events that supported by the ETM module.

Values:

enumerator MCPWM_CMPR_ETM_EVENT_EQUAL

The count value equals the value of comparator

enumerator MCPWM_CMPR_ETM_EVENT_MAX

Maximum number of comparator events


此文档对您有帮助吗?