ESP32-S3 MCPWM Tutorial: Features, Block Diagram, and PWM Control Examples

101 Views
No Comments

The ESP32  -S3’s MCPWM is a versatile PWM generator consisting of two units, supporting 12 independent PWM outputs. It achieves high-precision control through modules such as timers and operators, and features dead-zone and carrier modulation, enabling fault detection and brake protection. Flexible GPIO output configuration makes it widely applicable in scenarios such as motor control and digital power supplies, providing an efficient solution for power electronics applications .

ESP32-S3 MCPWM Tutorial: Features, Block Diagram, and PWM Control Examples

01 Introduction to MCPWM

The ESP32-S3’s MCPWM (Motor Control Pulse Width Modulator) is a versatile PWM generator widely used in applications such as motor control, digital power supplies, and LED dimming. Through multiple timer, operator, comparator, and generator modules, it achieves high-precision and high-efficiency PWM signal output and supports advanced features such as fault detection, synchronization control, and pulse width capture.

ESP-IDF Official MCPWM Documentation

1. Features

  • Rich functions: Supports multiple motor control modes, such as forward/reverse drive, power-off braking, etc.
  • High-precision control: supports dead-band control and external signal capture.
  • Multi-channel output: Each MCPWM peripheral can output 6 PWM signals, and two MCPWM peripherals can output a total of 12 PWM signals.
  • Advanced functions: Supports carrier modulation, fault detection and brake control.
  • Flexible configuration: Each PWM operator can use the timing reference of any PWM timer, and different PWM operators can use the same or different PWM timer values ​​to generate PWM signals.

2. Quantity

The ESP32-S3 includes two MCPWM units, each with three pairs of PWM outputs. Each MCPWM unit includes a clock divider, three PWM timers, three PWM operators, and a capture module. Therefore, the two MCPWM units together provide 12 PWM outputs with independently adjustable duty cycles.

3.IO port requirements

The MCPWM module contains two submodules (MCPWM0 and MCPWM1). Each submodule can be configured with multiple operators (OP0, OP1, OP2), each of which can output to different GPIO pins. Each operator supports two output channels (A and B), and each channel can be mapped to multiple GPIO pins. For example, channel A of the OP0 operator of the MCPWM0 module can output to GPIO0, GPIO10, or GPIO16. All available IO ports are shown in the following table:

MCPWM module Operator Output Channel Optional GPIO (example)
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 Functional Block Diagram

ESP32-S3 MCPWM Tutorial: Features, Block Diagram, and PWM Control Examples

In the MCPWM module of Esp32-s3, the workflow for generating PWM signals with dead zone and carrier modulation is as follows:

① The clock prescaler divides the input CLK_160M clock signal to provide the appropriate clock frequency for the timer. Then, the three timers (Timer0, Timer1, Timer2) count according to the prescaled clock signal to generate the basic period of the PWM signal.

② The operators (Operator0, Operator1, Operator2) generate PWM signals based on the timer output and configuration parameters. The operators can configure dead time to insert a fixed time interval between two PWM signals to prevent the two signals from being on at the same time.

③ The operator can also use carrier modulation technology to combine the PWM signal with a high-frequency carrier signal to generate a high-frequency PWM signal to improve the accuracy and efficiency of motor control. Finally, the generated PWM signal is output to the corresponding GPIO pin through the GPIO matrix to drive external devices.

④ The Fault Detect module monitors the MCPWM’s operating status, while the Capture module captures the rising or falling edges of external signals to implement more complex control logic. In the brushless DC motor (BLDC) solution shown below, the Capture module can be used to confirm the rotor position from the Hall effect sensor.

ESP32-S3 MCPWM Tutorial: Features, Block Diagram, and PWM Control Examples

Dead Zone:

