Journal Article

42步进电机驱动板:STM32 + TB67H450 + MT6816 全栈方案

基于STM32F103CBT6的42步进电机驱动板设计方案,采用TB67H450FNG双路有刷电机驱动器 + MT6816磁编码器闭环反馈,配套Qt桌面调试上位机,支持电流/速度/位置三种控制模式,具备堵转保护与自恢复机制。

17 min6 views

42步进电机驱动板:STM32 + TB67H450 + MT6816 全栈方案

项目概述

本项目是一套完整的42步进电机一体式驱动板设计方案,涵盖硬件原理图、PCB Layout、BOM物料清单、下位机固件和 Windows 桌面调试上位机。采用 STM32F103CBT6 作为主控,搭配 TB67H450FNG 双路电机驱动器和 MT6816 磁编码器实现闭环反馈控制。

项目系统概览

PCB布局与原理图

PCB 版图 & 原理图

PCB正面

PCB背面及走线

原理图局部

原理图完整版

3D渲染图

3D渲染图背面


核心功能指标

运动控制

c
// 控制模式
enum MotorMode {
    MODE_CURRENT,   // 电流模式: c <float>
    MODE_SPEED,     // 速度模式: v <float>
    MODE_POSITION,  // 位置模式: p <float>
    MODE_STOP,      // 紧急停止: s
    MODE_CLEAR,     // 清除堵转: l
    MODE_ZERO       // 位置归零: z
};
功能参数说明
转速范围0–20 RPM步长 0.1 RPM 连续可调
微步细分128/256微步200×256=51200 微步/圈
运行模式正转/反转/交替/随机时间、方向可自定义
堵转保护自动反转重试防止卡死

0.1 RPM 低速控制分析

以 0.1 RPM 为例,每秒仅旋转 0.6°。使用 256 微步时:

  • 总微步数:200 × 256 = 51200 微步/圈
  • 10分钟走一圈:51200 ÷ 600s ≈ 85 微步/s
c
// 速度转换
#define FULL_STEPS_PER_REV   200
#define MICROSTEPS          256
#define PULSES_PER_REV      (FULL_STEPS_PER_REV * MICROSTEPS)  // 51200

float speed_to_pulse_rate(float rpm) {
    float rps = rpm / 60.0f;
    return rps * PULSES_PER_REV;  // 脉冲频率计算
}

硬件方案

BOM 物料清单

序号器件型号数量封装
1主控 MCUSTM32F103CBT61LQFP-48
2电机驱动TB67H450FNG2HSOP-8
3磁编码器MT6816CT-ACD1SOP-8
4USB转串口CH340C1SOP-16
5LDO 3.3VLP2992IM5-3.31SOT-23-5
6DC-DCME3116AM6G1SOT-23-6
7TVS管SMBJ28CA1SMB
8肖特基二极管SS541SMA
9保险丝0.5A 自恢复1F0805
10功率电感6.8uH12016封装
11晶振12MHz15032封装
12USB-A母座SHOU HAN1直插
13电机接口XH-4AW1直插4P
14接线端子KF128-2.54-2P1直插
15按键3x4x2 SMD2SMD
16LED指示灯黄色/绿色20603
17电流采样电阻100mΩ 120621206
18低阻采样电阻1mΩ 060320603

核心器件详解

STM32F103CBT6(主控)

  • ARM Cortex-M3 @ 72MHz
  • 128KB Flash / 20KB SRAM
  • 2×12位 ADC(1µs转换,16通道):检测电流突变判断堵转
  • 7通道 DMA:定时器 + ADC + SPI + I²C + USART
  • 3×USART:用于串口通信 + CH340C USB转串口

TB67H450FNG(双路驱动)

  • PWM 斩波式直流有刷电机驱动器
  • 单通道输出,最大电流 3A
  • 内置过流/过热保护
  • 双路配置:分别驱动 A 相和 B 相线圈
code
         ┌──────────┐
  PWM_A →│TB67H450  │→ A+ / A-
  PHASE_A→│  (U4)   │
         └──────────┘
         ┌──────────┐
  PWM_B →│TB67H450  │→ B+ / B-
  PHASE_B→│  (U5)   │
         └──────────┘

