送锡器控制系统fd32_4988_v1

步进电机控制系统详细说明

1. 系统概述

本代码实现了一个完整的步进电机控制系统,支持两种操作模式:点动模式(JOG)和自动循环模式(RUN)。系统通过电位器调节速度和步数,通过按钮控制启停和模式切换,并配有LED状态指示。

2. 主要功能

  • 双模式控制:点动模式(按住按钮运行)和自动循环模式(自动正反转循环)
  • 参数调节
    • 速度调节(通过电位器)
    • 正/反转步数独立调节(通过电位器)
  • 安全保护:急停按钮立即停止电机
  • 状态指示:LED显示当前模式和运行状态
  • 微步控制:支持全步和1/16微步模式

    3. 硬件接线说明

    3.1 所需组件

  • STM32开发板
  • 步进电机驱动器(如A4988、DRV8825等)
  • 步进电机
  • 10kΩ线性电位器×3
  • 按钮×3
  • LED×2(不同颜色)
  • 电阻(220Ω用于LED限流)
  • 电源(根据电机需求)

    3.2 接线表

    元件引脚 开发板引脚 说明
    驱动器EN PB0 使能信号(低电平有效)
    驱动器STEP PA8 步进脉冲
    驱动器DIR PB1 方向控制
    驱动器MS1 PB12 微步控制1
    驱动器MS2 PB13 微步控制2
    驱动器MS3 PB14 微步控制3
    电位器1中间脚 PA0 正转步数调节
    电位器2中间脚 PA1 反转步数调节
    电位器3中间脚 PA2 速度调节
    模式按钮 PA3 模式切换(接GND触发)
    动作按钮 PA4 启动/停止(接GND触发)
    急停按钮 PA5 紧急停止(接GND触发)
    JOG模式LED PB10 通过220Ω电阻接地
    RUN模式LED PB11 通过220Ω电阻接地

    4. 使用方法

    4.1 基本操作流程

    1. 上电后系统默认进入RUN模式(RUN LED常亮)
    2. 旋转速度电位器调节运行速度
    3. 旋转正/反转电位器分别设置正转和反转步数
    4. 按下动作按钮开始自动循环运行
    5. 按下模式按钮可切换到JOG模式(JOG LED常亮)
    6. 在JOG模式下,按住动作按钮电机运行,松开停止
    7. 任何时候按下急停按钮立即停止电机

      4.2 LED状态指示

  • 常亮:表示当前处于该模式(IDLE状态)
  • 闪烁:表示正在该模式下运行
  • 熄灭:表示非当前模式

    5. 代码结构详解

    5.1 主要参数配置

    // 步数范围
    #define MIN_STEPS_CW    0     // 正转最小步数
    #define MAX_STEPS_CW    6000  // 正转最大步数
    // 速度范围(单位微秒)
    #define DEFAULT_MIN_SPEED  5000    // 最快速度(200步/秒)
    #define DEFAULT_MAX_SPEED  500000  // 最慢速度(2步/秒)

    5.2 核心功能函数

    电位器滤波读取

    int filteredAnalogRead(int pin) {
    // 使用移动平均滤波消除噪声
    static int readings[FILTER_SAMPLES] = {0};
    // ...滤波计算...
    return total / FILTER_SAMPLES;
    }

    速度计算

    unsigned long calculateStepDelay(int potValue, bool isJogging) {
    // 使用指数映射实现非线性速度调节
    float expValue = pow(normalized, SPEED_EXPONENT);
    return minSpeed + (unsigned long)(expValue * (maxSpeed - minSpeed));
    }

    电机控制

    void enableMotor() {
    digitalWrite(EN_PIN, LOW); // 驱动器使能
    }
    void disableMotor() {
    digitalWrite(EN_PIN, HIGH); // 驱动器禁用
    }

    5.3 主循环逻辑

    void loop() {
    // 1. 按钮状态检测(带消抖)
    // 2. 根据当前模式处理电机控制:
    //    - IDLE: 等待按钮触发
    //    - JOGGING: 按住按钮时运行
    //    - RUNNING: 自动完成设定的正反转循环
    }

    6. 参数调优建议

    6.1 速度调节

  • 修改DEFAULT_MIN_SPEEDDEFAULT_MAX_SPEED调整速度范围
  • 调整SPEED_EXPONENT(1.0-3.0)改变速度变化曲线

    6.2 步数调节

  • 修改MAX_STEPS_CWMAX_STEPS_CCW调整最大步数
  • 调整FILTER_SAMPLES(3-10)改变电位器响应速度

    6.3 微步设置

    setMicrosteps(16); // 可改为1(全步)、2、4、8、16等

    7. 注意事项

    1. 确保电机电源与逻辑电源隔离
    2. 长距离接线时使用屏蔽线减少干扰
    3. 急停按钮应使用常闭触点,直接切断电机电源更安全
    4. 首次使用时从低速开始测试,逐步提高速度
    5. 确保散热良好,特别是驱动器芯片

      8. 扩展建议

  • 增加限位开关保护
  • 添加加速度控制使启停更平滑
  • 通过EEPROM保存常用参数
  • 增加更多微步模式选择 这个系统提供了灵活的步进电机控制方案,适用于需要精确位置控制的各种应用场景。