In motor control, a dead zone is a safety interval designed into power circuits (such as H-bridges and three-phase inverters) to prevent simultaneous conduction of upper and lower power devices. When the control signal switches from one bridge arm to the other, due to the switching delay characteristics of the devices, without a dead zone, both upper and lower devices may be on simultaneously for a brief period, resulting in a power short. The dead zone inserts delays (positive and negative edge delays) between the rising and falling edges of the original control signal to ensure that the upper device is fully turned off before the lower device is turned on, or vice versa. This prevents the risk of bridge arm short circuits and protects the safe and stable operation of the power devices and circuit system.

ESP32-S3 MCPWM Tutorial: Features, Block Diagram, and PWM Control Examples

The MCPWM module has the following peripherals:

Clock Prescaler:

The clock prescaler is used to reduce the input clock frequency (CLK_160M) to meet the requirements of PWM generation. It adjusts the clock frequency by the frequency division coefficient to provide a suitable clock signal for the subsequent timer.

Timer:

The timer is the core part of MCPWM, used to generate timing signals. Each timer can be independently configured, including period, comparison value, etc.

Operator:

The operator receives the timing signal from the timer and generates a PWM signal according to the configuration. Each operator can be configured to different PWM modes, such as complementary, bridge, etc.

Fault Detection:

The fault detection module is used to monitor the operating status of the MCPWM and detect possible fault conditions such as overcurrent, overvoltage, etc.

Capture:

The capture module is used to capture the rising edge or falling edge of an external signal and is usually used to measure the period or frequency of the external signal.

GPIO Matrix:

The GPIO matrix is ​​used to output the PWM signals generated by MCPWM to the specified GPIO pins.

03 How to use various MCPWM modes

1. Classic PWM waveform generation

Programming process :

Create a timer group and configure the timer’s clock source, resolution, period, counting mode and other parameters.

Create an operator and bind it to the timer.

Create a comparator and set the comparison value of the comparator.

Create a generator and configure the generator’s GPIO pins.

Set the generator’s actions on timer events and comparator events to generate the desired PWM waveform.

# include "driver/mcpwm.h"# include "esp_log.h"#defineMCPWM_GROUP_ID0#defineMCPWM_TIMER_ID0#defineMCPWM_GEN_A_GPIO21# defineMCPWM_GEN_B_GPIO22voidapp_main (void) {// Create a timermcpwm_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 period.count_mode=MCPWM_TIMER_COUNT_MODE_UP,};ESP_ERROR_CHECK (mcpwm_new_timer (&timer_config,&timer));// Create an operatormcpwm_oper_handle_toper= NULL ;mcpwm_operator_config_toper_config={.group_id=MCPWM_GROUP_ID,};ESP_ERROR_CHECK (mcpwm_new_operator (&oper_config,&oper));// Bind timer and operatorESP_ERROR_CHECK (mcpwm_operator_connect_timer (oper,timer));// Create comparator 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% duty cycle// Create a generatormcpwm_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));// Set generator action 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)));// Start the timerESP_ERROR_CHECK (mcpwm_timer_enable (timer));ESP_ERROR_CHECK (mcpwm_timer_start_stop (timer,MCPWM_TIMER_START_NO_STOP));}

2. Dead zone generation

Programming process:

Create a dead zone module and bind it to the operator.

Configure the dead time, including rising edge dead time and falling edge dead time.

Set the generator’s actions on timer events and comparator events to generate PWM waveforms with dead-band.

# include "driver/mcpwm.h"# include "esp_log.h"#defineMCPWM_GROUP_ID0#defineMCPWM_TIMER_ID0#defineMCPWM_GEN_A_GPIO21# defineMCPWM_GEN_B_GPIO22voidapp_main (void) {// Create a timermcpwm_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 period.count_mode=MCPWM_TIMER_COUNT_MODE_UP,};ESP_ERROR_CHECK (mcpwm_new_timer (&timer_config,&timer));// Create an operatormcpwm_oper_handle_toper= NULL ;mcpwm_operator_config_toper_config={.group_id=MCPWM_GROUP_ID,};ESP_ERROR_CHECK (mcpwm_new_operator (&oper_config,&oper));// Bind timer and operatorESP_ERROR_CHECK (mcpwm_operator_connect_timer (oper,timer));// Create dead zone modulemcpwm_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 dead time};ESP_ERROR_CHECK (mcpwm_new_deadtime (oper,&deadtime_config,&deadtime));// Create a comparatormcpwm_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% duty cycle// Create a generatormcpwm_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));// Set generator action 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)));// Start timer ESP_ERROR_CHECK(mcpwm_timer_enable(timer));ESP_ERROR_CHECK (mcpwm_timer_start_stop (timer,MCPWM_TIMER_START_NO_STOP));}