MT6816CT-ACD(磁编码器)

  • 非接触式磁性编码器
  • 增量式 ABZ 输出 + 绝对位置
  • SPI 接口读取角度
  • 检测丢步/堵转,实现闭环补偿
c
// 磁编码器读取角度
uint16_t read_magnetic_angle(void) {
    uint16_t angle;
    SPI_CS_LOW();
    SPI_SendByte(MT6816_READ_CMD);
    angle = (SPI_ReadByte() << 8) | SPI_ReadByte();
    SPI_CS_HIGH();
    return angle;
}

// 堵转检测
bool is_stalled(uint16_t target_angle, uint16_t current_angle) {
    static uint16_t stall_count = 0;
    if (abs(target_angle - current_angle) < STALL_THRESHOLD) {
        stall_count++;
    } else {
        stall_count = 0;
    }
    return stall_count > STALL_TIMEOUT;  // 连续多个周期无位移
}

通信协议

上位机 → 下位机(控制指令)

命令格式示例说明
电流模式c <float>c 1.5设定目标电流 (A)
速度模式v <float>v 100设定目标转速 (R/s)
位置模式p <float>p 360设定目标位置 (圈)
停止ss紧急停止电机
清除堵转ll清除堵转标志
归零zz位置编码器归零
自定义<任意字符串>help透传,用于调试

下位机 → 上位机(数据上报)

帧格式T:<pos>,<vel>,<cur>\n

字段含义单位示例值
pos当前位置圈数 (R)360.00
vel当前转速圈/秒 (R/s)100.50
cur当前电流安培 (A)1.25

示例帧T:360.00,100.50,1.25

上位机按 \n 分帧解析,以 T: 识别为有效数据帧:

cpp
// Qt 串口解析
void MainWindow::parseSerialData() {
    buffer += serial.readAll();
    while (true) {
        int idx = buffer.indexOf("\n");
        if (idx == -1) break;
        QString frame = buffer.left(idx);
        buffer.remove(0, idx + 1);
        
        if (frame.startsWith("T:")) {
            QStringList parts = frame.mid(2).split(",");
            if (parts.size() == 3) {
                double pos = parts[0].toDouble();
                double vel = parts[1].toDouble();
                double cur = parts[2].toDouble();
                updateDisplay(pos, vel, cur);
            }
        }
    }
}

堵转保护机制

c
// 堵转检测与自恢复
typedef struct {
    float current_threshold;  // 电流阈值 (A)
    float current_prev;       // 上一次电流值
    uint8_t stall_cnt;        // 堵转计数
    uint8_t retry_cnt;        // 重试次数
    bool  is_stalled;         // 堵转标志
} MotorSafety;

void motor_safety_check(MotorSafety *ms) {
    float current = read_motor_current();
    
    // 电流突变检测 (ADC + DMA)
    if (fabsf(current - ms->current_prev) > CURRENT_DELTA_THRESHOLD) {
        ms->stall_cnt++;
    } else {
        ms->stall_cnt = 0;
    }
    ms->current_prev = current;
    
    // 判断堵转
    if (ms->stall_cnt > STALL_COUNT_THRESHOLD) {
        ms->is_stalled = true;
        motor_stop();                          // 急停
        delay_ms(200);                        // 等待
        motor_reverse(STALL_REVERSE_ANGLE);   // 反转一定角度
        ms->stall_cnt = 0;
        ms->retry_cnt++;
    }
    
    // 连续堵转保护
    if (ms->retry_cnt > MAX_RETRY_COUNT) {
        motor_power_off();  // 断电保护
        ms->retry_cnt = 0;
    }
}

真随机数生成

STM32F103CBT6 无硬件 RNG,本方案采用 ADC 悬空引脚捕获白噪声:

c
// ADC 噪声采集法
uint32_t generate_true_random(void) {
    ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_239Cycles5);
    
    uint32_t noise = 0;
    for (int i = 0; i < 4; i++) {
        ADC_SoftwareStartConvCmd(ADC1, ENABLE);
        while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
        noise = (noise << 8) | (ADC_GetConversionValue(ADC1) & 0xFF);
    }
    return noise;
}