9. 程序代码

#include <Arduino.h>

// =============== 硬件引脚定义 ===============
#define EN_PIN          PB0   // 驱动器使能(低电平有效)
#define STEP_PIN        PA8   // 步进脉冲
#define DIR_PIN         PB1   // 方向控制
#define MS1_PIN         PB12  // 微步控制1
#define MS2_PIN         PB13  // 微步控制2
#define MS3_PIN         PB14  // 微步控制3
#define POT_STEPS_CW    PA0   // 正转步数电位器
#define POT_STEPS_CCW   PA1   // 反转步数电位器
#define POT_SPEED       PA2   // 速度电位器
#define BUTTON_MODE     PA3   // 模式切换按钮
#define BUTTON_ACTION   PA4   // 动作按钮
#define BUTTON_STOP     PA5   // 急停按钮
#define LED_JOG         PB10  // 点动模式指示灯
#define LED_RUN         PB11  // 运行模式指示灯

// =============== 可配置参数 ===============
// 步数范围 (电位器映射范围)
#define MIN_STEPS_CW    0     // 正转最小步数
#define MAX_STEPS_CW    6000  // 正转最大步数
#define MIN_STEPS_CCW   0     // 反转最小步数
#define MAX_STEPS_CCW   6000  // 反转最大步数

// 速度范围 (单位: 微秒, 值越小速度越快)
#define DEFAULT_MIN_SPEED       5000    // 默认最快速度 (20us/步)
#define DEFAULT_MAX_SPEED       500000 // 默认最慢速度 (10000us/步)
#define SPEED_EXPONENT  2.5   // 非线性映射指数 (1.0为线性)

// 点动模式速度范围
#define JOG_MIN_SPEED   5000    // 点动最快速度
#define JOG_MAX_SPEED   500000  // 点动最慢速度
#define JOG_SPEED_EXPONENT 2.5 // 点动模式非线性指数

// 系统参数
#define BUTTON_DEBOUNCE 50     // 按钮消抖时间(ms)
#define STATUS_UPDATE_INTERVAL 1000 // 状态更新间隔(ms)
#define SPEED_UPDATE_INTERVAL 100   // 速度更新间隔(ms)
#define FILTER_SAMPLES  5      // 电位器滤波采样数

// =============== 系统状态定义 ===============
enum OperationMode { JOG_MODE, RUN_MODE };
OperationMode currentMode = RUN_MODE;

enum MotorState { IDLE, JOGGING, RUNNING };
MotorState motorState = IDLE;

bool emergencyStop = false;

// 自动循环参数
unsigned long stepsToMoveCW = 0;
unsigned long stepsToMoveCCW = 0;
unsigned long stepsMoved = 0;
unsigned long stepDelay = 0;
int autoPhase = 0;