3. Carrier modulation

Programming process:

Create a carrier module and bind it to the operator.

Configure parameters such as carrier frequency and duty cycle.

Set the generator’s actions on timer events and comparator events to generate carrier-modulated PWM waveforms.

# include "driver/mcpwm.h"# include "esp_log.h"#defineMCPWM_GROUP_ID0#defineMCPWM_TIMER_ID0#defineMCPWM_GEN_A_GPIO21# defineMCPWM_GEN_B_GPIO22voidapp_main (void) {// Create a timermcpwm_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 period.count_mode=MCPWM_TIMER_COUNT_MODE_UP,};ESP_ERROR_CHECK (mcpwm_new_timer (&timer_config,&timer));// Create an operatormcpwm_oper_handle_toper= NULL ;mcpwm_operator_config_toper_config={.group_id=MCPWM_GROUP_ID,};ESP_ERROR_CHECK (mcpwm_new_operator (&oper_config,&oper));// Bind timer and operatorESP_ERROR_CHECK (mcpwm_operator_connect_timer (oper,timer));// Create carrier modulemcpwm_carrier_handle_tcarrier= NULL ;mcpwm_carrier_config_tcarrier_config={.carrier_freq_hz= 20000 , //20kHz carrier frequency.duty_cycle= 50 , //50% carrier duty cycle.update_on_tez= true ,.update_on_tep= true ,.update_on_sync= true ,};ESP_ERROR_CHECK (mcpwm_new_carrier (oper,&carrier_config,&carrier));// Create a comparatormcpwm_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% duty cycle// Create a generatormcpwm_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));// Set generator action 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)));// Start the timerESP_ERROR_CHECK (mcpwm_timer_enable (timer));ESP_ERROR_CHECK (mcpwm_timer_start_stop (timer,MCPWM_TIMER_START_NO_STOP));}

4. Fault Detection

Programming process:

Create a fault detection module and bind it to the operator.

Configure the GPIO pin for fault detection and the fault signal polarity.

Set the generator’s action on failure events to implement failsafe.

# include "driver/mcpwm.h"# include "esp_log.h"#defineMCPWM_GROUP_ID0#defineMCPWM_TIMER_ID0#defineMCPWM_GEN_A_GPIO21#defineMCPWM_GEN_B_GPIO22# defineMCPWM_FAULT_GPIO23voidapp_main (void) {// Create a timermcpwm_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 period.count_mode=MCPWM_TIMER_COUNT_MODE_UP,};ESP_ERROR_CHECK (mcpwm_new_timer (&timer_config,&timer));// Create an operatormcpwm_oper_handle_toper= NULL ;mcpwm_operator_config_toper_config={.group_id=MCPWM_GROUP_ID,};ESP_ERROR_CHECK (mcpwm_new_operator (&oper_config,&oper));// Bind timer and operatorESP_ERROR_CHECK (mcpwm_operator_connect_timer (oper,timer));// Create a fault detection modulemcpwm_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 debounce time};ESP_ERROR_CHECK (mcpwm_new_fault (oper,&fault_config,&fault));// Create a comparatormcpwm_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% duty cycle// Create a generatormcpwm_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));// Set generator action 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)));// Start the timerESP_ERROR_CHECK (mcpwm_timer_enable (timer));ESP_ERROR_CHECK (mcpwm_timer_start_stop (timer,MCPWM_TIMER_START_NO_STOP));}

5. Synchronization module

