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

191 阅读6分钟

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

编辑

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口如下表所示:

image.png

02 功能框图

编辑

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) 方案中,可以使用捕获子模块来确认来自霍尔传感器的转子位置。

编辑

死区:

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

编辑

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.死区生成

编程流程:

继续阅读全文:ESP32 MCPWM教程:特性、功能框图与PWM控制编程实例