ESP32 MCPWM教程:特性、功能框图与PWM控制编程实例

100次阅读
没有评论

 ESP32-S3 的 MCPWM 是多功能 PWM 生成器,含两个单元,支持 12 路独立 PWM 输出。通过定时器、操作器等模块实现高精度控制,具备死区、载波调制功能,可检测故障并制动保护。灵活配置 GPIO 输出,广泛用于电机控制、数字电源等场景,为电力电子应用提供高效解决方案。

ESP32 MCPWM 教程:特性、功能框图与 PWM 控制编程实例

01 MCPWM 简介

ESP32-S3 的 MCPWM(电机控制脉宽调制器)是一种多功能 PWM 生成器,广泛应用于电机控制、数字电源、LED 调光等场景。它通过多个定时器、操作器、比较器和生成器模块,实现高精度、高效率的 PWM 信号输出,并支持故障检测、同步控制和脉宽捕获等高级功能。

ESP-IDF 官方 MCPWM 文档

1. 特性

  • 功能丰富: 支持多种电机控制模式,如电机的向前 / 向后驱动、断电刹车等。
  • 高精度控制: 支持死区控制和外部信号捕获。
  • 多通道输出: 每个 MCPWM 外设可以输出 6 路 PWM 信号,两个 MCPWM 外设合计可以输出 12 路 PWM 信号。
  • 高级功能: 支持载波调制、故障检测和制动控制。
  • 灵活配置: 每个 PWM 操作器可以使用任一 PWM 定时器的定时参考,不同 PWM 操作器可使用相同或不同 PWM 定时器的值来生成 PWM 信号。

2. 数量

ESP32-S3 包含两个 MCPWM 单元,每个单元有三对 PWM 输出。每个 MCPWM 单元包含一个时钟分频器、三个 PWM 定时器、三个 PWM 操作器和一个捕获模块。因此,两个 MCPWM 单元合计可以提供 12 个占空比独立可调的 PWM 输出。

3.IO 口要求

MCPWM 模块包含两个子模块(MCPWM0 和 MCPWM1),每个子模块可以配置多个操作器(OP0、OP1、OP2),每个操作器可以输出到不同的 GPIO 引脚。每个操作器支持两种输出通道(A 和 B),并且每个通道可以映射到多个 GPIO 引脚。例如,MCPWM0 模块的 OP0 操作器的 A 通道可以输出到 GPIO0、GPIO10 或 GPIO16。所有可用 IO 口如下表所示:

MCPWM 模块 操作器 输出通道 可选 GPIO(示例)
MCPWM0 OP0 A GPIO0,GPIO10,GPIO16
OP0 B GPIO1,GPIO11,GPIO17
OP1 A GPIO2,GPIO12,GPIO18
OP1 B GPIO3,GPIO13,GPIO19
OP2 A GPIO4,GPIO14,GPIO20
OP2 B GPIO5,GPIO15,GPIO21
MCPWM1 OP0 A GPIO6,GPIO25,GPIO33
OP0 B GPIO7,GPIO26,GPIO34
OP1 A GPIO8,GPIO27,GPIO35
OP1 B GPIO9,GPIO28,GPIO36
OP2 A GPIO22,GPIO29,GPIO37
OP2 B GPIO23,GPIO30,GPIO38

02 功能框图

ESP32 MCPWM 教程:特性、功能框图与 PWM 控制编程实例

Esp32-s3 的 MCPWM 模块中,生成带死区和载波调制的 PWM 信号的工作流程如下:

①时钟预分频器(ClockPrescaler)将输入的 CLK_160M 时钟信号进行分频,为定时器提供适当的时钟频率。接着,三个定时器(Timer0、Timer1、Timer2)根据预分频后的时钟信号进行计数,生成 PWM 信号的基础周期。

②操作器(Operator0、Operator1、Operator2)根据定时器的输出和配置参数生成 PWM 信号。操作器可以配置死区时间,以在两个 PWM 信号之间插入一个固定的时间间隔,防止两个信号同时导通。

③操作器还可以通过载波调制技术,将 PWM 信号与高频载波信号结合,生成高频 PWM 信号,以提高电机控制的精度和效率。最后,生成的 PWM 信号通过 GPIO 矩阵输出到相应的 GPIO 引脚,驱动外部设备。

