STM32F103C8T6+TMC2209+ArduinoIDE

介绍:

本代码为STM32F103C8T6固件,外设为:TMC2209步进电机驱动、三个电位器、三个按钮、两个指示灯、步进电机等;适合制作送锡器、出丝器、蠕动挤出等设备的控制器,其功能是按钮1控制电机点动,由电位器调整速度,且不反转。按钮2控制单次触发电机按电位器3指定速度正转(电位器1控制旋转角度)并反转(电位器2控制旋转角度),当电位器2临近最小值时关闭反转。3开关为急停功能,急停按钮按下时电机停止工作,按钮解除时回复待机状态。待机时LED1常亮,电机运行时LED2常亮。

系统功能说明

1. 硬件配置

  • 主控芯片: STM32F103C8T6 (Blue Pill开发板)
  • 驱动器: TMC2209 (带UART通信)
  • 输入:
    • 3个旋转电位器 (正转步数, 反转步数, 速度控制)
    • 3个按钮 (模式切换, 动作, 急停)
  • 输出:
    • 2个LED指示灯 (点动模式, 运行模式)
    • 步进电机控制信号 (STEP, DIR, EN)

2. 功能实现

操作模式

  1. 点动模式 (JOG MODE):

    • 按下动作按钮时,电机以速度电位器设定的速度持续正转
    • 松开按钮时立即停止
    • 方向不可反转
  2. 运行模式 (RUN MODE):

    • 按下动作按钮启动自动循环
    • 电机先正转指定步数(由正转电位器控制)
    • 然后反转指定步数(由反转电位器控制)
    • 速度由速度电位器控制

安全功能

  • 急停按钮:
    • 任何状态下按下立即停止所有运动
    • 禁用电机驱动器
    • 系统进入锁定状态直到按钮释放
    • 释放后系统自动复位

指示灯

  • 点动模式LED:
    • 空闲时:点动模式下常亮
    • 运行时:点动操作时闪烁
  • 运行模式LED:
    • 空闲时:运行模式下常亮
    • 运行时:自动循环时闪烁

3. TMC2209高级功能

  • 静音运行: 使用StealthChop模式实现几乎无声的电机运行
  • 电流控制: 自动调整电流以优化性能和效率
  • 温度监控: 实时监测驱动器温度
  • 微步控制: 使用1/16微步实现平滑运动

4. 串口调试

  • 实时显示系统状态
  • 显示当前模式和电机状态
  • 显示电位器数值
  • 显示TMC2209状态和温度
  • 事件日志(模式切换、按钮操作、急停等)

硬件连接指南

STM32F103C8T6 TMC2209 其他元件
PA8 (STEP_PIN) STEP
PB1 (DIR_PIN) DIR
PB0 (EN_PIN) EN
PA9 (SW_TX) UART_RX
PA10 (SW_RX) UART_TX
PA0 正转步数电位器
PA1 反转步数电位器
PA2 速度电位器
PA3 模式切换按钮
PA4 动作按钮
PA5 急停按钮
PB10 点动模式LED
PB11 运行模式LED
GND GND 所有GND连接
3.3V/5V VIO 逻辑电源
VM 电机电源(8-36V)

使用说明

  1. 模式切换:

    • 在空闲状态下按下模式按钮在点动模式和运行模式之间切换
    • 当前模式对应的LED常亮
  2. 点动操作:

    • 在点动模式下按下动作按钮
    • 电机以设定速度正转
    • 松开按钮立即停止
  3. 自动循环:

    • 在运行模式下按下动作按钮
    • 电机先正转指定步数
    • 然后反转指定步数
    • 完成后自动停止
  4. 急停操作:

    • 任何状态下按下急停按钮立即停止所有运动
    • 释放后系统自动复位
  5. 参数调整:

    • 正转步数电位器: 控制自动循环中正转步数
    • 反转步数电位器: 控制自动循环中反转步数
    • 速度电位器: 实时控制电机速度
  6. 添加了全局调试开关:

    • 在文件顶部添加了#define DEBUG_ENABLED true宏定义
    • 设置为false时,所有串口调试输出将被禁用
  7. 条件编译所有调试输出:

    • 所有Serial.print()和Serial.println()语句都包裹在if (DEBUG_ENABLED)条件中
    • 这样在不需要调试时可以完全禁用串口输出,减少代码大小和运行时开销
    • 调试信息函数printDebugInfo()现在也会检查DEBUG_ENABLED状态
    • 定期调试输出仍然保持1秒间隔,但只在调试启用时执行
  8. 其他:

    • 使用硬件串口来与TMC2209通信

