Базовий драйвер DRV8231 на C++, сумісний з ESP-IDF та PlatformIO

Цей приклад класу використовує LEDC PWM-драйвер ESP-IDF для керування драйвером двигуна DRV8231 (ви також можете використовувати драйвер MCPWM) для керування драйвером двигуна DRV8231.

Заголовок (DRV8231.hpp)

DRV8231.hpp
#pragma once
#include <cstdio>
#include <cstdint>
#include <driver/gpio.h>
#include <driver/ledc.h>

class DRV8231 {
public:
    DRV8231(gpio_num_t pwmA, gpio_num_t pwmB, ledc_channel_t channelA, ledc_channel_t channelB);

    void Start(uint16_t speed, bool reverse=false);
    void Stop();
private:
    gpio_num_t pwmA;
    gpio_num_t pwmB;
    ledc_channel_t channelA;
    ledc_channel_t channelB;
};

Джерело (DRV8231.cpp)

DRV8231.cpp
#include "DRV8231.hpp"
#include <algorithm>


DRV8231::DRV8231(gpio_num_t pwmA, gpio_num_t pwmB, ledc_channel_t channelA, ledc_channel_t channelB) {
    // Зберегти номери пінів
    this->pwmA = pwmA;
    this->pwmB = pwmB;
    this->channelA = channelA;
    this->channelB = channelB;

    // Налаштувати таймер LEDC для генерації PWM
    ledc_timer_config_t ledc_timer = {
        .speed_mode = LEDC_LOW_SPEED_MODE,
        .duty_resolution = LEDC_TIMER_10_BIT,  // 8-бітна роздільна здатність (0-255)
        .timer_num = LEDC_TIMER_0,
        .freq_hz = 20000,  // Встановити частоту 100 кГц
        .clk_cfg = LEDC_AUTO_CLK
    };
    ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));

    // Налаштувати канал LEDC для pwmA
    ledc_channel_config_t ledc_channel_a = {
        .gpio_num = pwmA,
        .speed_mode = LEDC_LOW_SPEED_MODE,
        .channel = channelA,
        .intr_type = LEDC_INTR_DISABLE,
        .timer_sel = LEDC_TIMER_0,
        .duty = 0,  // Ініціалізувати з 0% заповнення
        .hpoint = 0
    };
    ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel_a));

    // Налаштувати канал LEDC для pwmB
    ledc_channel_config_t ledc_channel_b = {
        .gpio_num = pwmB,
        .speed_mode = LEDC_LOW_SPEED_MODE,
        .channel = channelB,
        .intr_type = LEDC_INTR_DISABLE,
        .timer_sel = LEDC_TIMER_0,
        .duty = 0,  // Ініціалізувати з 0% заповнення
        .hpoint = 0
    };
    ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel_b));

}

void DRV8231::Start(uint16_t speed, bool reverse) {
    uint16_t duty = std::min(speed, (uint16_t)1023);  // Обмежити швидкість діапазоном 0-4095
    // Встановити напрямок та заповнення
    if (reverse) {
        ledc_set_duty(LEDC_LOW_SPEED_MODE, channelB, duty);
        ledc_update_duty(LEDC_LOW_SPEED_MODE, channelB);
        ledc_set_duty(LEDC_LOW_SPEED_MODE, channelA, 1023);
        ledc_update_duty(LEDC_LOW_SPEED_MODE, channelA);
    } else {
        ledc_set_duty(LEDC_LOW_SPEED_MODE, channelA, duty);
        ledc_update_duty(LEDC_LOW_SPEED_MODE, channelA);
        ledc_set_duty(LEDC_LOW_SPEED_MODE, channelB, 1023); // 100%
        ledc_update_duty(LEDC_LOW_SPEED_MODE, channelB);
    }
}

void DRV8231::Stop() {
    // Встановити обидва канали на 100% заповнення (тобто гальмування)
    ledc_set_duty(LEDC_LOW_SPEED_MODE, channelA, 1023);
    ledc_update_duty(LEDC_LOW_SPEED_MODE, channelA);
    ledc_set_duty(LEDC_LOW_SPEED_MODE, channelB, 1023);
    ledc_update_duty(LEDC_LOW_SPEED_MODE, channelB);
}

Приклад використання

usage_example.cpp
#include "DRV8231.hpp"

DRV8231 motor(GPIO_NUM_7, GPIO_NUM_8, LEDC_CHANNEL_0, LEDC_CHANNEL_1);

extern "C" void app_main() {
  while (true) {
    // Ініціалізувати драйвер DRV8231
    motor.Start(512);  // Запустити двигун на половині швидкості
    vTaskDelay(pdMS_TO_TICKS(2000));  // Працювати 2 секунди
    motor.Stop();  // Зупинити двигун
  }
}

Дивіться схожі статті за категоріями: C/C++ Electronics ESP-IDF