④故障检测(FaultDetect)模块监控 MCPWM 的运行状态,捕获(Capture)模块用于捕获外部信号的上升沿或下降沿,以实现更复杂的控制逻辑。在下图的无刷直流电机 (BLDC) 方案中,可以使用捕获子模块来确认来自霍尔传感器的转子位置。

ESP32 MCPWM 教程:特性、功能框图与 PWM 控制编程实例

死区:

在电机控制中,死区是功率电路(如 H 桥、三相逆变器)设计中为防止上下桥臂功率器件同时导通而设置的安全时间间隔。当控制信号从一个桥臂切换到另一个桥臂时,由于器件的开关延迟特性,若没有死区,可能出现短暂的上下管同时导通状态,导致电源短路。死区通过在原始控制信号的上升沿和下降沿分别插入延迟时间(正边沿延迟和负边沿延迟),确保上管完全关断后下管才导通,或下管完全关断后上管才导通,从而避免桥臂短路风险,保护功率器件和电路系统的安全稳定运行。

ESP32 MCPWM 教程:特性、功能框图与 PWM 控制编程实例

MCPWM 模块有以下外设:

时钟预分器频(ClockPrescaler):

时钟预分频器用于将输入的时钟频率(CLK_160M)降低,以适应 PWM 生成的需求。它通过分频系数来调整时钟频率,为后续的定时器提供合适的时钟信号。

定时器(Timer):

定时器是 MCPWM 的核心部分,用于生成定时信号。每个定时器可以独立配置,包括周期、比较值等。

操作器(Operator):

操作器接收来自定时器的定时信号,并根据配置生成 PWM 信号。每个操作器可以配置为不同的 PWM 模式,如互补、桥接等。

故障检测(FaultDetect):

故障检测模块用于监控 MCPWM 的运行状态,检测可能的故障情况,如过流、过压等。

捕获(Capture):

捕获模块用于捕获外部信号的上升沿或下降沿,通常用于测量外部信号的周期或频率。

GPIO 矩阵:

GPIO 矩阵用于将 MCPWM 生成的 PWM 信号输出到指定的 GPIO 引脚。

03 MCPWM 各种模式使用方法

1. 经典 PWM 波形生成

编程流程

创建定时器组,配置定时器的时钟源、分辨率、周期、计数模式等参数。

创建操作器,并将其与定时器绑定。

创建比较器,设置比较器的比较值。

创建生成器,配置生成器的 GPIO 引脚。

设置生成器在定时器事件和比较器事件上的动作,以生成所需的 PWM 波形。

#include"driver/mcpwm.h"
#include"esp_log.h"
#defineMCPWM_GROUP_ID0
#defineMCPWM_TIMER_ID0
#defineMCPWM_GEN_A_GPIO21
#defineMCPWM_GEN_B_GPIO22
voidapp_main(void){
// 创建定时器
mcpwm_timer_handle_ttimer=NULL;
mcpwm_timer_config_ttimer_config={
.group_id=MCPWM_GROUP_ID,
.clk_src=MCPWM_TIMER_CLK_SRC_DEFAULT,
.resolution_hz=1000000,//1MHz
.period_ticks=1000,//1ms 周期
.count_mode=MCPWM_TIMER_COUNT_MODE_UP,
};
ESP_ERROR_CHECK(mcpwm_new_timer(&timer_config,&timer));
// 创建操作器
mcpwm_oper_handle_toper=NULL;
mcpwm_operator_config_toper_config={.group_id=MCPWM_GROUP_ID,};
ESP_ERROR_CHECK(mcpwm_new_operator(&oper_config,&oper));
// 绑定定时器和操作器
ESP_ERROR_CHECK(mcpwm_operator_connect_timer(oper,timer));
// 创建比较器 mcpwm_cmpr_handle_tcmpr_a=NULL;
mcpwm_comparator_config_tcmpr_config={.flags.update_cmp_on_tez=true,};
ESP_ERROR_CHECK(mcpwm_new_comparator(oper,&cmpr_config,&cmpr_a));
ESP_ERROR_CHECK(mcpwm_comparator_set_compare_value(cmpr_a,500));//50% 占空比
// 创建生成器
mcpwm_gen_handle_tgen_a=NULL;
mcpwm_generator_config_tgen_config={.gen_gpio_num=MCPWM_GEN_A_GPIO,};
ESP_ERROR_CHECK(mcpwm_new_generator(oper,&gen_config,&gen_a));
// 设置生成器动作 ESP_ERROR_CHECK(mcpwm_generator_set_action_on_timer_event(gen_a,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(gen_a,MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP,cmpr_a,MCPWM_GEN_ACTION_LOW)));
// 启动定时器
ESP_ERROR_CHECK(mcpwm_timer_enable(timer));
ESP_ERROR_CHECK(mcpwm_timer_start_stop(timer,MCPWM_TIMER_START_NO_STOP));
}