// 按钮状态管理
bool modeButtonPressed = false;
bool actionButtonPressed = false;
bool actionButtonActive = false;
bool actionButtonConsumed = false;

// 时间跟踪
unsigned long lastStepTime = 0;
unsigned long lastButtonCheck = 0;
unsigned long lastSpeedUpdate = 0;

// 可调速度参数
unsigned long minSpeed = DEFAULT_MIN_SPEED;
unsigned long maxSpeed = DEFAULT_MAX_SPEED;

// =============== 功能函数 ===============
int filteredAnalogRead(int pin) {
  static int readings[FILTER_SAMPLES] = {0};
  static int index = 0;
  static long total = 0;

  total -= readings[index];
  readings[index] = analogRead(pin);
  total += readings[index];
  index = (index + 1) % FILTER_SAMPLES;

  return total / FILTER_SAMPLES;
}

unsigned long calculateStepDelay(int potValue, bool isJogging = false) {
  float normalized = (float)constrain(potValue, 0, 4095) / 4095.0;
  float expValue;

  if(isJogging) {
    expValue = pow(normalized, JOG_SPEED_EXPONENT);
    return JOG_MIN_SPEED + (unsigned long)(expValue * (JOG_MAX_SPEED - JOG_MIN_SPEED));
  } else {
    expValue = pow(normalized, SPEED_EXPONENT);
    return minSpeed + (unsigned long)(expValue * (maxSpeed - minSpeed));
  }
}

void setMicrosteps(uint8_t mode) {
  switch(mode) {
    case 1: // 全步
      digitalWrite(MS1_PIN, LOW);
      digitalWrite(MS2_PIN, LOW);
      digitalWrite(MS3_PIN, LOW);
      break;
    case 16: // 1/16步
      digitalWrite(MS1_PIN, HIGH);
      digitalWrite(MS2_PIN, HIGH);
      digitalWrite(MS3_PIN, HIGH);
      break;
    default: // 默认全步
      digitalWrite(MS1_PIN, LOW);
      digitalWrite(MS2_PIN, LOW);
      digitalWrite(MS3_PIN, LOW);
  }
}

void updateLEDs() {
  static unsigned long lastBlinkTime = 0;
  static bool ledState = false;

  if (motorState == IDLE) {
    digitalWrite(LED_JOG, currentMode == JOG_MODE ? HIGH : LOW);
    digitalWrite(LED_RUN, currentMode == RUN_MODE ? HIGH : LOW);
  } else {
    if(millis() - lastBlinkTime > 300) {
      lastBlinkTime = millis();
      ledState = !ledState;
      digitalWrite(LED_JOG, motorState == JOGGING ? ledState : LOW);
      digitalWrite(LED_RUN, motorState == RUNNING ? ledState : LOW);
    }
  }
}

void enableMotor() {
  if (emergencyStop) return;
  digitalWrite(EN_PIN, LOW);
}

void disableMotor() {
  digitalWrite(EN_PIN, HIGH);
}

void toggleMode() {
  currentMode = (currentMode == JOG_MODE) ? RUN_MODE : JOG_MODE;
  updateLEDs();
}

void startAutoCycle() {
  stepsToMoveCW = map(filteredAnalogRead(POT_STEPS_CW), 0, 4095, MIN_STEPS_CW, MAX_STEPS_CW);
  stepsToMoveCCW = map(filteredAnalogRead(POT_STEPS_CCW), 0, 4095, MIN_STEPS_CCW, MAX_STEPS_CCW);
  stepDelay = calculateStepDelay(filteredAnalogRead(POT_SPEED));

  if (stepsToMoveCCW < 50) stepsToMoveCCW = 0;

  motorState = RUNNING;
  autoPhase = 0;
  stepsMoved = 0;
  digitalWrite(DIR_PIN, HIGH);
  enableMotor();
  updateLEDs();
}

