简单理解:ESP32S3 开发板中通过什么控制舵机

在 ESP32S3 开发板中,MCPWM 定时器LEDC 定时器的数量及配置如下:

1. MCPWM 定时器数量

ESP32S3 集成了 2 个 MCPWM 单元 ,每个单元包含 3 个独立定时器 ,因此总共有 6 个 MCPWM 定时器

  • 每个定时器可独立配置频率、计数模式(向上 / 向下计数)等参数。
  • 每个定时器可驱动 2 个 PWM 输出通道(如 MCPWM0AMCPWM0B),因此 2 个 MCPWM 单元共支持 6 个定时器 × 2 通道 = 12 路 PWM 输出

用途:主要用于需要复杂控制的场景(如电机正反转、舵机角度控制等)。

2. LEDC 定时器数量

ESP32S3 集成了 2 个 LEDC 定时器组 (低速组和高速组),每组包含 8 个定时器 ,因此总共有 16 个 LEDC 定时器

  • 定时器分为 低速模式(LEDC_LOW_SPEED_MODE)高速模式(LEDC_HIGH_SPEED_MODE),低速模式通常用于 GPIO 矩阵引脚,高速模式用于专用外设引脚。
  • 每个定时器可绑定多个 LEDC 通道(最多 8 个通道共享 1 个定时器),因此 16 个定时器可支持 16 通道 PWM 输出(每个通道独立控制占空比,但共享定时器的频率)。

用途:适合简单 PWM 场景(如 LED 调光、背光调节等)。

总结

外设 定时器数量 通道数量(最大) 典型用途
MCPWM 6 个 12 路 舵机、直流电机控制
LEDC 16 个 16 路 LED 调光、简单 PWM 输出

实际使用时,需根据引脚功能(专用引脚 / 矩阵引脚)和场景需求选择定时器和通道,避免与其他外设(如摄像头、显示屏)的引脚冲突。


在 ESP32S3 上控制舵机的常见做法是使用 MCPWM 外设(因舵机需要稳定的 50Hz PWM 信号),以下是参考网上开源实现的舵机控制代码,可集成到你的项目中:

1. 舵机控制类(servo_controller.h

复制代码
#ifndef __SERVO_CONTROLLER_H__
#define __SERVO_CONTROLLER_H__

#include "driver/mcpwm.h"
#include "esp_err.h"

class ServoController {
private:
    mcpwm_unit_t mcpwm_unit_;      // MCPWM 单元(0 或 1)
    mcpwm_timer_t timer_num_;      // 定时器编号(0-2)
    mcpwm_io_signals_t io_signal_; // 信号输出通道(如 MCPWM0A、MCPWM0B 等)
    gpio_num_t gpio_num_;          // 控制引脚
    uint32_t min_pulse_width_;     // 最小脉冲宽度(对应 0°,单位:us)
    uint32_t max_pulse_width_;     // 最大脉冲宽度(对应 180°,单位:us)
    uint32_t freq_hz_;             // PWM 频率(通常 50Hz)

public:
    /**
     * 构造函数:初始化舵机参数
     * @param unit MCPWM 单元(MCPWM_UNIT_0 或 MCPWM_UNIT_1)
     * @param timer 定时器编号(MCPWM_TIMER_0 等)
     * @param signal 输出通道(MCPWM0A 等)
     * @param gpio 控制引脚(需未被占用)
     * @param min_us 最小脉冲宽度(默认 500us,对应 0°)
     * @param max_us 最大脉冲宽度(默认 2500us,对应 180°)
     * @param freq 频率(默认 50Hz)
     */
    ServoController(
        mcpwm_unit_t unit,
        mcpwm_timer_t timer,
        mcpwm_io_signals_t signal,
        gpio_num_t gpio,
        uint32_t min_us = 500,
        uint32_t max_us = 2500,
        uint32_t freq = 50
    ) : mcpwm_unit_(unit),
        timer_num_(timer),
        io_signal_(signal),
        gpio_num_(gpio),
        min_pulse_width_(min_us),
        max_pulse_width_(max_us),
        freq_hz_(freq) {}

    /**
     * 初始化 MCPWM 外设和引脚
     */
    esp_err_t Init() {
        // 1. 配置 MCPWM 定时器
        mcpwm_config_t pwm_config = {
            .frequency = freq_hz_,                  // 舵机标准频率 50Hz
            .cmpr_a = 0,                            // 初始占空比(通道 A)
            .counter_mode = MCPWM_UP_COUNTER,        // 向上计数模式
            .duty_mode = MCPWM_DUTY_MODE_0,          // 占空比模式
        };
        ESP_ERROR_CHECK(mcpwm_init(mcpwm_unit_, timer_num_, &pwm_config));

        // 2. 绑定引脚到 MCPWM 信号
        ESP_ERROR_CHECK(mcpwm_gpio_init(mcpwm_unit_, io_signal_, gpio_num_));

        // 3. 初始化为 0°
        return SetAngle(0);
    }

    /**
     * 设置舵机角度
     * @param angle 角度(0-180°)
     */
    esp_err_t SetAngle(uint8_t angle) {
        if (angle > 180) return ESP_ERR_INVALID_ARG;

        // 计算脉冲宽度:从角度映射到 [min_us, max_us]
        uint32_t pulse_width = min_pulse_width_ + 
            (max_pulse_width_ - min_pulse_width_) * angle / 180;

        // 计算占空比(占空比 = 脉冲宽度(us) / 周期(us) * 100)
        // 周期(us) = 1e6 / 频率(Hz)(50Hz 时周期为 20000us)
        float duty_cycle = (float)pulse_width * 100 / (1000000.0f / freq_hz_);

        // 设置占空比
        mcpwm_set_duty(mcpwm_unit_, timer_num_, io_signal_, duty_cycle);
        mcpwm_set_duty_type(mcpwm_unit_, timer_num_, io_signal_, MCPWM_DUTY_MODE_0);
        return ESP_OK;
    }
};

#endif // __SERVO_CONTROLLER_H__

2. 使用示例(集成到项目中)

InitializeIot() 或其他初始化函数中添加舵机控制:

复制代码
#include "servo_controller.h"

// 在 config.h 中添加舵机引脚定义(选择未被占用的引脚,如 GPIO_NUM_2)
#define SERVO_GPIO GPIO_NUM_2

// 初始化舵机
void InitializeServo() {
    // 实例化舵机控制器(使用 MCPWM 单元 0、定时器 0、通道 A,引脚 GPIO2)
    static ServoController servo(
        MCPWM_UNIT_0,
        MCPWM_TIMER_0,
        MCPWM0A,
        SERVO_GPIO
    );

    // 初始化舵机(默认 0°)
    if (servo.Init() != ESP_OK) {
        ESP_LOGE(TAG, "Servo initialization failed");
    }

    // 示例:通过 MCP 协议暴露舵机控制接口
    auto& mcp_server = McpServer::GetInstance();
    mcp_server.AddTool("self.servo.set_angle",
        "Set the angle of the servo motor (0-180 degrees)",
        PropertyList({
            Property("angle", kPropertyTypeInteger, 0, 180) // 角度参数(0-180)
        }),
        [&servo](const PropertyList& properties) -> ReturnValue {
            uint8_t angle = properties["angle"].value<int>();
            esp_err_t ret = servo.SetAngle(angle);
            return ret == ESP_OK ? true : false;
        }
    );
}

3. 关键说明

  • 引脚选择 :需在 config.h 中定义 SERVO_GPIO,且该引脚未被摄像头、LCD 等其他外设占用(参考项目中已用引脚,避免冲突)。
  • 脉冲参数 :不同舵机的 min_pulse_width_max_pulse_width_ 可能不同(通常 500-2500us),需根据舵机 datasheet 调整。
  • MCP 集成 :通过 AddTool 注册 self.servo.set_angle 命令后,即可通过 MCP 协议发送指令控制舵机角度(如 self.servo.set_angle(90) 控制到 90°)。

4. 硬件连接

舵机通常有 3 根线:

  • 棕色 / 黑色:GND(接 ESP32S3 的 GND)
  • 红色:电源(通常 5V,不可直接接 ESP32S3 的 3.3V,需外接电源)
  • 橙色 / 黄色:信号线(接定义的 SERVO_GPIO,如 GPIO2)

通过以上代码,即可在你的项目中实现舵机控制,并通过小智 AI 的 MCP 协议远程调节角度。

相关推荐
victorwjw1 小时前
STM32 ISP下载原理
stm32·嵌入式硬件
沐欣工作室_lvyiyi1 小时前
基于单片机的智能宠物监护设备(论文+源码)
stm32·单片机·毕业设计·宠物监护
cjy_Somnr1 小时前
电机驱动学习以及闭环控制和硬件连接
嵌入式硬件·学习
小李做物联网1 小时前
【物联网毕设】60.1基于单片机物联网嵌入式项目程序开发之智能家庭安防感应报警
stm32·单片机·嵌入式硬件·物联网
沉在嵌入式的鱼1 小时前
STM32--BH1750光敏传感器
stm32·单片机·嵌入式硬件·bh1750·光敏模块
bai5459361 小时前
STM32 单片机 按键控制led灯亮灭
stm32·单片机·嵌入式硬件
heisd_12 小时前
使用TRAE来制作MCP和Agent
agent·mcp·trae
三佛科技-187366133972 小时前
FT60F210-URT是什么芯片?FT60F210-URT(系统框图及管脚定义)
单片机·嵌入式硬件
传感器与混合集成电路2 小时前
提升多轴同步精度:DSP+FPGA架构在高端特种装备伺服控制中的应用
嵌入式硬件·fpga开发·架构