一、硬件装备清单

二、核心参数说明

  1. 42 步进电机参数
    1. 步距角:1.8°(整步模式下,200 步 = 360°)
    2. 额定电流:1.7A
    3. 线圈分组:红 - 蓝(A 组)、黑 - 绿(B 组)(根据万用表测量结果)
  2. 驱动器参数
    1. 供电电压:24V(电机电源)
    2. 控制信号电压:3.3V(兼容 ESP32-S3 输出)
    3. 细分设置:默认整步(S1=ON, S2=ON, S3=OFF)(需与代码匹配)
    4. 电流设置:1.7A(根据拨码开关说明书设置,如 S4=ON, S5=ON, S6=OFF)
  3. ESP32-S3 引脚功能
    1. GPIO14:脉冲信号(PUL+)
    2. GPIO15:方向信号(DIR+)
    3. GPIO16:使能信号(ENA+)
    4. GND:共地引脚

三、接线表格(关键连接关系)

一、电机线圈与驱动器连接表(你的实际分组)

二、ESP32-S3 与驱动器信号连接表

三、电源与共地连接表(核心共地回路)

四、接线正确性验证表(自查用)

五、代码解析

  • 头文件与宏定义

#include <stdio.h> // 标准输入输出(用于打印调试信息)

#include <math.h> // 数学函数库(用于 fabs() 取绝对值)

#include "freertos/FreeRTOS.h" // FreeRTOS 实时操作系统接口(任务调度)

#include "freertos/task.h" // FreeRTOS 任务相关函数(如 vTaskDelay)

#include "driver/gpio.h" // ESP32 GPIO 驱动库(配置引脚输入输出)

#include "esp_err.h" // ESP32 错误处理库(返回错误码)

#include "esp_rom_sys.h" // ESP32 内置 ROM 函数(用于 esp_rom_delay_us 延时)

引脚定义(核心控制信号)
电机参数(整步模式下)

#define STEP_ANGLE 1.8f // 步距角(每步转动的角度,42 电机常见值)

#define FULL_STEPS 200 // 360° 所需步数(360 / 1.8 = 200 步)

#define MAX_SPEED 1000 // 最大速度(每秒最多走 1000 步)

#define MIN_DELAY_US 1000 // 最小脉冲间隔(避免速度过快导致电机堵转)

方向枚举(简化方向控制)

二、核心函数解析

1. 电机初始化函数 stepper_init()

esp_err_t stepper_init(void) {

// 配置 GPIO 引脚参数

gpio_config_t io_conf = {

.pin_bit_mask = (1ULL << PUL_PIN) | (1ULL << DIR_PIN) | (1ULL << ENA_PIN),

// 要配置的引脚:PUL、DIR、ENA

.mode = GPIO_MODE_OUTPUT, // 设为输出模式(发送控制信号)

.pull_up_en = GPIO_PULLUP_DISABLE, // 禁用上拉电阻

.pull_down_en = GPIO_PULLDOWN_DISABLE, // 禁用下拉电阻

.intr_type = GPIO_INTR_DISABLE // 禁用中断(无需触发中断)

};

// 应用配置,返回错误码(如配置失败)

esp_err_t ret = gpio_config(&io_conf);

if (ret != ESP_OK) {

return ret; // 配置失败,返回错误

}



// 使能电机(ENA 引脚高电平有效,低电平会锁定电机)

gpio_set_level(ENA_PIN, 1);

// 初始方向设为顺时针(DIR 引脚输出低电平)

gpio_set_level(DIR_PIN, STEPPER_DIR_CW);

return ESP_OK; // 初始化成功

}

作用:将控制引脚配置为输出模式,使能电机并设置初始方向,为后续控制做准备。

2. 方向设置函数 stepper_set_dir()

void stepper_set_dir(stepper_dir_t dir) {

gpio_set_level(DIR_PIN, dir); // 通过 DIR 引脚电平控制方向

}

作用:通过改变 DIR 引脚的高低电平,切换电机旋转方向(0 为顺时针,非 0 为逆时针)。