void nextAutoPhase() {
  if (autoPhase == 0 && stepsToMoveCCW > 0) {
    autoPhase = 1;
    stepsMoved = 0;
    digitalWrite(DIR_PIN, LOW);
  } else {
    motorState = IDLE;
    disableMotor();
    updateLEDs();
  }
}

void setup() {
  pinMode(BUTTON_MODE, INPUT_PULLUP);
  pinMode(BUTTON_ACTION, INPUT_PULLUP);
  pinMode(BUTTON_STOP, INPUT_PULLUP);
  pinMode(LED_JOG, OUTPUT);
  pinMode(LED_RUN, OUTPUT);

  pinMode(EN_PIN, OUTPUT);
  pinMode(STEP_PIN, OUTPUT);
  pinMode(DIR_PIN, OUTPUT);
  pinMode(MS1_PIN, OUTPUT);
  pinMode(MS2_PIN, OUTPUT);
  pinMode(MS3_PIN, OUTPUT);

  setMicrosteps(16);
  updateLEDs();
  disableMotor();
}

void loop() {
  unsigned long currentMicros = micros();
  unsigned long currentMillis = millis();

  // 按钮状态检测
  if (currentMillis - lastButtonCheck >= BUTTON_DEBOUNCE) {
    if (!digitalRead(BUTTON_MODE)) {
      if (!modeButtonPressed) {
        modeButtonPressed = true;
        if (motorState == IDLE) toggleMode();
      }
    } else {
      modeButtonPressed = false;
    }

    if (!digitalRead(BUTTON_ACTION)) {
      if (!actionButtonPressed) {
        actionButtonPressed = true;
        actionButtonActive = true;
        actionButtonConsumed = false;
      }
    } else {
      actionButtonPressed = false;
      actionButtonActive = false;
    }

    if (!digitalRead(BUTTON_STOP)) {
      if (!emergencyStop) {
        emergencyStop = true;
        motorState = IDLE;
        disableMotor();
        updateLEDs();
      }
    } else if (emergencyStop) {
      emergencyStop = false;
    }

    lastButtonCheck = currentMillis;
  }

  // 电机状态机
  switch(motorState) {
    case IDLE:
      if (actionButtonActive && !actionButtonConsumed && !emergencyStop) {
        if (currentMode == JOG_MODE) {
          motorState = JOGGING;
          enableMotor();
          updateLEDs();
        } else {
          startAutoCycle();
        }
        actionButtonConsumed = true;
      }
      break;

    case JOGGING:
      if (currentMillis - lastSpeedUpdate >= SPEED_UPDATE_INTERVAL) {
        stepDelay = calculateStepDelay(filteredAnalogRead(POT_SPEED), true);
        lastSpeedUpdate = currentMillis;
      }

      digitalWrite(DIR_PIN, HIGH);

      if (currentMicros - lastStepTime >= stepDelay) {
        digitalWrite(STEP_PIN, HIGH);
        delayMicroseconds(2);
        digitalWrite(STEP_PIN, LOW);
        lastStepTime = currentMicros;
      }

      if (!actionButtonActive) {
        motorState = IDLE;
        disableMotor();
        updateLEDs();
      }
      break;

    case RUNNING:
      if (currentMillis - lastSpeedUpdate >= SPEED_UPDATE_INTERVAL) {
        stepDelay = calculateStepDelay(filteredAnalogRead(POT_SPEED));
        lastSpeedUpdate = currentMillis;
      }

      if (currentMicros - lastStepTime >= stepDelay) {
        digitalWrite(STEP_PIN, HIGH);
        delayMicroseconds(2);
        digitalWrite(STEP_PIN, LOW);
        lastStepTime = currentMicros;

        stepsMoved++;
        if ((autoPhase == 0 && stepsMoved >= stepsToMoveCW) || 
            (autoPhase == 1 && stepsMoved >= stepsToMoveCCW)) {
          nextAutoPhase();
        }
      }
      break;
  }
}

