ESP32 пример генерации ШИМ с работой в противофазе используя MCPWM и deadtime

Работа MCPWM с deadtime

MCPWM - настраивает специальный ШИМ (PWM) сигнал для того чтобы аппаратно управлять моторами с помощью ESP32, то есть это блок встроенной периферии который конфигурируется в setup() функции и не занимает рабочий цикл. Самый простой пример для чего можно использовать MCPWM - качать трансформатор с отводом от середины. Сначала код, а потом пояснения.


#include "driver/mcpwm.h"
#include "soc/mcpwm_periph.h"

// Пины
#define PIN_A 18
#define PIN_B 19

// Частота ШИМ (в Гц)
#define PWM_FREQUENCY 20000

// Коэффициент заполнения (duty cycle) от 0 до 100 (%)
#define DUTY_CYCLE 50
#define DEADTIME_TICKS DEADTIME_NS
// Например, 1 ticks = 100 нс 2 ticks = 200 нс и т.д. для одного фронта (у нас их два)
#define DEADTIME_NS 1


// Стандартный setup() arduino
void setup() {
   // Инициализация MCPWM unit 0
    mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0A, PIN_A);
    mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0B, PIN_B);

    // Конфигурация таймера
    mcpwm_config_t pwm_config;
    pwm_config.frequency = PWM_FREQUENCY;       // Частота ШИМ
    pwm_config.cmpr_a = DUTY_CYCLE;             // Коэффициент заполнения канала A
    pwm_config.cmpr_b = DUTY_CYCLE;             // Коэффициент заполнения канала B (наверное будет проигнорирован, так как MCPWM_ACTIVE_HIGH_COMPLIMENT_MODE включает инвертирование канала А для B)
    pwm_config.counter_mode = MCPWM_UP_COUNTER; // Обновление в начале каждого цикла
    pwm_config.duty_mode = MCPWM_DUTY_MODE_0;   // Обычный режим

    mcpwm_init(MCPWM_UNIT_0, MCPWM_TIMER_0, &pwm_config);



    // Настройка dead-time
    mcpwm_deadtime_enable(MCPWM_UNIT_0, MCPWM_TIMER_0,
                          MCPWM_ACTIVE_HIGH_COMPLIMENT_MODE,  // Режим dead-time
                          DEADTIME_NS,                        // RED (rising edge delay)
                          DEADTIME_NS);   

    // Включаем оба канала
    mcpwm_start(MCPWM_UNIT_0, MCPWM_TIMER_0);
}

// Стандартный loop() arduino
void loop() {
  vTaskDelay(1000); // Просто ничего не делаем все время          
}

Рассмотрим чуть ближе сигнал с логического анализатора:

Как видно общий deadtime при 100ns равен 200ns имейте ввиду. Общий deadtime рассчитывается по формуле:

deadtime общий, в наносекундах = DEADTIME_NS * 100 * 2

Частота и заполнение меняются через спец функций:

mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_OPR_A, 7.5); // Процент заполнения канала A 7.5 %

mcpwm_set_frequency(MCPWM_UNIT_0, MCPWM_TIMER_0, 50); // Частота генерации 50 Гц


mcpwm_deadtime_enable(MCPWM_UNIT_0, MCPWM_TIMER_0,
                          MCPWM_ACTIVE_HIGH_COMPLIMENT_MODE, 
                          2,                       
                          2);// deadtime общий deadtime 400нс

Имейте ввиду, что для остановки ШИМ сигнала нужно будет переконфигурировать deadtime. Т.к. после его включения выводы работают только в противофазе, и кроме как их переконфигурирования ничего сделать нельзя. Для драйвера лучше используйте gpio 5 чтобы с подтягивающим на землю (при старте драйвер не будет работать).


Очень хорошо управлять накачкой трансформатора через драйвер затвора:

Схема управления трансформатором через ESP32

Заключение

Если требуется два противофазных сигнала на ESP32 то лучше не использовать код в цикле loop() функции, а использовать модуль перефирии MCPWM.

Ссылки где почитать больше об MCPW

Официальная дока 

W

{{ x.text }}