Programming process:

Create a synchronization module and bind it to the operator.

Configure the source of the synchronization signal and the trigger conditions of the synchronization event.

Set the generator’s action on the synchronization event to synchronize multiple PWM signals.

# include "driver/mcpwm.h"# include "esp_log.h"#defineMCPWM_GROUP_ID0#defineMCPWM_TIMER_ID0#defineMCPWM_GEN_A_GPIO21# defineMCPWM_GEN_B_GPIO22voidapp_main (void) {// Create a timermcpwm_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 period.count_mode=MCPWM_TIMER_COUNT_MODE_UP,};ESP_ERROR_CHECK (mcpwm_new_timer (&timer_config,&timer));// Create an operatormcpwm_oper_handle_toper= NULL ;mcpwm_operator_config_toper_config={.group_id=MCPWM_GROUP_ID,};ESP_ERROR_CHECK (mcpwm_new_operator (&oper_config,&oper));// Bind timer and operatorESP_ERROR_CHECK (mcpwm_operator_connect_timer (oper,timer));// Create a synchronization modulemcpwm_sync_handle_tsync= NULL ;mcpwm_sync_config_tsync_config={.sync_src=MCPWM_SYNC_SRC_TEZ, // The synchronization signal source is the timer overflow event};ESP_ERROR_CHECK (mcpwm_new_sync (oper,&sync_config,&sync));// Create a comparatormcpwm_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% duty cycle// Create a generatormcpwm_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));// Set generator action 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)));// Start the timerESP_ERROR_CHECK (mcpwm_timer_enable (timer));ESP_ERROR_CHECK (mcpwm_timer_start_stop (timer,MCPWM_TIMER_START_NO_STOP));}

6. Braking control

Programming process:

Configure the generator’s braking action on fault events, such as immediate shutdown or cycle-by-cycle regulation.

Set the fault signal source and polarity of the fault detection module.

By starting the timer and running the PWM signal, the generator will perform braking action when a fault occurs.

# include "driver/mcpwm.h"# include "esp_log.h"#defineMCPWM_GROUP_ID0#defineMCPWM_TIMER_ID0#defineMCPWM_GEN_A_GPIO21#defineMCPWM_GEN_B_GPIO22# defineMCPWM_FAULT_GPIO23voidapp_main (void) {// Create a timermcpwm_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 period.count_mode=MCPWM_TIMER_COUNT_MODE_UP,};ESP_ERROR_CHECK (mcpwm_new_timer (&timer_config,&timer));// Create an operatormcpwm_oper_handle_toper= NULL ;mcpwm_operator_config_toper_config={.group_id=MCPWM_GROUP_ID,};ESP_ERROR_CHECK (mcpwm_new_operator (&oper_config,&oper));// Bind timer and operatorESP_ERROR_CHECK (mcpwm_operator_connect_timer (oper,timer));// Create a fault detection modulemcpwm_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 debounce time};ESP_ERROR_CHECK (mcpwm_new_fault (oper,&fault_config,&fault));// Create a comparatormcpwm_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% duty cycle// Create a generatormcpwm_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));// Set generator action 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)));// Configure brake control ESP_ERROR_CHECK(mcpwm_generator_set_brake_action(gen_a,MCPWM_GEN_BRAKE_ACTION_LOW));// Start timer ESP_ERROR_CHECK(mcpwm_timer_enable(timer));ESP_ERROR_CHECK (mcpwm_timer_start_stop (timer,MCPWM_TIMER_START_NO_STOP));}

7. Capture Module

Programming process:

Create a capture module and configure the GPIO pins of the capture channel.

Configure the trigger condition for the capture event, such as rising edge or falling edge.

Enable capture interrupt and read the captured pulse width value in the interrupt processing function.