带加速度控制版

增加了加速度控制,使电机启动和停止更加平滑,避免突然启停造成的机械冲击。

#include <Arduino.h>

// =============== 硬件引脚定义 ===============
#define EN_PIN          PB0   // 驱动器使能(低电平有效)
#define STEP_PIN        PA8   // 步进脉冲
#define DIR_PIN         PB1   // 方向控制
#define MS1_PIN         PB12  // 微步控制1
#define MS2_PIN         PB13  // 微步控制2
#define MS3_PIN         PB14  // 微步控制3
#define POT_STEPS_CW    PA0   // 正转步数电位器
#define POT_STEPS_CCW   PA1   // 反转步数电位器
#define POT_SPEED       PA2   // 速度电位器
#define BUTTON_MODE     PA3   // 模式切换按钮
#define BUTTON_ACTION   PA4   // 动作按钮
#define BUTTON_STOP     PA5   // 急停按钮
#define LED_JOG         PB10  // 点动模式指示灯
#define LED_RUN         PB11  // 运行模式指示灯

// =============== 可配置参数 ===============
// 步数范围 (电位器映射范围)
#define MIN_STEPS_CW    0     // 正转最小步数
#define MAX_STEPS_CW    6000  // 正转最大步数
#define MIN_STEPS_CCW   0     // 反转最小步数
#define MAX_STEPS_CCW   6000  // 反转最大步数

// 速度范围 (单位: 微秒, 值越小速度越快)
#define DEFAULT_MIN_SPEED       5000    // 默认最快速度 (200Hz)
#define DEFAULT_MAX_SPEED       500000  // 默认最慢速度 (2Hz)
#define SPEED_EXPONENT         2.5     // 非线性映射指数

// 加速度控制参数
#define ACCELERATION_RATE       1.05   // 加速度系数(每次步进间隔变化率)
#define DECELERATION_STEPS      100    // 减速开始的提前步数
#define MIN_ACCEL_STEP_DELAY    1000   // 加速过程中的最小步进间隔(us)

// 点动模式参数
#define JOG_MIN_SPEED          5000    // 点动最快速度
#define JOG_MAX_SPEED          500000  // 点动最慢速度
#define JOG_SPEED_EXPONENT     2.5     // 点动模式非线性指数
#define JOG_ACCELERATION_RATE  1.08    // 点动模式加速度系数

// 系统参数
#define BUTTON_DEBOUNCE        50      // 按钮消抖时间(ms)
#define SPEED_UPDATE_INTERVAL  100     // 速度更新间隔(ms)
#define FILTER_SAMPLES         5       // 电位器滤波采样数

// =============== 系统状态定义 ===============
enum OperationMode { JOG_MODE, RUN_MODE };
OperationMode currentMode = RUN_MODE;

enum MotorState { IDLE, ACCELERATING, CRUISING, DECELERATING, JOGGING };
MotorState motorState = IDLE;

bool emergencyStop = false;

// 运动控制参数
unsigned long stepsToMoveCW = 0;
unsigned long stepsToMoveCCW = 0;
unsigned long stepsMoved = 0;
unsigned long stepDelay = 0;
unsigned long currentSpeed = 0;
unsigned long targetSpeed = 0;
int autoPhase = 0;
bool direction = true; // true=CW, false=CCW

// 按钮状态管理
bool modeButtonPressed = false;
bool actionButtonPressed = false;
bool actionButtonActive = false;
bool actionButtonConsumed = false;

// 时间跟踪
unsigned long lastStepTime = 0;
unsigned long lastButtonCheck = 0;
unsigned long lastSpeedUpdate = 0;

// =============== 功能函数 ===============
int filteredAnalogRead(int pin) {
  static int readings[FILTER_SAMPLES] = {0};
  static int index = 0;
  static long total = 0;

  total -= readings[index];
  readings[index] = analogRead(pin);
  total += readings[index];
  index = (index + 1) % FILTER_SAMPLES;

  return total / FILTER_SAMPLES;
}

