ESP32 пример генерации ШИМ с работой в противофазе используя 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 то лучше не использовать код в цикле loop() функции, а использовать модуль перефирии MCPWM.
Ссылки где почитать больше об MCPW
Официальная дока
W