2026/8/29 4:17:27

如何自制一款丝杆滑台?

如何自制一款丝杆滑台? 这篇文章解决一个问题网上步进电机的教程一大堆但没几个把“电机转起来”和“平台精确到位”说清楚。用42步进电机做丝杆滑台你会立刻撞上开环控制的三个坑丢步、回程间隙、联轴器打滑。本文从开环一路做到闭环提升重复定位精度再接入大夏龙雀 DX-NR11 2.4G 无线串口模组让平台支持远程遥控——一套“精确定位 无线控制”的完整闭环系统。适用对象会用 STM32CubeMX / HAL 库、想玩机电一体化的学生和创客。你会得到完整接线、脉冲当量计算、开环 / 闭环 C 代码、实测数据表、踩坑清单。前置条件STM32F405RGT6 最小系统板 HAL 库基础机械部分可直接用成品丝杆滑台。项目背景为什么开环的丝杆滑台“不听话”很多人以为“发了 N 个脉冲滑台就该走 N 步”。实际工程里根本不是这样主要误差源有三个失步丢步电机启动加速度太大、负载过重或速度超过矩频特性转子跟不上脉冲直接丢步——脉冲发出去了轴没转。回程间隙丝杆和螺母之间有间隙换向时先空转一段才带动工作台造成“正着走准、反着走偏”。传动打滑刚性不够时电机轴转了丝杆端没跟上。所以开环只能“大概准”。要真正精确就得把实际位置量出来反馈给单片机做闭环——这就是本项目的核心。硬件清单与接线电子硬件清单部件型号 / 规格作用主控STM32F405RGT6 最小系统板控制核心步进电机42BYGH1.8°两相四线驱动丝杆驱动器TB6600脉冲 → 驱动电流丝杆滑台T8 丝杆导程 8mm 光轴×2 滑块直线进给机构限位开关轻触开关 ×2回零磁编码器AS5600 模块丝杆转角反馈磁铁径向充磁圆磁铁 D6配合 AS5600通信模块DX-NR11-24T12S2.4G 无线串口无线遥控电源12V 3A驱动供电线材杜邦线、接线端子连接引脚定义STM32 引脚连接对象说明PA0TIM2_CH1 → TB6600 PUL步进脉冲硬件 PWMPB0TB6600 DIR运动方向PB1TB6600 ENA使能低有效PB12左限位开关回零原点PB13右限位开关行程保护PB6I2C1 SCLAS5600 OLEDI2C 时钟总线共用PB7I2C1 SDAAS5600 OLEDI2C 数据总线共用PA2USART2 TX → NR11 RXD串口发送3.3V 直连PA3USART2 RX ← NR11 TXD串口接收无线命令系统架构执行链是“STM32发脉冲 → TB6600 驱动 → 步进电机 → 丝杆 → 工作台”反馈链是“丝杆转角 → AS5600 磁编码器 → 主控”构成位置闭环。限位开关负责回零和防撞。此外STM32 的串口接一块DX-NR11 2.4G 无线串口模组遥控端的 NR11电脑 USB-TTL通过 2.4G 空中链路与滑台端透传命令帧实现远程定位、回零与坐标回读——本地闭环 无线遥控就是这套平台的核心功能。关键参数脉冲当量怎么算先做开环让滑台按脉冲走开环的核心是“用定时器、硬件 PWM 按固定频率输出 PUL 脉冲”。代码如下// CubeMX 配置TIM2 通道1 PWM 输出到 PA0预分频 0 // TIM2 时钟 APB1×2 84MHzPWM 频率 84MHz / (ARR1) volatile uint32_t pulse_remain; // 剩余脉冲数 volatile uint8_t is_moving; // 运动标志 // TIM2 的 CC 中断每个 PWM 周期 1 个脉冲 void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim) { if (htim-Instance TIM2) { if (pulse_remain 0) { pulse_remain--; if (pulse_remain 0) { is_moving 0; HAL_TIM_PWM_Stop_IT(htim2, TIM_CHANNEL_1); // 停发脉冲 } } } } // 设置脉冲频率Hz void step_set_freq(uint32_t freq_hz) { uint32_t arr 84000000UL / freq_hz - 1; __HAL_TIM_SET_AUTORELOAD(htim2, arr); __HAL_TIM_SET_COMPARE(htim2, TIM_CHANNEL_1, arr / 2); // 50% 占空比 } // 按步数运动 void move_steps(int32_t steps, uint32_t freq_hz) { if (steps 0) return; HAL_GPIO_WritePin(DIR_GPIO_Port, DIR_Pin, (steps 0) ? GPIO_PIN_SET : GPIO_PIN_RESET); pulse_remain (steps 0) ? steps : -steps; step_set_freq(freq_hz); is_moving 1; HAL_TIM_PWM_Start_IT(htim2, TIM_CHANNEL_1); // 开 PWM 并开中断 while (is_moving); // 阻塞等待 }回零逻辑启动时向负方向低速走直到触发左限位PB12把当前位置记为原点同时清零 AS5600 累计值。闭环改造AS5600 磁编码器反馈为什么反馈装在丝杆上而不是电机上装在电机轴上只能证明“电机转了”证明不了“丝杆转了”。联轴器打滑、丝杆间隙都不会在电机端体现所以必须测最终输出——丝杆转角。AS5600 安装3D 打印一个小支架把径向充磁的圆磁铁粘在丝杆末端AS5600 模块正对磁铁固定在支架上。上电后用串口打印原始角度转动丝杆确认读数连续变化、无跳变。读取与多圈累计// CubeMX 配置I2C1PB6SCL / PB7SDA标准模式 100kHz // AS5600 地址 0x36OLED 地址 0x3C共用同一总线 #define AS5600_ADDR 0x36 #define REG_ANGLE 0x0C // RAW ANGLE (12bit) uint16_t as5600_read(void) { uint8_t reg REG_ANGLE; uint8_t buf[2]; HAL_I2C_Master_Transmit(hi2c1, (AS5600_ADDR 1), reg, 1, 10); HAL_I2C_Master_Receive (hi2c1, (AS5600_ADDR 1) | 1, buf, 2, 10); return ((uint16_t)buf[0] 8 | buf[1]) 0x0FFF; } // 多圈累计 static uint16_t last_angle; volatile int32_t total_cnt; void sample_position(void) { uint16_t a as5600_read(); int16_t diff (int16_t)(a - last_angle); if (diff 2048) diff - 4096; // 跨零回绕 if (diff -2048) diff 4096; total_cnt diff; last_angle a; }位置环误差补脉冲 回程间隙补偿#define PULSE_PER_CNT (3200.0f / 4096.0f) // 1 个编码器计数 ≈ 0.78 个脉冲 volatile int32_t target_cnt; // 目标位置 volatile int32_t act_cnt; // 实际位置 #define DEAD_ZONE 3 void position_loop(void) { sample_position(); act_cnt total_cnt; int32_t err target_cnt - act_cnt; if (err DEAD_ZONE || err -DEAD_ZONE) { int32_t need (int32_t)(err * PULSE_PER_CNT); move_steps(need, 300); // 低速补齐 } } #define BACKLASH_CNT 52 // 标定值 static uint8_t last_dir 0; void backlash_comp(uint8_t dir) { if (dir ! last_dir) { int32_t gap dir ? BACKLASH_CNT : -BACKLASH_CNT; move_steps((int32_t)(gap * PULSE_PER_CNT), 200); } last_dir dir; }主循环里周期性调用position_loop()把目标位置与实测位置之差换算成脉冲补上去直到误差进入死区。间隙补偿在每次换向前先“预走”一个实测间隙量。闭环实测测试项命令位移 (mm)实测位移 (mm)正向 1010.00010.002正向 2020.00019.998正向 3030.00030.004高速 (2000pps) 2020.00020.011往返重复定位 ×10回到 0≤0.018结论闭环后高速丢步被拉回20.011mm重复定位从 ±0.1mm 级别收敛到 ≤0.02mm。对 2.5μm 理论分辨率来说剩余误差主要来自丝杆本身的间隙与 AS5600 的标定误差。自制STM32F405RGT6核心板设计最小系统板原理图实拍图无线遥控NR11 2.4G 远程控制定位闭环只解决了“本地精确”要让这台平台真正“有用”还得能远程控制。这里引入大夏龙雀DX-NR11-24T12S一块 2.4G 无线串口模组板载 PCB 天线、半双工、默认 9600 波特率透明传输空旷距离可达 200m。滑台端一块 NR11 接 STM32 的串口遥控端再放一块 NR11电脑 USB-TTL或与 BT121 桥接连手机两端同信道同地址即可透传——STM32 端解析命令帧执行定位再把坐标回传。接线与电平匹配NR11 是 3.3V 逻辑器件供电 2.5~3.6V典型 3.3VSTM32F405 同为 3.3V电平天然匹配TXD、RXD 直连即可连接说明STM32 PA2USART2_TX→ NR11 RXD同为 3.3V 电平直连STM32 PA3USART2_RX← NR11 TXD3.3V 电平直连NR11 VCC接 STM32 板 3.3VNR11 GND与 STM32 共地NR11 直接取 STM32 板的 3.3V 电源即可注意 NR11 模块供电超过 3.6V 有烧毁风险。模块配置AT 指令两端模块出厂默认射频参数一致空中速率 2Mbps、信道 000、地址 10,11不改也能直接透传要换信道、地址隔离干扰进入 AT 模式配置通信协议自定义帧透明传输只负责“传字节”协议要自己定。这里用 6 字节定长帧末尾带校验防误触发字段长度说明0xAA 0x552B帧头CMD1B命令码D1 D22B参数目标位置单位 0.01mmSUM1B校验AA^55^CMD^D1^D2CMD功能参数0x01回零无0x02定位D1D2 目标位置 ×1000.01mm0x03查询位置无回传坐标帧0x04急停无例定位到 20.00mm目标值 2000 0x07D0命令帧为AA 55 02 07 D0 2ASUM AA^55^02^07^D0 0x2A。STM32 端程序STM32 用 USART2 接收接收用状态机逐字节解析帧头、命令和校验// CubeMX 配置USART2PA2TX / PA3RX9600, 8, N, 1 volatile uint8_t rx_byte; uint8_t rx_state 0; // 接收状态机 uint8_t rx_cmd, rx_d1, rx_d2; void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart-Instance USART2) { uint8_t c rx_byte; switch (rx_state) { case 0: rx_state (c 0xAA) ? 1 : 0; break; case 1: rx_state (c 0x55) ? 2 : 0; break; case 2: rx_cmd c; rx_state 3; break; case 3: rx_d1 c; rx_state 4; break; case 4: rx_d2 c; rx_state 5; break; case 5: if ((0xAA ^ 0x55 ^ rx_cmd ^ rx_d1 ^ rx_d2) c) handle_cmd(rx_cmd, (uint16_t)(rx_d1 8 | rx_d2)); rx_state 0; break; } HAL_UART_Receive_IT(huart2, rx_byte, 1); // 继续接收 } } void uart_send(uint8_t c) { HAL_UART_Transmit(huart2, c, 1, 10); }效果验证电脑端串口助手sscom接 USB-TTL NR11发一帧AA 55 02 07 D0 2A滑台走到 20.00mm 并回传坐标。开发记录AS5600 读数跳变磁铁偏心或用了轴向充磁换成径向充磁磁铁并确保对中。TB6600 大电流时主控复位主控与驱动分电源供电、共地。限位开关必须接第一次调试把最大速度调低限位触发立即停防止撞机顶坏丝杆。NR11 是 3.3V 器件不能 5V 直供与 STM32 同为 3.3V 电平TXD / RXD 直连即可。NR11同信道同地址才能通信两端射频参数不一致就“静默”先发 AT 确认模块在线。天线避开金属NR11 用板载天线别贴金属外壳或大面积铺铜天线方向留至少 5mm 净空。