# include "driver/mcpwm.h"# include "esp_log.h"# include "driver/gpio.h"#defineMCPWM_GROUP_ID0# defineMCPWM_CAPTURE_GPIO21staticvoidIRAM_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) {// Create capture modulemcpwm_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));// Enable capture interruptmcpwm_capture_enable_intr (capture);mcpwm_capture_register_intr_handler (capture,mcpwm_capture_intr_handler,capture);// Start the capture moduleESP_ERROR_CHECK (mcpwm_capture_enable (capture));}

04 MCPWM Commonly Used API Functions

mcpwm_new_timer()

This function is used to create and initialize the MCPWM timer handle, which serves as the time base for all MCPWM functions. Key parameters include the MCPWM group ID (group_id), clock source (clk_src), timer resolution (resolution_hz), count mode (count_mode), and period count value (period_ticks). It serves as the foundation for generating PWM signals, providing a unified period time base for subsequent submodules and applicable to all scenarios requiring PWM output.

mcpwm_new_operator()

This function creates an MCPWM operator handle, serving as the logical control hub for coordinating submodules such as the timer, comparator, and generator. Parameters specify the group ID (group_id), whether to update the generator action when the timer resets (update_gen_action_on_tez), and the interrupt priority (intr_priority). The operator must be bound to a timer to function and is the core control unit for PWM waveform generation.

mcpwm_operator_connect_timer()

This is used to bind an operator to a timer, ensuring that the operator can schedule submodules based on the timer. The parameters are the operator handle (oper) and the timer handle (timer), and both must belong to the same group. This is necessary for the operator to function properly; otherwise, PWM signals cannot be generated.

mcpwm_new_comparator()

This function creates a comparator handle, which is used to set the threshold for the PWM duty cycle toggle. It requires the operator handle (oper) and the configuration for the comparison value update timing (e.g., update_cmp_on_tez indicates an update when the timer reaches zero). The comparator compares the timer count value with the threshold to trigger a level toggle, and is a key module in defining the PWM duty cycle.

mcpwm_new_generator()

This function creates a generator handle responsible for outputting a PWM signal to a specified GPIO pin. Parameters include the corresponding operator handle (oper), the output GPIO number (gen_gpio_num), whether the signal is inverted (invert_pwm), and the pull-up and pull-down configurations (pull_up/pull_down). The generator receives timer and comparator events and performs level manipulation, serving as the final output unit for the PWM signal.

mcpwm_del_timer()

Releases timer resources. The argument is the timer handle. They must be released in the reverse order of “generator → comparator → operator → timer” to avoid resource conflicts and ensure proper recycling of system resources.

mcpwm_del_operator()

Used to release operator resources. The parameter is the operator handle. As one of the resource cleanup steps, it must be executed before releasing the timer to prevent conflicts caused by resource occupation.

mcpwm_del_comparator()

Releases comparator resources. The argument is the comparator handle. This function must be executed before releasing the operator to ensure that the hardware resources occupied by the comparator are properly reclaimed.

mcpwm_del_generator()

Used to release generator resources. The parameter is the generator handle. As the first step in resource cleanup, it must be released first to avoid affecting the resource recovery process of other modules.

mcpwm_comparator_set_compare_value()

Set the comparator threshold to dynamically adjust the PWM duty cycle. The parameters are the comparator handle (cmpr) and the threshold (value), with the threshold value required to be less than or equal to the timer period. The duty cycle is calculated as “threshold value / period value,” making it suitable for scenarios requiring real-time duty cycle adjustment, such as motor speed regulation.

mcpwm_generator_set_action_on_timer_event()

Configure the generator’s level actions for timer events (such as reaching zero or peak). Parameters include the generator handle (gen) and event-action configuration (including counting direction, event type, and actions such as set high, set low, or flip). For example, you can set the output high when the timer reaches zero, defining the level state at the start of a PWM cycle.

mcpwm_generator_set_action_on_compare_event()

Defines the generator’s action upon a comparator event (count value = threshold). It requires the generator handle (gen) and configuration including the count direction, comparator handle, and action. This function sets the level flip when the compare value matches, thereby defining the end point of the PWM duty cycle and achieving a PWM waveform with a specific duty cycle.