2. 死区生成

编程流程:

创建死区模块,并将其与操作器绑定。

配置死区时间,包括上升沿死区时间和下降沿死区时间。

设置生成器在定时器事件和比较器事件上的动作,以生成带有死区的 PWM 波形。

#include"driver/mcpwm.h"
#include"esp_log.h"
#defineMCPWM_GROUP_ID0
#defineMCPWM_TIMER_ID0
#defineMCPWM_GEN_A_GPIO21
#defineMCPWM_GEN_B_GPIO22
voidapp_main(void){
// 创建定时器
mcpwm_timer_handle_ttimer=NULL;
mcpwm_timer_config_ttimer_config={
.group_id=MCPWM_GROUP_ID,
.clk_src=MCPWM_TIMER_CLK_SRC_DEFAULT,
.resolution_hz=1000000,//1MHz
.period_ticks=1000,//1ms 周期
.count_mode=MCPWM_TIMER_COUNT_MODE_UP,
};
ESP_ERROR_CHECK(mcpwm_new_timer(&timer_config,&timer));
// 创建操作器
mcpwm_oper_handle_toper=NULL;
mcpwm_operator_config_toper_config={.group_id=MCPWM_GROUP_ID,};
ESP_ERROR_CHECK(mcpwm_new_operator(&oper_config,&oper));
// 绑定定时器和操作器
ESP_ERROR_CHECK(mcpwm_operator_connect_timer(oper,timer));
// 创建死区模块
mcpwm_deadtime_handle_tdeadtime=NULL;
mcpwm_deadtime_config_tdeadtime_config={
.update_on_tez=true,
.update_on_tep=true,
.update_on_sync=true,
.deadtime_ticks=10,//10us 死区时间
};
ESP_ERROR_CHECK(mcpwm_new_deadtime(oper,&deadtime_config,&deadtime));
// 创建比较器
mcpwm_cmpr_handle_tcmpr_a=NULL;
mcpwm_comparator_config_tcmpr_config={.flags.update_cmp_on_tez=true,};
ESP_ERROR_CHECK(mcpwm_new_comparator(oper,&cmpr_config,&cmpr_a));
ESP_ERROR_CHECK(mcpwm_comparator_set_compare_value(cmpr_a,500));//50% 占空比
// 创建生成器
mcpwm_gen_handle_tgen_a=NULL;
mcpwm_generator_config_tgen_config={.gen_gpio_num=MCPWM_GEN_A_GPIO,};
ESP_ERROR_CHECK(mcpwm_new_generator(oper,&gen_config,&gen_a));
// 设置生成器动作 ESP_ERROR_CHECK(mcpwm_generator_set_action_on_timer_event(gen_a,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(gen_a,MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP,cmpr_a,MCPWM_GEN_ACTION_LOW)));
// 启动定时器 ESP_ERROR_CHECK(mcpwm_timer_enable(timer));
ESP_ERROR_CHECK(mcpwm_timer_start_stop(timer,MCPWM_TIMER_START_NO_STOP));
}

3. 载波调制

编程流程:

创建载波模块,并将其与操作器绑定。

配置载波频率、占空比等参数。

设置生成器在定时器事件和比较器事件上的动作,以生成载波调制的 PWM 波形。

