STM32 控制 3 个步进电机方案,适用于 STM32F1 / F4 / G0 / L4(HAL 库),支持 独立速度 / 启停 / 加减速。
一、推荐硬件方案(工业常用 )
1、步进电机驱动方式
| 项目 | 推荐 |
|---|---|
| 步进驱动 | DRV8825 / A4988 / TB6600 |
| 控制方式 | STEP + DIR + EN |
| 隔离 | 光耦(防干扰) |
| 供电 | 电机与 MCU 分开供电 |
2、 STM32 与 3 路步进电机连接
| 步进电机 | STEP | DIR | EN |
|---|---|---|---|
| MOTOR1 | PA0 | PA1 | PA2 |
| MOTOR2 | PA3 | PA4 | PA5 |
| MOTOR3 | PA6 | PA7 | PA8 |
每个电机 1 个定时器通道 产生 STEP 脉冲
DIR / EN 用 GPIO
二、定时器方案(核心思想)
方案对比
| 方案 | 特点 | 推荐 |
|---|---|---|
| 定时器 PWM | 精准、不占 CPU | 推荐 |
| SysTick 延时 | 简单但不准 | ❌ |
| 主循环翻转 IO | 抖动大 | ❌ |
3 个电机 = 3 个定时器 PWM(TIM2 / TIM3 / TIM4)
三、定时器 PWM 初始化(CubeMX)
TIM 配置(每个电机一路)
| 参数 | 设置 |
|---|---|
| Mode | PWM Generation CHx |
| Prescaler | 0 |
| Counter Period | 自动重装值 |
| Pulse | 占空比 50% |
| Polarity | High |
例:72MHz → 50kHz 步进频率
四、核心控制代码
1、 GPIO 定义(DIR / EN)
c
#define M1_DIR_H() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET)
#define M1_DIR_L() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET)
#define M1_EN_ON() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET)
#define M1_EN_OFF() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET)
2、 步进电机结构体
c
typedef struct
{
TIM_HandleTypeDef *htim;
uint32_t channel;
uint32_t freq;
} StepMotor_t;
c
StepMotor_t motor[3] = {
{&htim2, TIM_CHANNEL_1, 0},
{&htim3, TIM_CHANNEL_1, 0},
{&htim4, TIM_CHANNEL_1, 0}
};
3、 设置电机转速(Hz)
c
void StepMotor_SetFreq(StepMotor_t *m, uint32_t freq)
{
m->freq = freq;
if (freq == 0)
{
__HAL_TIM_DISABLE(m->htim);
return;
}
uint32_t arr = 1000000 / freq; // 1MHz 计数
__HAL_TIM_SET_AUTORELOAD(m->htim, arr - 1);
__HAL_TIM_SET_COMPARE(m->htim, m->channel, arr / 2);
__HAL_TIM_ENABLE(m->htim);
}
4、 电机启停控制
c
void StepMotor_Start(StepMotor_t *m)
{
StepMotor_SetFreq(m, m->freq);
}
void StepMotor_Stop(StepMotor_t *m)
{
StepMotor_SetFreq(m, 0);
}
五、主函数示例(3 电机独立运行)
c
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_TIM2_Init();
MX_TIM3_Init();
MX_TIM4_Init();
MX_GPIO_Init();
M1_EN_ON();
M2_EN_ON();
M3_EN_ON();
M1_DIR_H(); // 正转
M2_DIR_H();
M3_DIR_L(); // 反转
StepMotor_SetFreq(&motor[0], 500); // 500 Hz
StepMotor_SetFreq(&motor[1], 800);
StepMotor_SetFreq(&motor[2], 1200);
while (1)
{
HAL_Delay(1000);
}
}
参考代码 stm32控制3个步进电机程序 www.youwenfan.com/contentcst/182298.html
六、加减速
c
void StepMotor_Accel(StepMotor_t *m, uint32_t target_freq)
{
while (m->freq < target_freq)
{
m->freq += 50;
StepMotor_SetFreq(m, m->freq);
HAL_Delay(10);
}
}
七、抗干扰 & 实战经验
共地 :STM32 GND 必须与驱动器 GND 相连
光耦隔离 :STEP / DIR 必须隔离
细分设置 :DRV8825 推荐 16 细分
低速加减速 :否则必丢步
ENA 使能:不运行时关掉电机电流
八、可扩展方向
FreeRTOS 多任务控制
多轴插补(直线 / 圆弧)
编码器闭环步进
Modbus / CAN 远程控制
位置模式(脉冲计数)