mcpwm_generator_set_dead_time()

Configure dead time for PWM signals to prevent simultaneous conduction of both upper and lower transistors in the same bridge arm in power circuits such as H-bridges and three-phase inverters. Parameters include the original generator (in_gen), output generator (out_gen), rising edge delay (posedge_delay_ticks), falling edge delay (negedge_delay_ticks), and whether the output is inverted (invert_output). This function is suitable for power control scenarios requiring complementary PWM signals.

mcpwm_timer_enable()

Enable the timer to start counting and provide a time base for the submodules. The parameter is the timer handle. After enabling, the timer runs according to the configured mode, triggering event responses of subsequent modules such as comparators and generators. This is a key step in activating the MCPWM function.

mcpwm_timer_start_stop()

Controls the start or stop of the timer counting. The parameters are the timer handle and command (MCPWM_TIMER_START to start, MCPWM_TIMER_STOP to stop). It can be used to temporarily pause PWM output, such as in scenarios where rapid start and stop control is required, such as motor emergency stop.

mcpwm_new_gpio_fault()

Create a GPIO fault detection handler to monitor external fault signals (such as overcurrent and overvoltage). Parameters include the faulty GPIO number (gpio_num) and active level (active_level). This handler triggers protection actions by detecting the active level of the specified GPIO. It is suitable for systems requiring hardware fault protection.

mcpwm_operator_set_brake_on_fault()

Configure the operator’s braking mode when a fault occurs. Parameters include the operator handle (oper), the fault handle, and the braking mode (CBC (cycle-by-cycle protection) or OST (one-time shutdown). CBC mode automatically recovers after the fault disappears, while OST requires manual recovery to protect the system during a fault.

mcpwm_timer_register_event_callbacks()

Registers a timer event callback function to respond to events such as cycle expiration and count reset. Parameters include the timer handle, a callback structure (including callbacks like on_full and on_empty), and user data (user_data). This can be used to update parameters (such as dynamically adjusting the duty cycle) at the end of a cycle or to record operating status, enhancing the system’s real-time control capabilities.

FAQ

1. How many PWM outputs does the ESP32 MCPWM module support?

ESP32 contains two MCPWM units, each with three pairs of PWM outputs, for a total of 12 independent PWM signals that can be used in motor control and power electronics applications.

2. What is the function of MCPWM dead zone control?

The dead zone is used to prevent the upper and lower bridge arms of the power device from being turned on at the same time, avoiding power short circuit and ensuring safe and stable operation of the motor control circuit.

3. How to implement PWM carrier modulation on ESP32?

By configuring the carrier frequency and duty cycle through the MCPWM carrier module and binding it with the operator, a carrier-modulated PWM waveform can be generated to improve the accuracy of motor control.

4. Can the MCPWM GPIO pins be freely mapped?

Yes, the ESP32’s MCPWM input and output pins support GPIO matrix configuration. Users can map PWM outputs, capture inputs, fault signals, etc. to any available GPIO pins.

5. How to use the fault detection and braking functions of MCPWM?

MCPWM supports fault signal input through GPIO, automatically shutting down PWM output when overcurrent or overvoltage is detected, achieving emergency braking and ensuring the safety of motors and circuits.

6. What applications is ESP32 MCPWM suitable for?

MCPWM is commonly used in scenarios requiring high-precision PWM, such as brushless DC motor (BLDC) control, stepper motor drive, inverter, switching power supply, and power electronics control.

7. How to configure MCPWM to output PWM signals through ESP-IDF?

Developers can use ESP-IDF’s mcpwm_new_timer(), mcpwm_new_operator(), mcpwm_new_comparator() and other APIs to create timers, operators and comparators, and bind output channels to generate the required PWM signals.

END
 0
Pa2sw0rd
Copyright Notice: Our original article was published by Pa2sw0rd on 2025-09-07, total 27009 words.
Reproduction Note: Unless otherwise specified, all articles are published by cc-4.0 protocol. Please indicate the source of reprint.
Comment(No Comments)