#include"driver/mcpwm.h"
#include"esp_log.h"
#defineMCPWM_GROUP_ID0
#defineMCPWM_TIMER_ID0
#defineMCPWM_GEN_A_GPIO21
#defineMCPWM_GEN_B_GPIO22
voidapp_main(void){
// 创建定时器
mcpwm_timer_handle_ttimer=NULL;
mcpwm_timer_config_ttimer_config={
.group_id=MCPWM_GROUP_ID,
.clk_src=MCPWM_TIMER_CLK_SRC_DEFAULT,
.resolution_hz=1000000,//1MHz
.period_ticks=1000,//1ms 周期
.count_mode=MCPWM_TIMER_COUNT_MODE_UP,
};
ESP_ERROR_CHECK(mcpwm_new_timer(&timer_config,&timer));
// 创建操作器
mcpwm_oper_handle_toper=NULL;
mcpwm_operator_config_toper_config={.group_id=MCPWM_GROUP_ID,};
ESP_ERROR_CHECK(mcpwm_new_operator(&oper_config,&oper));
// 绑定定时器和操作器
ESP_ERROR_CHECK(mcpwm_operator_connect_timer(oper,timer));
// 创建载波模块
mcpwm_carrier_handle_tcarrier=NULL;
mcpwm_carrier_config_tcarrier_config={
.carrier_freq_hz=20000,//20kHz 载波频率
.duty_cycle=50,//50% 载波占空比
.update_on_tez=true,
.update_on_tep=true,
.update_on_sync=true,
};
ESP_ERROR_CHECK(mcpwm_new_carrier(oper,&carrier_config,&carrier));
// 创建比较器
mcpwm_cmpr_handle_tcmpr_a=NULL;
mcpwm_comparator_config_tcmpr_config={.flags.update_cmp_on_tez=true,};
ESP_ERROR_CHECK(mcpwm_new_comparator(oper,&cmpr_config,&cmpr_a));
ESP_ERROR_CHECK(mcpwm_comparator_set_compare_value(cmpr_a,500));//50% 占空比
// 创建生成器
mcpwm_gen_handle_tgen_a=NULL;
mcpwm_generator_config_tgen_config={.gen_gpio_num=MCPWM_GEN_A_GPIO,};
ESP_ERROR_CHECK(mcpwm_new_generator(oper,&gen_config,&gen_a));
// 设置生成器动作 ESP_ERROR_CHECK(mcpwm_generator_set_action_on_timer_event(gen_a,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(gen_a,MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP,cmpr_a,MCPWM_GEN_ACTION_LOW)));
// 启动定时器
ESP_ERROR_CHECK(mcpwm_timer_enable(timer));
ESP_ERROR_CHECK(mcpwm_timer_start_stop(timer,MCPWM_TIMER_START_NO_STOP));
}

4. 故障检测

编程流程:

创建故障检测模块,并将其与操作器绑定。

配置故障检测的 GPIO 引脚和故障信号极性。

设置生成器在故障事件上的动作,以实现故障保护。

#include"driver/mcpwm.h"
#include"esp_log.h"
#defineMCPWM_GROUP_ID0
#defineMCPWM_TIMER_ID0
#defineMCPWM_GEN_A_GPIO21
#defineMCPWM_GEN_B_GPIO22
#defineMCPWM_FAULT_GPIO23
voidapp_main(void){
// 创建定时器
mcpwm_timer_handle_ttimer=NULL;
mcpwm_timer_config_ttimer_config={
.group_id=MCPWM_GROUP_ID,
.clk_src=MCPWM_TIMER_CLK_SRC_DEFAULT,
.resolution_hz=1000000,//1MHz
.period_ticks=1000,//1ms 周期
.count_mode=MCPWM_TIMER_COUNT_MODE_UP,
};
ESP_ERROR_CHECK(mcpwm_new_timer(&timer_config,&timer));
// 创建操作器
mcpwm_oper_handle_toper=NULL;
mcpwm_operator_config_toper_config={.group_id=MCPWM_GROUP_ID,};
ESP_ERROR_CHECK(mcpwm_new_operator(&oper_config,&oper));
// 绑定定时器和操作器
ESP_ERROR_CHECK(mcpwm_operator_connect_timer(oper,timer));
// 创建故障检测模块
mcpwm_fault_handle_tfault=NULL;
mcpwm_fault_config_tfault_config={
.fault_gpio_num=MCPWM_FAULT_GPIO,
.fault_signal_polarity=MCPWM_FAULT_SIGNAL_POLARITY_LOW,
.fault_debounce_ticks=10,//10us 消抖时间
};
ESP_ERROR_CHECK(mcpwm_new_fault(oper,&fault_config,&fault));
// 创建比较器
mcpwm_cmpr_handle_tcmpr_a=NULL;
mcpwm_comparator_config_tcmpr_config={.flags.update_cmp_on_tez=true,};
ESP_ERROR_CHECK(mcpwm_new_comparator(oper,&cmpr_config,&cmpr_a));
ESP_ERROR_CHECK(mcpwm_comparator_set_compare_value(cmpr_a,500));//50% 占空比
// 创建生成器
mcpwm_gen_handle_tgen_a=NULL;
mcpwm_generator_config_tgen_config={.gen_gpio_num=MCPWM_GEN_A_GPIO,};
ESP_ERROR_CHECK(mcpwm_new_generator(oper,&gen_config,&gen_a));
// 设置生成器动作 ESP_ERROR_CHECK(mcpwm_generator_set_action_on_timer_event(gen_a,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(gen_a,MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP,cmpr_a,MCPWM_GEN_ACTION_LOW)));
ESP_ERROR_CHECK(mcpwm_generator_set_action_on_fault_event(gen_a,MCPWM_GEN_FAULT_EVENT_ACTION(fault,MCPWM_GEN_ACTION_LOW)));
// 启动定时器
ESP_ERROR_CHECK(mcpwm_timer_enable(timer));
ESP_ERROR_CHECK(mcpwm_timer_start_stop(timer,MCPWM_TIMER_START_NO_STOP));
}

