Цей приклад класу використовує 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
Якщо ця стаття допомогла вам, будь ласка, подумайте про те, щоб купити мені каву або зробити пожертву через PayPal на підтримку досліджень та публікації нових статей на TechOverflow