3. 单步驱动函数 stepper_step()

void stepper_step(uint32_t delay_us) {

gpio_set_level(PUL_PIN, 1); // 脉冲引脚输出高电平(开始一步)

esp_rom_delay_us(10); // 高电平持续 10us(满足驱动器最小脉冲宽度要求)

gpio_set_level(PUL_PIN, 0); // 脉冲引脚输出低电平(结束一步)

esp_rom_delay_us(delay_us); // 步间延迟(控制转速:延迟越短,速度越快)

}

作用:发送一个完整的脉冲信号(高电平 + 低电平),驱动电机转动一步(1.8°)。步间延迟 delay_us 决定了电机速度(延迟越小,每秒步数越多,速度越快)。

4. 角度旋转函数 stepper_rotate()

void stepper_rotate(float angle, uint32_t speed) {

// 限制速度不超过最大值(避免电机过载)

if (speed > MAX_SPEED) {

speed = MAX_SPEED;

}

// 计算步间延迟(微秒):1秒=1e6微秒,除以每秒步数得每步间隔

uint32_t delay_us = 1000000 / speed;

// 确保延迟不小于最小值(避免速度过快导致堵转)

if (delay_us < MIN_DELAY_US) {

delay_us = MIN_DELAY_US;

}



// 计算所需步数:角度 → 步数(四舍五入)

// 公式:步数 = 角度绝对值 × 总步数(200) / 360°

uint32_t steps_needed = (uint32_t)(fabs(angle) * FULL_STEPS / 360.0f + 0.5f);

if (steps_needed == 0) { // 角度为0时无需转动

return;

}



// 根据角度正负设置方向(负角度为逆时针)

if (angle < 0) {

stepper_set_dir(STEPPER_DIR_CCW);

} else {

stepper_set_dir(STEPPER_DIR_CW);

}



// 循环发送脉冲,完成指定步数(即指定角度)

for (uint32_t i = 0; i < steps_needed; i++) {

stepper_step(delay_us);

}

}

作用:根据目标角度和速度,自动计算所需步数和步间延迟,控制电机旋转到指定角度。

三、主函数 app_main()

void app_main(void) {

// 初始化步进电机,检查是否成功

esp_err_t ret = stepper_init();

if (ret != ESP_OK) {

printf("Stepper init failed: %s\n", esp_err_to_name(ret));

return; // 初始化失败则退出

}

printf("Stepper initialized\n"); // 初始化成功提示



// 循环执行旋转动作

while (1) {

// 顺时针旋转90度,速度500步/秒

printf("Rotate 90 degrees CW\n");

stepper_rotate(90.0f, 500);

vTaskDelay(pdMS_TO_TICKS(2000)); // 暂停2秒(等待旋转完成)



// 逆时针旋转180度,速度800步/秒

printf("Rotate 180 degrees CCW\n");

stepper_rotate(-180.0f, 800);

vTaskDelay(pdMS_TO_TICKS(2000)); // 暂停2秒



// 顺时针旋转360度,速度1000步/秒

printf("Rotate 360 degrees CW\n");

stepper_rotate(360.0f, 1000);

vTaskDelay(pdMS_TO_TICKS(2000)); // 暂停2秒

}

}

作用:程序入口,初始化电机后进入循环,演示不同角度和速度的旋转动作(顺时针 90°→逆时针 180°→顺时针 360°,循环往复)。

四、核心逻辑总结

  1. 控制原理:通过 PUL 引脚的脉冲数量控制旋转角度(1 脉冲 = 1 步 = 1.8°),通过 DIR 引脚电平控制方向,通过脉冲间隔控制速度。
  2. 参数匹配:代码中 FULL_STEPS(200 步)需与驱动器细分设置一致(整步模式),否则角度计算会偏差。
  3. 安全性:限制最大速度和最小延迟,避免电机因过载或频率不匹配导致 “堵转”(只响不转)。

通过修改 stepper_rotate() 的参数(角度和速度),可实现任意角度的精准旋转,适用于需要精确定位的场景(如机械臂、精密平台等)。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