5. 同步模块

编程流程:

创建同步模块,并将其与操作器绑定。

配置同步信号的来源和同步事件的触发条件。

设置生成器在同步事件上的动作,以实现多 PWM 信号的同步。

#include"driver/mcpwm.h"
#include"esp_log.h"
#defineMCPWM_GROUP_ID0
#defineMCPWM_TIMER_ID0
#defineMCPWM_GEN_A_GPIO21
#defineMCPWM_GEN_B_GPIO22
voidapp_main(void){
// 创建定时器
mcpwm_timer_handle_ttimer=NULL;
mcpwm_timer_config_ttimer_config={
.group_id=MCPWM_GROUP_ID,
.clk_src=MCPWM_TIMER_CLK_SRC_DEFAULT,
.resolution_hz=1000000,//1MHz
.period_ticks=1000,//1ms 周期
.count_mode=MCPWM_TIMER_COUNT_MODE_UP,
};
ESP_ERROR_CHECK(mcpwm_new_timer(&timer_config,&timer));
// 创建操作器
mcpwm_oper_handle_toper=NULL;
mcpwm_operator_config_toper_config={.group_id=MCPWM_GROUP_ID,};
ESP_ERROR_CHECK(mcpwm_new_operator(&oper_config,&oper));
// 绑定定时器和操作器
ESP_ERROR_CHECK(mcpwm_operator_connect_timer(oper,timer));
// 创建同步模块
mcpwm_sync_handle_tsync=NULL;
mcpwm_sync_config_tsync_config={.sync_src=MCPWM_SYNC_SRC_TEZ,// 同步信号来源为定时器溢出事件};
ESP_ERROR_CHECK(mcpwm_new_sync(oper,&sync_config,&sync));
// 创建比较器
mcpwm_cmpr_handle_tcmpr_a=NULL;
mcpwm_comparator_config_tcmpr_config={.flags.update_cmp_on_tez=true,};
ESP_ERROR_CHECK(mcpwm_new_comparator(oper,&cmpr_config,&cmpr_a));
ESP_ERROR_CHECK(mcpwm_comparator_set_compare_value(cmpr_a,500));//50% 占空比
// 创建生成器
mcpwm_gen_handle_tgen_a=NULL;
mcpwm_generator_config_tgen_config={.gen_gpio_num=MCPWM_GEN_A_GPIO,};
ESP_ERROR_CHECK(mcpwm_new_generator(oper,&gen_config,&gen_a));
// 设置生成器动作 ESP_ERROR_CHECK(mcpwm_generator_set_action_on_timer_event(gen_a,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(gen_a,MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP,cmpr_a,MCPWM_GEN_ACTION_LOW)));
ESP_ERROR_CHECK(mcpwm_generator_set_action_on_sync_event(gen_a,MCPWM_GEN_SYNC_EVENT_ACTION(sync,MCPWM_GEN_ACTION_HIGH)));
// 启动定时器
ESP_ERROR_CHECK(mcpwm_timer_enable(timer));
ESP_ERROR_CHECK(mcpwm_timer_start_stop(timer,MCPWM_TIMER_START_NO_STOP));
}

6. 制动控制

编程流程:

配置生成器在故障事件上的制动动作,例如立即关闭或逐周期调节。

设置故障检测模块的故障信号来源和极性。

启动定时器并运行 PWM 信号,故障发生时生成器将执行制动动作。

#include"driver/mcpwm.h"
#include"esp_log.h"
#defineMCPWM_GROUP_ID0
#defineMCPWM_TIMER_ID0
#defineMCPWM_GEN_A_GPIO21
#defineMCPWM_GEN_B_GPIO22
#defineMCPWM_FAULT_GPIO23
voidapp_main(void){
// 创建定时器
mcpwm_timer_handle_ttimer=NULL;
mcpwm_timer_config_ttimer_config={
.group_id=MCPWM_GROUP_ID,
.clk_src=MCPWM_TIMER_CLK_SRC_DEFAULT,
.resolution_hz=1000000,//1MHz
.period_ticks=1000,//1ms 周期
.count_mode=MCPWM_TIMER_COUNT_MODE_UP,
};
ESP_ERROR_CHECK(mcpwm_new_timer(&timer_config,&timer));
// 创建操作器
mcpwm_oper_handle_toper=NULL;
mcpwm_operator_config_toper_config={.group_id=MCPWM_GROUP_ID,};
ESP_ERROR_CHECK(mcpwm_new_operator(&oper_config,&oper));
// 绑定定时器和操作器
ESP_ERROR_CHECK(mcpwm_operator_connect_timer(oper,timer));
// 创建故障检测模块
mcpwm_fault_handle_tfault=NULL;
mcpwm_fault_config_tfault_config={
.fault_gpio_num=MCPWM_FAULT_GPIO,
.fault_signal_polarity=MCPWM_FAULT_SIGNAL_POLARITY_LOW,
.fault_debounce_ticks=10,//10us 消抖时间
};
ESP_ERROR_CHECK(mcpwm_new_fault(oper,&fault_config,&fault));
// 创建比较器
mcpwm_cmpr_handle_tcmpr_a=NULL;
mcpwm_comparator_config_tcmpr_config={.flags.update_cmp_on_tez=true,};
ESP_ERROR_CHECK(mcpwm_new_comparator(oper,&cmpr_config,&cmpr_a));
ESP_ERROR_CHECK(mcpwm_comparator_set_compare_value(cmpr_a,500));//50% 占空比
// 创建生成器
mcpwm_gen_handle_tgen_a=NULL;
mcpwm_generator_config_tgen_config={.gen_gpio_num=MCPWM_GEN_A_GPIO,};
ESP_ERROR_CHECK(mcpwm_new_generator(oper,&gen_config,&gen_a));
// 设置生成器动作 ESP_ERROR_CHECK(mcpwm_generator_set_action_on_timer_event(gen_a,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(gen_a,MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP,cmpr_a,MCPWM_GEN_ACTION_LOW)));
ESP_ERROR_CHECK(mcpwm_generator_set_action_on_fault_event(gen_a,MCPWM_GEN_FAULT_EVENT_ACTION(fault,MCPWM_GEN_ACTION_LOW)));
// 配置制动控制 ESP_ERROR_CHECK(mcpwm_generator_set_brake_action(gen_a,MCPWM_GEN_BRAKE_ACTION_LOW));
// 启动定时器 ESP_ERROR_CHECK(mcpwm_timer_enable(timer));
ESP_ERROR_CHECK(mcpwm_timer_start_stop(timer,MCPWM_TIMER_START_NO_STOP));
}

7. 捕获模块

编程流程:

创建捕获模块,并配置捕获通道的 GPIO 引脚。

配置捕获事件的触发条件,例如上升沿或下降沿。

启用捕获中断,并在中断处理函数中读取捕获到的脉宽值。

#include"driver/mcpwm.h"
#include"esp_log.h"
#include"driver/gpio.h"
#defineMCPWM_GROUP_ID0
#defineMCPWM_CAPTURE_GPIO21
staticvoidIRAM_ATTRmcpwm_capture_intr_handler(void*arg){mcpwm_capture_handle_tcapture=(mcpwm_capture_handle_t)arg;
uint32_tcap_val=0;
mcpwm_capture_get_input_signal_value(capture,&cap_val);
ESP_LOGI("MCPWM","Capturedvalue:%u",cap_val);
}
voidapp_main(void){
// 创建捕获模块
mcpwm_capture_handle_tcapture=NULL;
mcpwm_capture_config_tcapture_config={
.group_id=MCPWM_GROUP_ID,
.capture_signal=MCPWM_CAPTURE_SIGNAL_A,
.input_signal=MCPWM_CAPTURE_INPUT_SIG_GPIO,
.input_gpio_num=MCPWM_CAPTURE_GPIO,
.capture_edge=MCPWM_CAPTURE_EDGE_RISING,
};
ESP_ERROR_CHECK(mcpwm_new_capture(&capture_config,&capture));
// 启用捕获中断
mcpwm_capture_enable_intr(capture);
mcpwm_capture_register_intr_handler(capture,mcpwm_capture_intr_handler,capture);
// 启动捕获模块
ESP_ERROR_CHECK(mcpwm_capture_enable(capture));
}

04 MCPWM 常用的 API 函数

mcpwm_new_timer()

用于创建并初始化 MCPWM 定时器句柄,作为所有 MCPWM 功能的时间基准。关键参数包括 MCPWM 组 ID(group_id)、时钟源(clk_src)、定时器分辨率(resolution_hz)、计数模式(count_mode)和周期计数值(period_ticks)。它是生成 PWM 信号的基础,为后续子模块提供统一的周期时基,适用于所有需要 PWM 输出的场景。

mcpwm_new_operator()

用于创建 MCPWM 操作器句柄,作为协调定时器、比较器、生成器等子模块的逻辑控制中枢。参数需指定组 ID(group_id)、定时器归零是否更新生成器动作(update_gen_action_on_tez)及中断优先级(intr_priority)。操作器需与定时器绑定后才能工作,是实现 PWM 波形生成的核心控制单元。

mcpwm_operator_connect_timer()

用于将操作器与定时器绑定,确保操作器能以定时器为时间基准调度子模块。参数为操作器句柄(oper)和定时器句柄(timer),且两者必须属于同一组。这是操作器正常工作的必要步骤,否则无法生成 PWM 信号。

mcpwm_new_comparator()

用于创建比较器句柄,用于设置 PWM 占空比的翻转阈值。需传入所属操作器句柄(oper)及比较值更新时机配置(如 update_cmp_on_tez 表示定时器归零时更新)。比较器通过对比定时器计数值与阈值触发电平翻转,是定义 PWM 占空比的关键模块。

mcpwm_new_generator()

用于创建生成器句柄,负责将 PWM 信号输出到指定 GPIO 引脚。参数包括所属操作器句柄(oper)、输出 GPIO 号(gen_gpio_num)、信号是否反相(invert_pwm)及上下拉配置(pull_up/pull_down)。生成器接收定时器和比较器事件并执行电平动作,是 PWM 信号的最终输出单元。

mcpwm_del_timer()

用于释放定时器资源,参数为定时器句柄。需按“生成器→比较器→操作器→定时器”的逆序释放,避免资源冲突,确保系统资源正确回收。

mcpwm_del_operator()

用于释放操作器资源,参数为操作器句柄。作为资源清理步骤之一,需在释放定时器前执行,防止资源占用导致的冲突。

mcpwm_del_comparator()

用于释放比较器资源,参数为比较器句柄。需在释放操作器前执行,确保比较器占用的硬件资源被正确回收。

mcpwm_del_generator()

用于释放生成器资源,参数为生成器句柄。作为资源清理的第一步,需优先释放,避免影响其他模块的资源回收流程。

mcpwm_comparator_set_compare_value()

设置比较器的阈值,动态调整 PWM 占空比。参数为比较器句柄(cmpr)和阈值(value),且阈值需≤定时器周期值。占空比计算公式为“阈值 / 周期值”,适用于电机调速等需要实时调整占空比的场景。

mcpwm_generator_set_action_on_timer_event()

配置生成器在定时器事件(如计数归零、达峰值)时的电平动作。参数包括生成器句柄(gen)及事件 – 动作配置(含计数方向、事件类型、动作如置高 / 置低 / 翻转)。例如可设置定时器归零时输出置高,定义 PWM 周期起点的电平状态。

mcpwm_generator_set_action_on_compare_event()

定义生成器在比较器事件(计数值 = 阈值)时的动作。需传入生成器句柄(gen)及包含计数方向、比较器句柄、动作的配置。通过该函数可设置比较值匹配时电平翻转,从而定义 PWM 占空比的结束点,实现特定占空比的 PWM 波形。

mcpwm_generator_set_dead_time()

为 PWM 信号配置死区时间,防止 H 桥、三相逆变器等功率电路中同一桥臂上下管同时导通。参数包括原始生成器(in_gen)、输出生成器(out_gen)、上升沿延迟(posedge_delay_ticks)、下降沿延迟(negedge_delay_ticks)及输出是否反相(invert_output)。适用于需要互补 PWM 信号的功率控制场景。

mcpwm_timer_enable()

启用定时器,使其开始计数并为子模块提供时基。参数为定时器句柄,启用后定时器按配置模式运行,触发后续比较器、生成器等模块的事件响应,是激活 MCPWM 功能的关键步骤。

mcpwm_timer_start_stop()

控制定时器计数的启动或停止,参数为定时器句柄和命令(MCPWM_TIMER_START 启动,MCPWM_TIMER_STOP 停止)。可用于临时暂停 PWM 输出,如电机急停等需要快速启停控制的场景。

mcpwm_new_gpio_fault()

创建 GPIO 故障检测句柄,监测外部故障信号(如过流、过压)。参数包括故障 GPIO 号(gpio_num)和有效电平(active_level)。通过检测指定 GPIO 的有效电平触发保护动作,适用于需要硬件故障保护的系统。

mcpwm_operator_set_brake_on_fault()

配置操作器在故障发生时的制动模式,参数为操作器句柄(oper)、故障句柄及制动模式(CBC 逐周期保护或 OST 一次性停机)。CBC 模式在故障消失后自动恢复,OST 需手动恢复,用于故障时保护系统安全。

mcpwm_timer_register_event_callbacks()

注册定时器事件回调函数,响应周期结束、计数归零等事件。参数为定时器句柄、回调结构体(含 on_full/on_empty 等回调)及用户数据(user_data)。可用于周期结束时更新参数(如动态调占空比)或记录运行状态,增强系统的实时控制能力。

FAQ

1、ESP32 的 MCPWM 模块支持多少路 PWM 输出?

ESP32 包含两个 MCPWM 单元,每个单元有三对 PWM 输出,共 12 路独立 PWM 信号,可用于电机控制和电力电子应用。

2、MCPWM 的死区控制有什么作用?

死区用于防止功率器件上下桥臂同时导通,避免电源短路,确保电机控制电路安全稳定运行。

3、如何在 ESP32 上实现 PWM 载波调制?

通过 MCPWM 的载波模块配置载波频率和占空比,并与操作器绑定,即可生成载波调制的 PWM 波形,提高电机控制的精度。

4、MCPWM 的 GPIO 引脚可以自由映射吗?

是的,ESP32 的 MCPWM 输入输出引脚支持 GPIO 矩阵配置,用户可以将 PWM 输出、捕获输入、故障信号等映射到任意可用的 GPIO 引脚上。

5、MCPWM 的故障检测和制动功能怎么用?

MCPWM 支持通过 GPIO 输入故障信号,在检测到过流或过压时自动关闭 PWM 输出,实现紧急制动,保障电机与电路的安全。

6、ESP32 MCPWM 适合哪些应用场景?

MCPWM 常用于无刷直流电机(BLDC)控制、步进电机驱动、逆变器、开关电源以及电力电子控制等需要高精度 PWM 的场景。

7、如何通过 ESP-IDF 配置 MCPWM 输出 PWM 信号?

开发者可以使用 ESP-IDF 的 mcpwm_new_timer()、mcpwm_new_operator()、mcpwm_new_comparator() 等 API 创建定时器、操作器和比较器,并绑定输出通道,即可生成所需的 PWM 信号。

正文完
 0
Pa2sw0rd
版权声明:本站原创文章,由 Pa2sw0rd 于2025-09-07发表,共计17595字。
转载说明:Unless otherwise specified, all articles are published by cc-4.0 protocol. Please indicate the source of reprint.
评论(没有评论)