unsigned long calculateStepDelay(int potValue, bool isJogging = false) {
  float normalized = (float)constrain(potValue, 0, 4095) / 4095.0;
  float expValue;

  if(isJogging) {
    expValue = pow(normalized, JOG_SPEED_EXPONENT);
    return JOG_MIN_SPEED + (unsigned long)(expValue * (JOG_MAX_SPEED - JOG_MIN_SPEED));
  } else {
    expValue = pow(normalized, SPEED_EXPONENT);
    return DEFAULT_MIN_SPEED + (unsigned long)(expValue * (DEFAULT_MAX_SPEED - DEFAULT_MIN_SPEED));
  }
}

void setMicrosteps(uint8_t mode) {
  switch(mode) {
    case 1: // 全步
      digitalWrite(MS1_PIN, LOW);
      digitalWrite(MS2_PIN, LOW);
      digitalWrite(MS3_PIN, LOW);
      break;
    case 16: // 1/16步
      digitalWrite(MS1_PIN, HIGH);
      digitalWrite(MS2_PIN, HIGH);
      digitalWrite(MS3_PIN, HIGH);
      break;
    default: // 默认全步
      digitalWrite(MS1_PIN, LOW);
      digitalWrite(MS2_PIN, LOW);
      digitalWrite(MS3_PIN, LOW);
  }
}

void updateLEDs() {
  static unsigned long lastBlinkTime = 0;
  static bool ledState = false;

  if (motorState == IDLE) {
    digitalWrite(LED_JOG, currentMode == JOG_MODE ? HIGH : LOW);
    digitalWrite(LED_RUN, currentMode == RUN_MODE ? HIGH : LOW);
  } else {
    if(millis() - lastBlinkTime > 300) {
      lastBlinkTime = millis();
      ledState = !ledState;
      digitalWrite(LED_JOG, motorState == JOGGING ? ledState : LOW);
      digitalWrite(LED_RUN, (motorState == ACCELERATING || motorState == CRUISING || motorState == DECELERATING) ? ledState : LOW);
    }
  }
}

void enableMotor() {
  if (emergencyStop) return;
  digitalWrite(EN_PIN, LOW);
}

void disableMotor() {
  digitalWrite(EN_PIN, HIGH);
}

void toggleMode() {
  currentMode = (currentMode == JOG_MODE) ? RUN_MODE : JOG_MODE;
  updateLEDs();
}

void startAutoCycle() {
  stepsToMoveCW = map(filteredAnalogRead(POT_STEPS_CW), 0, 4095, MIN_STEPS_CW, MAX_STEPS_CW);
  stepsToMoveCCW = map(filteredAnalogRead(POT_STEPS_CCW), 0, 4095, MIN_STEPS_CCW, MAX_STEPS_CCW);
  targetSpeed = calculateStepDelay(filteredAnalogRead(POT_SPEED));

  if (stepsToMoveCCW < 50) stepsToMoveCCW = 0;

  motorState = ACCELERATING;
  autoPhase = 0;
  stepsMoved = 0;
  direction = true;
  digitalWrite(DIR_PIN, direction ? HIGH : LOW);
  currentSpeed = DEFAULT_MAX_SPEED; // 从最低速开始加速
  enableMotor();
  updateLEDs();
}

void nextAutoPhase() {
  if (autoPhase == 0 && stepsToMoveCCW > 0) {
    autoPhase = 1;
    stepsMoved = 0;
    direction = false;
    digitalWrite(DIR_PIN, direction ? HIGH : LOW);
    motorState = ACCELERATING;
    currentSpeed = DEFAULT_MAX_SPEED;
  } else {
    motorState = IDLE;
    disableMotor();
    updateLEDs();
  }
}