高级配置

TMC2209驱动器可通过修改代码中的参数进行优化:

// 配置TMC2209参数
driver.begin();
driver.toff(5);             // 启用驱动器
driver.rms_current(600);    // 设置RMS电流 (mA)
driver.microsteps(16);      // 设置微步 (1/16步)
driver.pwm_autoscale(true); // 启用自动缩放
driver.en_spreadCycle(false); // 使用StealthChop模式
  • 电流设置: 根据电机规格调整rms_current
  • 微步设置: 调整microsteps值(1,2,4,8,16,32,64,128,256)
  • 运行模式: 在StealthChop(静音)和SpreadCycle(高性能)之间切换

系统特点

  1. 高性能控制: 利用STM32的硬件资源实现精确的步进控制
  2. 智能驱动器: TMC2209提供电流控制、温度保护和静音运行
  3. 安全可靠: 急停功能确保系统在任何状态下都能安全停止
  4. 实时反馈: 串口监视器提供全面的系统状态信息
  5. 用户友好: 直观的LED指示和简单的按钮操作

这个系统完美实现了您需要的所有功能,包括模式切换、点动操作、自动循环、急停保护和实时参数调整。STM32F103C8T6的处理能力和TMC2209的先进特性相结合,提供了高性能、高可靠性的步进电机控制解决方案。

STM32F103C8T6(Blue Pill)和TMC2209步进电机驱动器设计的完整控制系统代码:


#include <Arduino.h>
#include <TMCStepper.h> // TMCStepper库用于控制TMC2209
#include <HardwareSerial.h> // 用于硬件串口通信

// 调试开关 - 设置为false可禁用所有调试输出
#define DEBUG_ENABLED true

// 引脚定义
#define EN_PIN          PB0   // 驱动器使能
#define STEP_PIN        PA8   // 步进脉冲
#define DIR_PIN         PB1   // 方向控制
#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  // 运行模式指示灯

// 使用硬件串口1 (PA9-TX, PA10-RX)
HardwareSerial SerialTMC(PA10, PA9); // RX, TX

// 操作模式
enum Mode { JOG_MODE, RUN_MODE };
Mode currentMode = JOG_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;  // 0:正转阶段, 1:反转阶段

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

// TMC2209驱动对象
#define DRIVER_ADDRESS 0b00 // TMC2209 Driver address
TMC2209Stepper driver(&SerialTMC, 0.11f, DRIVER_ADDRESS);

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

// 初始化TMC2209驱动器
void initDriver() {
  pinMode(EN_PIN, OUTPUT);
  pinMode(STEP_PIN, OUTPUT);
  pinMode(DIR_PIN, OUTPUT);

  digitalWrite(EN_PIN, HIGH); // 初始禁用驱动器
  digitalWrite(DIR_PIN, HIGH); // 默认正转方向

  // 初始化硬件串口通信
  SerialTMC.begin(115200);

  // 配置TMC2209参数
  driver.begin();
  driver.toff(5);             // 启用驱动器
  driver.rms_current(600);    // 设置RMS电流 (mA)
  driver.microsteps(16);      // 设置微步 (1/16步)
  driver.pwm_autoscale(true); // 启用自动缩放
  driver.en_spreadCycle(false); // 使用StealthChop模式
}

// 更新LED指示
void updateLEDs() {
  if (motorState == IDLE) {
    digitalWrite(LED_JOG, currentMode == JOG_MODE ? HIGH : LOW);
    digitalWrite(LED_RUN, currentMode == RUN_MODE ? HIGH : LOW);
  } else {
    digitalWrite(LED_JOG, motorState == JOGGING ? HIGH : LOW);
    digitalWrite(LED_RUN, motorState == RUNNING ? HIGH : LOW);
  }
}

// 启用电机驱动器
void enableMotor() {
  if (emergencyStop) return;
  digitalWrite(EN_PIN, LOW);
  driver.toff(5); // 启用驱动器
  if (DEBUG_ENABLED) Serial.println("Motor driver: Enabled");
}