// 生成随机延时/方向
void random_mode_control(void) {
    uint32_t rand_val = generate_true_random();
    uint32_t delay_ms = (rand_val % RANDOM_PERIOD_MAX) + RANDOM_PERIOD_MIN;
    bool direction = (rand_val & 0x10000000) ? MOTOR_CW : MOTOR_CCW;
    
    motor_run(direction, RANDOM_SPEED);
    vTaskDelay(pdMS_TO_TICKS(delay_ms));
}

上下位机系统架构

code
┌────────────────────────────────────────┐
│          Windows 桌面软件 (Qt C++)       │
│  ┌─────────┐ ┌─────────┐ ┌──────────┐ │
│  │ 用户系统  │ │ 设备管理 │ │ 数据管理  │ │
│  │注册/登录 │ │绑定/在线│ │Excel导出 │ │
│  └─────────┘ └─────────┘ └──────────┘ │
│  ┌──────────────────────────────────┐  │
│  │     串口通信 (Windows API)        │  │
│  └──────────────────────────────────┘  │
├────────────────────────────────────────┤
│              USB (CH340C)              │
├────────────────────────────────────────┤
│          42步进电机驱动板               │
│  ┌──────────────────────────────────┐  │
│  │  STM32F103CBT6 (ARM Cortex-M3)   │  │
│  │  - 电机控制算法                    │  │
│  │  - ADC 电流检测                   │  │
│  │  - 磁编码器 SPI 读取              │  │
│  │  - 串口协议解析                   │  │
│  └──────┬───────────────┬───────────┘  │
│  ┌──────┴──────┐ ┌──────┴──────┐      │
│  │TB67H450(U4) │ │TB67H450(U5)│        │
│  │  A相驱动    │ │  B相驱动    │        │
│  └──────┬──────┘ └──────┬──────┘      │
│         └───────┬───────┘              │
│          ┌──────┴──────┐              │
│          │ 42步进电机  │              │
│          │  MT6816磁编 │              │
│          └─────────────┘              │
└────────────────────────────────────────┘

Qt 上位机功能

code
┌───────────┬────────────────────────────┐
│  设备连接  │ 串口号 / 波特率 / 连接状态  │
├───────────┼────────────────────────────┤
│  运动控制  │ 正转 / 反转 / 停止         │
│           │ 转速滑块 (0-20 RPM)         │
│           │ 模式选择 (速度/位置/电流)    │
├───────────┼────────────────────────────┤
│  实时数据  │ 当前位置: 360.00 R         │
│           │ 当前转速: 100.50 R/s        │
│           │ 当前电流: 1.25 A            │
├───────────┼────────────────────────────┤
│  波形显示  │ 速度曲线 / 电流曲线         │
├───────────┼────────────────────────────┤
│  数据导出  │ Excel 格式 (可编辑/保存)    │
└───────────┴────────────────────────────┘

调试上位机样例


BOM 物料汇总

71 个元器件,32 种规格:

类型数量典型物料
电阻201kΩ×7, 10kΩ×4, 100mΩ×2, 1mΩ×2
电容28100nF×17, 10uF×4, 100uF×4
IC6STM32, TB67H450×2, MT6816, LP2992, ME3116
二极管4SS54, SMBJ28CA, 5819WS×2
接口4XH-4AW, KF128, USB-A, PZ254V
开关2按键 3×4×2
其他7晶振, 电感, 保险丝, LED×2, 螺丝×4

总结

这是一套完整的步进电机驱动方案,覆盖全栈技术点:

  1. 硬件设计:原理图 + PCB + BOM,嘉立创 EDA 设计
  2. MCU 控制:STM32F103CBT6,PID 速度环/位置环控制
  3. 功率驱动:TB67H450FNG 双路 PWM 斩波,3A 输出
  4. 闭环反馈:MT6816 磁编码器,检测丢步与堵转
  5. 堵转保护:ADC 电流突变检测 + 自动反转重试
  6. 真随机数:ADC 悬空引脚白噪声采集
  7. 上位机:Qt C++ 桌面软件,串口通信 + Excel 数据导出
  8. 通信协议:ASCII 文本帧 T:pos,vel,cur\n,易于调试