void setup() {
  pinMode(BUTTON_MODE, INPUT_PULLUP);
  pinMode(BUTTON_ACTION, INPUT_PULLUP);
  pinMode(BUTTON_STOP, INPUT_PULLUP);
  pinMode(LED_JOG, OUTPUT);
  pinMode(LED_RUN, OUTPUT);

  pinMode(EN_PIN, OUTPUT);
  pinMode(STEP_PIN, OUTPUT);
  pinMode(DIR_PIN, OUTPUT);
  pinMode(MS1_PIN, OUTPUT);
  pinMode(MS2_PIN, OUTPUT);
  pinMode(MS3_PIN, OUTPUT);

  setMicrosteps(16);
  updateLEDs();
  disableMotor();
}

void loop() {
  unsigned long currentMicros = micros();
  unsigned long currentMillis = millis();

  // 按钮状态检测
  if (currentMillis - lastButtonCheck >= BUTTON_DEBOUNCE) {
    if (!digitalRead(BUTTON_MODE)) {
      if (!modeButtonPressed) {
        modeButtonPressed = true;
        if (motorState == IDLE) toggleMode();
      }
    } else {
      modeButtonPressed = false;
    }

    if (!digitalRead(BUTTON_ACTION)) {
      if (!actionButtonPressed) {
        actionButtonPressed = true;
        actionButtonActive = true;
        actionButtonConsumed = false;
      }
    } else {
      actionButtonPressed = false;
      actionButtonActive = false;
    }

    if (!digitalRead(BUTTON_STOP)) {
      if (!emergencyStop) {
        emergencyStop = true;
        motorState = IDLE;
        disableMotor();
        updateLEDs();
      }
    } else if (emergencyStop) {
      emergencyStop = false;
    }

    lastButtonCheck = currentMillis;
  }

  // 电机状态机
  switch(motorState) {
    case IDLE:
      if (actionButtonActive && !actionButtonConsumed && !emergencyStop) {
        if (currentMode == JOG_MODE) {
          motorState = JOGGING;
          direction = true;
          digitalWrite(DIR_PIN, HIGH);
          currentSpeed = JOG_MAX_SPEED;
          enableMotor();
          updateLEDs();
        } else {
          startAutoCycle();
        }
        actionButtonConsumed = true;
      }
      break;

    case JOGGING:
      if (currentMillis - lastSpeedUpdate >= SPEED_UPDATE_INTERVAL) {
        targetSpeed = calculateStepDelay(filteredAnalogRead(POT_SPEED), true);
        lastSpeedUpdate = currentMillis;
      }

      // 加速度控制
      if (currentSpeed > targetSpeed) {
        currentSpeed = max(targetSpeed, (unsigned long)(currentSpeed / JOG_ACCELERATION_RATE));
      } else if (currentSpeed < targetSpeed) {
        currentSpeed = min(targetSpeed, (unsigned long)(currentSpeed * JOG_ACCELERATION_RATE));
      }

      // 生成步进脉冲
      if (currentMicros - lastStepTime >= currentSpeed) {
        digitalWrite(STEP_PIN, HIGH);
        delayMicroseconds(2);
        digitalWrite(STEP_PIN, LOW);
        lastStepTime = currentMicros;
      }

      if (!actionButtonActive) {
        // 松开按钮时减速停止
        if (currentSpeed < JOG_MAX_SPEED * 1.5) {
          motorState = IDLE;
          disableMotor();
          updateLEDs();
        }
      }
      break;

    case ACCELERATING:
      // 加速过程
      currentSpeed = max((unsigned long)(currentSpeed / ACCELERATION_RATE), targetSpeed);

      if (currentSpeed <= targetSpeed) {
        motorState = CRUISING;
        currentSpeed = targetSpeed;
      }

      // 检查是否需要开始减速
      if ((autoPhase == 0 && stepsMoved >= stepsToMoveCW - DECELERATION_STEPS) ||
          (autoPhase == 1 && stepsMoved >= stepsToMoveCCW - DECELERATION_STEPS)) {
        motorState = DECELERATING;
      }

      // 生成步进脉冲
      if (currentMicros - lastStepTime >= currentSpeed) {
        digitalWrite(STEP_PIN, HIGH);
        delayMicroseconds(2);
        digitalWrite(STEP_PIN, LOW);
        lastStepTime = currentMicros;
        stepsMoved++;
      }
      break;

    case CRUISING:
      // 匀速运行阶段
      if (currentMillis - lastSpeedUpdate >= SPEED_UPDATE_INTERVAL) {
        targetSpeed = calculateStepDelay(filteredAnalogRead(POT_SPEED));
        lastSpeedUpdate = currentMillis;

        // 如果目标速度改变,切换到加速/减速状态
        if (targetSpeed < currentSpeed) {
          motorState = ACCELERATING;
        } else if (targetSpeed > currentSpeed) {
          motorState = DECELERATING;
        }
      }

      // 检查是否需要开始减速
      if ((autoPhase == 0 && stepsMoved >= stepsToMoveCW - DECELERATION_STEPS) ||
          (autoPhase == 1 && stepsMoved >= stepsToMoveCCW - DECELERATION_STEPS)) {
        motorState = DECELERATING;
      }

      // 生成步进脉冲
      if (currentMicros - lastStepTime >= currentSpeed) {
        digitalWrite(STEP_PIN, HIGH);
        delayMicroseconds(2);
        digitalWrite(STEP_PIN, LOW);
        lastStepTime = currentMicros;
        stepsMoved++;
      }
      break;

    case DECELERATING:
      // 减速过程
      currentSpeed = min((unsigned long)(currentSpeed * ACCELERATION_RATE), DEFAULT_MAX_SPEED);

      // 生成步进脉冲
      if (currentMicros - lastStepTime >= currentSpeed) {
        digitalWrite(STEP_PIN, HIGH);
        delayMicroseconds(2);
        digitalWrite(STEP_PIN, LOW);
        lastStepTime = currentMicros;
        stepsMoved++;
      }

      // 检查是否完成减速或到达目标位置
      if ((autoPhase == 0 && stepsMoved >= stepsToMoveCW) ||
          (autoPhase == 1 && stepsMoved >= stepsToMoveCCW) ||
          currentSpeed >= DEFAULT_MAX_SPEED * 0.9) {
        nextAutoPhase();
      }
      break;
  }
}