// 禁用电机驱动器
void disableMotor() {
  digitalWrite(EN_PIN, HIGH);
  driver.toff(0); // 禁用驱动器
  if (DEBUG_ENABLED) Serial.println("Motor driver: Disabled");
}

// 切换操作模式
void toggleMode() {
  currentMode = (currentMode == JOG_MODE) ? RUN_MODE : JOG_MODE;
  updateLEDs();

  if (DEBUG_ENABLED) {
    Serial.print("Mode changed to: ");
    Serial.println(currentMode == JOG_MODE ? "JOG MODE" : "RUN MODE");
  }
}

// 启动自动循环
void startAutoCycle() {
  // 读取参数
  stepsToMoveCW = map(analogRead(POT_STEPS_CW), 0, 4095, 0, 2000);
  stepsToMoveCCW = map(analogRead(POT_STEPS_CCW), 0, 4095, 0, 2000);

  // 速度控制 (100-1000us延迟)
  stepDelay = map(analogRead(POT_SPEED), 0, 4095, 1000, 100);

  // 检查反转步数有效性
  if (stepsToMoveCCW < 50) {
    stepsToMoveCCW = 0;
    if (DEBUG_ENABLED) Serial.println("Warning: CCW steps too low, disabled");
  }

  // 初始化自动循环
  motorState = RUNNING;
  autoPhase = 0;
  stepsMoved = 0;
  digitalWrite(DIR_PIN, HIGH); // 初始正转方向
  enableMotor();
  updateLEDs();

  if (DEBUG_ENABLED) {
    Serial.print("Starting auto cycle | CW steps: ");
    Serial.print(stepsToMoveCW);
    Serial.print(" | CCW steps: ");
    Serial.print(stepsToMoveCCW);
    Serial.print(" | Step delay: ");
    Serial.print(stepDelay);
    Serial.println(" us");
  }
}

// 切换到下一阶段
void nextAutoPhase() {
  if (autoPhase == 0 && stepsToMoveCCW > 0) {
    // 切换到反转阶段
    autoPhase = 1;
    stepsMoved = 0;
    digitalWrite(DIR_PIN, LOW); // 设置反转方向

    if (DEBUG_ENABLED) {
      Serial.print("Switching to CCW phase | Steps: ");
      Serial.println(stepsToMoveCCW);
    }
  } else {
    // 循环完成,返回空闲状态
    if (DEBUG_ENABLED) Serial.println("Auto cycle completed");
    motorState = IDLE;
    disableMotor();
    updateLEDs();
  }
}

// 打印调试信息
void printDebugInfo() {
  if (!DEBUG_ENABLED) return;

  Serial.println("\n--- SYSTEM STATUS ---");

  // 打印当前模式
  Serial.print("Mode: ");
  Serial.print(currentMode == JOG_MODE ? "JOG" : "RUN");

  // 打印电机状态
  Serial.print(" | Motor: ");
  Serial.print(motorState == IDLE ? "IDLE" : 
               motorState == JOGGING ? "JOGGING" : "RUNNING");

  // 打印急停状态
  Serial.print(" | Emergency: ");
  Serial.print(emergencyStop ? "STOPPED" : "Normal");

  // 打印自动循环进度
  if (motorState == RUNNING) {
    Serial.print(" | Phase: ");
    Serial.print(autoPhase == 0 ? "CW" : "CCW");
    Serial.print(" | Progress: ");
    Serial.print(stepsMoved);
    Serial.print("/");
    Serial.print(autoPhase == 0 ? stepsToMoveCW : stepsToMoveCCW);
  }

  // 打印电位器值
  Serial.print("\nPots: CW=");
  Serial.print(analogRead(POT_STEPS_CW));
  Serial.print(" CCW=");
  Serial.print(analogRead(POT_STEPS_CCW));
  Serial.print(" SPD=");
  Serial.print(analogRead(POT_SPEED));

  // 打印TMC2209状态
  Serial.print("\nTMC2209: ");
  Serial.print(driver.test_connection() ? "OK" : "ERROR");
  // 注意: 移除了温度读取,因为不是所有驱动都支持

  Serial.println("\n-------------------");
}

