从台达伺服到STM32:手把手搭建二维移动平台控制原型
在工业自动化与创客项目中,二维移动平台是最基础也最实用的机械结构之一。无论是3D打印机、激光雕刻机还是简单的XY绘图仪,其核心都是通过两个轴向的协同运动实现精准定位。本文将带你从零开始,用STM32单片机驱动台达伺服电机,构建一个完整的二维移动平台控制原型。
这个项目最有趣的部分在于,我们不仅实现了基本的电机控制,还设计了一套完整的串口指令系统。通过简单的文本命令,你可以让平台移动到指定坐标、调整运动速度,甚至实时监控平台状态。下面让我们从硬件选型开始,逐步拆解这个系统的每个关键环节。
1. 硬件架构设计与选型
1.1 核心组件清单
构建一个可靠的二维移动平台,硬件选型直接影响最终的控制精度和系统稳定性。以下是经过实际验证的组件组合:
| 组件类别 | 型号规格 | 关键参数 |
|---|---|---|
| 主控制器 | STM32F103C8T6 | Cortex-M3内核,72MHz主频 |
| 伺服驱动器 | 台达ASD-B2-0421-B | 支持位置/速度/扭矩三模式 |
| 伺服电机 | ECMA-C20604RS | 400W,3000rpm,17位编码器 |
| 机械传动 | 滚珠丝杠+直线导轨 | 导程10mm,重复定位±0.02mm |
| 通信接口 | USB转TTL模块(CH340) | 支持115200bps波特率 |
提示:伺服电机与驱动器的匹配至关重要,务必确认额定电压和电流参数兼容。我们选择的ECMA-C20604RS电机与ASD-B2驱动器是台达的标准配套组合。
1.2 电气连接要点
硬件接线中最容易出错的是信号线的连接方式。伺服驱动器需要接收两路关键信号:
PWM脉冲信号:控制电机转动角度
- 连接STM32的TIM3_CH3(PB0)至驱动器的PULSE+
- 需串联200Ω限流电阻
方向电平信号:决定电机旋转方向
- 连接STM32的PA4至驱动器的SIGN+
- 驱动器侧的PULSE-和SIGN-需共接到GND
// GPIO初始化示例 void DIR_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_SetBits(GPIOA,GPIO_Pin_4); // 默认高电平 }2. 伺服驱动参数配置
2.1 驱动器关键参数设置
台达伺服驱动器需要通过面板设置以下参数才能正常工作:
- P1-01=0 (位置控制模式)
- P1-44=5000 (电子齿轮比分子)
- P1-45=1 (电子齿轮比分母)
- P2-10=1 (脉冲+方向控制方式)
- P2-15=100 (速度环增益)
注意:参数修改后必须断电重启才能生效。建议先用驱动器面板手动测试电机运转,确认基本功能正常后再连接单片机。
2.2 脉冲当量计算
在机械系统中,我们需要将物理位移转换为脉冲数。假设:
- 丝杠导程:10mm/转
- 驱动器设置:5000脉冲/转
- 则脉冲当量 = 10mm / 5000 = 0.002mm/脉冲
这意味着:
- 发送500个脉冲 → 电机转0.1圈 → 平台移动1mm
- 发送5000个脉冲 → 电机转1圈 → 平台移动10mm
// 计算移动距离对应的脉冲数 uint32_t calc_pulses(float distance_mm) { const float PULSE_PER_MM = 500.0f; // 500脉冲/mm return (uint32_t)(distance_mm * PULSE_PER_MM); }3. STM32软件架构设计
3.1 定时器PWM生成
我们使用TIM3产生PWM脉冲,关键配置如下:
- 时钟源:内部72MHz
- 预分频:39 → 计数频率=1.8MHz
- 自动重载值:359 → PWM频率=5kHz
- 占空比:50% (比较值=180)
void TIM3_PWM_Init(u16 arr, u16 psc) { TIM_OCInitTypeDef TIM_OCInitStructure; // ... 省略部分初始化代码 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC3Init(TIM3, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable); TIM_Cmd(TIM3, ENABLE); }3.2 运动控制状态机
二维平台的运动需要协调X/Y两个轴,我们采用状态机实现运动序列:
- IDLE:等待串口指令
- ACCEL:加速阶段
- CRUISE:匀速运动
- DECEL:减速停止
- DONE:运动完成
stateDiagram-v2 [*] --> IDLE IDLE --> ACCEL: 收到移动指令 ACCEL --> CRUISE: 达到目标速度 CRUISE --> DECEL: 剩余距离≤减速距离 DECEL --> DONE: 速度降为0 DONE --> IDLE: 运动完成4. 串口指令系统设计
4.1 指令协议格式
我们设计了一套简洁高效的指令系统,支持以下命令:
G0 X10 Y20:快速移动到(10,20)位置G1 X5 Y5 F1000:以1000mm/min速度直线移动到(5,5)M114:查询当前位置M203 S500:设置最大速度为500mm/min
指令解析流程:
- 接收完整行(以'\n'结尾)
- 校验校验和(可选)
- 提取命令字母(G/M)和参数
- 执行对应功能
4.2 缓冲区管理
使用环形缓冲区处理串口数据:
#define RX_BUF_SIZE 128 typedef struct { uint8_t buffer[RX_BUF_SIZE]; uint16_t head; uint16_t tail; } RingBuffer; void USART1_IRQHandler(void) { if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) { uint8_t ch = USART_ReceiveData(USART1); ringbuf.buffer[ringbuf.head] = ch; ringbuf.head = (ringbuf.head + 1) % RX_BUF_SIZE; } }5. 调试技巧与性能优化
5.1 实时监控实现
添加以下调试功能可大幅提高开发效率:
LED状态指示:
- LED1:PWM输出状态
- LED2:限位触发状态
串口调试输出:
printf("[Motor] X=%0.2f Y=%0.2f F=%d\n", current_pos.x, current_pos.y, feedrate);- 脉冲计数验证:
// 在定时器中断中计数 void TIM2_IRQHandler(void) { static uint32_t pulse_count = 0; pulse_count++; TIM_ClearITPendingBit(TIM2, TIM_IT_Update); }5.2 运动平滑处理
为避免启停时的机械冲击,采用S曲线加减速算法:
void calculate_s_curve(uint32_t total_pulses, uint32_t max_speed) { // 前20%脉冲数用于加速 uint32_t accel_phase = total_pulses * 0.2f; // 中间60%匀速 uint32_t cruise_phase = total_pulses * 0.6f; // 后20%减速 uint32_t decel_phase = total_pulses - accel_phase - cruise_phase; // 计算每个阶段的脉冲间隔 for(uint32_t i=0; i<accel_phase; i++) { pulse_interval = max_interval - (max_interval-min_interval)*i/accel_phase; } // ... 类似处理其他阶段 }6. 系统集成与测试
6.1 校准流程
正式使用前必须执行以下校准步骤:
机械回零:
- 缓慢移动至限位开关
- 记录编码器零点位置
脉冲校验:
- 发送5000脉冲,测量实际移动距离
- 调整电子齿轮比补偿误差
正交性校准:
- 沿X轴移动100mm,测量Y轴偏移
- 通过软件补偿非正交误差
6.2 典型测试案例
验证系统精度的最佳方式:
画对角线测试:
G1 X100 Y100 F1000测量实际终点与理论位置的偏差
圆形测试:
G2 X50 Y50 I25 J0 F800检查圆度误差和象限过渡平滑度
重复定位测试: 多次执行
G0 X0 Y0和G0 X100 Y100记录每次的定位偏差
在完成所有测试后,我发现最影响精度的因素是丝杠的反向间隙。通过添加软件补偿值,可以将重复定位精度提高约60%。另一个实用技巧是在运动指令前加入微小延时,给驱动器足够的响应时间。