加速度控制实现说明

1. 新增状态定义

enum MotorState { 
  IDLE,           // 空闲状态
  ACCELERATING,   // 加速状态
  CRUISING,       // 匀速状态
  DECELERATING,   // 减速状态
  JOGGING         // 点动状态
};

2. 关键加速度参数

#define ACCELERATION_RATE       1.05   // 加速度系数(每次步进间隔变化率)
#define DECELERATION_STEPS      100    // 减速开始的提前步数
#define MIN_ACCEL_STEP_DELAY    1000   // 加速过程中的最小步进间隔(us)

3. 加速度控制逻辑

加速过程

currentSpeed = max((unsigned long)(currentSpeed / ACCELERATION_RATE), targetSpeed);

减速过程

currentSpeed = min((unsigned long)(currentSpeed * ACCELERATION_RATE), DEFAULT_MAX_SPEED);

点动模式加速度

#define JOG_ACCELERATION_RATE  1.08    // 点动模式加速度系数

4. 运动控制流程

  1. 启动时:从最低速开始加速到目标速度(ACCELERATING)
  2. 达到目标速度:进入匀速运行状态(CRUISING)
  3. 接近终点时:提前开始减速(DECELERATING)
  4. 点动模式:按下按钮时加速,松开时减速

系统优化说明

  1. 平滑启停:通过加速度控制消除了电机启停时的机械冲击
  2. 动态调速:运行中可以实时调整目标速度,系统会自动加速/减速到新速度
  3. 自适应减速:根据剩余步数自动计算最佳减速点
  4. 点动模式优化:独立的加速度参数使点动操作更符合人机工程学

这个改进版本特别适合需要精密控制的场合,可以有效减少机械振动和提高定位精度。