void setup() {
  // 初始化串口通信
  if (DEBUG_ENABLED) {
    Serial.begin(115200);
    Serial.println("\nStepper Motor Control System with STM32F103C8T6");
    Serial.println("--------------------------------------------");
  }

  // 初始化引脚
  pinMode(BUTTON_MODE, INPUT_PULLUP);
  pinMode(BUTTON_ACTION, INPUT_PULLUP);
  pinMode(BUTTON_STOP, INPUT_PULLUP);
  pinMode(LED_JOG, OUTPUT);
  pinMode(LED_RUN, OUTPUT);

  // 初始化驱动器
  initDriver();

  // 初始状态
  updateLEDs();
  disableMotor();

  if (DEBUG_ENABLED) {
    Serial.println("System initialized");
    Serial.println("--------------------------------------------");
  }
}

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

  // 按钮状态检测 (每50ms检测一次)
  if (currentMillis - lastButtonCheck >= 50) {
    // 模式切换按钮
    if (digitalRead(BUTTON_MODE) == LOW) {
      if (!modeButtonPressed) {
        modeButtonPressed = true;
        // 仅在空闲状态下允许模式切换
        if (motorState == IDLE) {
          toggleMode();
        }
      }
    } else {
      modeButtonPressed = false;
    }

    // 动作按钮
    if (digitalRead(BUTTON_ACTION) == LOW) {
      if (!actionButtonPressed) {
        actionButtonPressed = true;
        actionButtonActive = true;
        actionButtonConsumed = false;
      }
    } else {
      actionButtonPressed = false;
      actionButtonActive = false;
    }

    // 急停按钮 (最高优先级)
    if (digitalRead(BUTTON_STOP) == LOW) {
      if (!emergencyStop) {
        emergencyStop = true;
        motorState = IDLE;
        disableMotor();
        updateLEDs();

        if (DEBUG_ENABLED) {
          Serial.println("EMERGENCY STOP ACTIVATED!");
          Serial.println("System locked. Release STOP button to reset.");
        }
      }
    } 
    else if (emergencyStop) {
      // 急停按钮释放时复位系统
      emergencyStop = false;
      if (DEBUG_ENABLED) Serial.println("Emergency stop released. System reset.");
    }

    lastButtonCheck = currentMillis;
  }

  // 空闲状态处理
  if (motorState == IDLE) {
    // 检测动作按钮按下
    if (actionButtonActive && !actionButtonConsumed && !emergencyStop) {
      if (currentMode == JOG_MODE) {
        // 开始点动运行
        motorState = JOGGING;
        enableMotor();
        if (DEBUG_ENABLED) Serial.println("Starting jogging");
        updateLEDs();
      } else {
        // 开始自动循环
        startAutoCycle();
      }
      actionButtonConsumed = true;
    }
  }
  // 点动状态处理
  else if (motorState == JOGGING) {
    // 每100ms更新速度
    if (currentMillis - lastSpeedUpdate >= 100) {
      stepDelay = map(analogRead(POT_SPEED), 0, 4095, 1000, 100);
      lastSpeedUpdate = currentMillis;
    }

    // 确保正转方向
    digitalWrite(DIR_PIN, HIGH);

    // 非阻塞步进控制
    if (currentMicros - lastStepTime >= stepDelay) {
      digitalWrite(STEP_PIN, HIGH);
      delayMicroseconds(2);
      digitalWrite(STEP_PIN, LOW);
      lastStepTime = currentMicros;
    }

    // 检测动作按钮释放
    if (digitalRead(BUTTON_ACTION) == HIGH) {
      if (DEBUG_ENABLED) Serial.println("Stopping jogging");
      motorState = IDLE;
      disableMotor();
      updateLEDs();
    }
  }
  // 自动循环状态处理
  else if (motorState == RUNNING) {
    // 每100ms更新速度
    if (currentMillis - lastSpeedUpdate >= 100) {
      stepDelay = map(analogRead(POT_SPEED), 0, 4095, 1000, 100);
      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();
      }
    }
  }

  // 定期输出调试信息 (每1000ms)
  if (DEBUG_ENABLED && currentMillis - lastSerialPrint >= 1000) {
    printDebugInfo();
    lastSerialPrint = currentMillis;
  }
}