介绍:
本代码为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. 功能实现
操作模式
-
点动模式 (JOG MODE):
- 按下动作按钮时,电机以速度电位器设定的速度持续正转
- 松开按钮时立即停止
- 方向不可反转
-
运行模式 (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) |
使用说明
-
模式切换:
- 在空闲状态下按下模式按钮在点动模式和运行模式之间切换
- 当前模式对应的LED常亮
-
点动操作:
- 在点动模式下按下动作按钮
- 电机以设定速度正转
- 松开按钮立即停止
-
自动循环:
- 在运行模式下按下动作按钮
- 电机先正转指定步数
- 然后反转指定步数
- 完成后自动停止
-
急停操作:
- 任何状态下按下急停按钮立即停止所有运动
- 释放后系统自动复位
-
参数调整:
- 正转步数电位器: 控制自动循环中正转步数
- 反转步数电位器: 控制自动循环中反转步数
- 速度电位器: 实时控制电机速度
-
添加了全局调试开关:
- 在文件顶部添加了#define DEBUG_ENABLED true宏定义
- 设置为false时,所有串口调试输出将被禁用
-
条件编译所有调试输出:
- 所有Serial.print()和Serial.println()语句都包裹在if (DEBUG_ENABLED)条件中
- 这样在不需要调试时可以完全禁用串口输出,减少代码大小和运行时开销
- 调试信息函数printDebugInfo()现在也会检查DEBUG_ENABLED状态
- 定期调试输出仍然保持1秒间隔,但只在调试启用时执行
-
其他:
- 使用硬件串口来与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(高性能)之间切换
系统特点
- 高性能控制: 利用STM32的硬件资源实现精确的步进控制
- 智能驱动器: TMC2209提供电流控制、温度保护和静音运行
- 安全可靠: 急停功能确保系统在任何状态下都能安全停止
- 实时反馈: 串口监视器提供全面的系统状态信息
- 用户友好: 直观的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;
}
}