Skip to content

SimpleAstronaut/Step_motor

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 

Repository files navigation

Step Motor Driver

一个简单易用的步进电机驱动库 (A simple and easy-to-use stepper motor driver)

项目简介

本项目为基于 STM32 HAL 库的步进电机驱动程序,采用梯形/三角形加减速算法,通过定时器 PWM 输出脉冲控制步进电机运动,支持非阻塞式控制。

主要特性

  • 梯形加减速算法 - 平滑启停,保护机械结构
  • 三角形加减速 - 短距离运动自动切换
  • 非阻塞控制 - 后台定时器中断处理,不占用主循环
  • 精确角度控制 - 基于角度输入,自动计算步数
  • 可配置参数 - 加速度、减速度、目标速度可调
  • PWM 脉冲输出 - 使用高级定时器生成精确脉冲

硬件要求

MCU 平台

  • STM32 系列(默认配置基于 STM32F4,168MHz 主频)
  • 需要至少 1 个高级定时器(默认使用 TIM8
  • 需要 GPIO 控制方向和使能信号

步进电机驱动器

支持通用步进电机驱动器(如 DRV8825、A4988、TB6600 等),需要以下接口:

  • PUL+/PUL-(脉冲信号) → 连接定时器 PWM 输出
  • DIR+/DIR-(方向信号) → 连接 GPIO
  • ENA+/ENA-(使能信号) → 连接 GPIO

接线示意

STM32                  步进驱动器
TIM8_CH1 (PWM)  -----> PUL+ (脉冲)
GPIO (DIR)      -----> DIR+ (方向)
GPIO (ENA)      -----> ENA+ (使能)
GND             -----> PUL-/DIR-/ENA-

快速开始

1. 文件集成

step_motor_v1 目录下的文件添加到您的工程:

step_motor_v1/
├── step_motor.c        # 主驱动实现
└── step_motor.h        # 头文件

2. STM32CubeMX 配置

(1) 配置定时器 TIM8

  • 时钟源: Internal Clock

  • 模式: PWM Generation CH1

  • 参数配置:

    Prescaler (PSC):     0
    Counter Mode:        Up
    Counter Period (ARR): 1000 (初始值,运行时会动态调整)
    Pulse (CCR1):        500  (50% 占空比)
    
  • 中断使能:

    • ✅ 勾选 Update interrupt

(2) 配置 GPIO(可选,用于方向和使能)

// 示例配置(根据实际硬件修改)
DIR_GPIO_Port: GPIOB, Pin: GPIO_PIN_0
ENA_GPIO_Port: GPIOB, Pin: GPIO_PIN_1

(3) 生成代码

在 CubeMX 中生成 HAL 库代码。


3. 代码集成

main.c 中包含头文件

#include "step_motor.h"

在主函数中调用

int main(void)
{
    /* HAL 初始化 */
    HAL_Init();
    SystemClock_Config();
    
    /* 初始化外设 */
    MX_GPIO_Init();
    MX_TIM8_Init();
    
    /* 设置电机使能和方向 */
    HAL_GPIO_WritePin(ENA_GPIO_Port, ENA_Pin, GPIO_PIN_RESET); // 使能电机
    HAL_GPIO_WritePin(DIR_GPIO_Port, DIR_Pin, GPIO_PIN_SET);   // 设置方向
    
    /* 启动电机旋转 360 度 */
    start(360.0);
    
    while (1)
    {
        // 主循环可以执行其他任务
        // 电机运动在中断中自动完成
    }
}

添加定时器中断回调

stm32f4xx_it.cmain.c 中确保定时器中断已启用:

// 此函数已在 step_motor.c 中实现
// 无需额外编写,但需确保中断向量表正确配置
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);

API 文档

核心函数

start - 启动电机运动

void start(float angle);

功能说明:

  • 控制步进电机旋转指定角度
  • 自动计算加减速曲线
  • 非阻塞式执行,函数立即返回

参数说明:

  • angle: 目标旋转角度(单位:度)
    • 正值:正向旋转
    • 负值:反向旋转(需先通过 GPIO 设置方向)
    • 相对角度:以上电时刻为 0° 基准

注意事项:

  • ⚠️ 不可重复调用:必须等待上一次运动完成后再调用
  • 默认电机步距角为 1.8°/步(200 步/转)
  • 如使用细分驱动器,需修改源码中的步数计算公式

示例:

// 旋转 360 度(一圈)
start(360.0);

// 旋转 180 度(半圈)
start(180.0);

// 旋转 90 度(四分之一圈)
start(90.0);

可配置参数

step_motor.c 中可修改以下全局变量:

运动参数

float accel = 0.5;      // 加速度(可调整范围:0.1 ~ 2.0)
float decel = 0.5;      // 减速度(可调整范围:0.1 ~ 2.0)
float speed = 20;       // 目标速度(可调整范围:10 ~ 50)

参数说明:

  • accel: 加速度值,越大加速越快,但过大可能导致失步
  • decel: 减速度值,越大减速越快
  • speed: 最大运行速度,单位为内部计算单位(非物理单位)

调整建议:

// 平滑运动(适合重载、精密场合)
accel = 0.3;
decel = 0.3;
speed = 15;

// 快速运动(适合轻载、快速定位)
accel = 1.0;
decel = 1.0;
speed = 40;

内部变量说明

运动状态

int status;  // 运动状态
状态 说明
0 停止 电机静止
1 加速 正在加速阶段
2 匀速 正在匀速运行
3 减速 正在减速阶段

运动模式

int mode;  // 运动模式
模式 说明
1 三角形 短距离运动,无匀速段,直接从加速转减速
2 梯形 长距离运动,包含加速-匀速-减速三个阶段

运动曲线算法

梯形加减速

适用于长距离运动,速度曲线分为三个阶段:

速度
  ^
  |     ___________  ← 匀速段
  |    /           \
  |   /             \
  |  /               \
  | /                 \
  |/__________________\___> 时间
    加速段  匀速段  减速段

阶段划分:

  1. 加速段: 从静止加速到目标速度
  2. 匀速段: 保持目标速度运行
  3. 减速段: 从目标速度减速到停止

三角形加减速

适用于短距离运动,无法达到目标速度:

速度
  ^
  |      /\
  |     /  \
  |    /    \
  |   /      \
  |  /        \
  | /          \
  |/_____________\___> 时间
    加速段  减速段

自动切换:

  • 当目标步数 < (加速步数 + 减速步数) 时,自动切换为三角形模式

定时器中断机制

工作原理

  1. start() 函数启动定时器 TIM8 并使能中断
  2. 每个定时器周期触发一次中断(产生一个脉冲)
  3. 中断回调函数 HAL_TIM_PeriodElapsedCallback() 中:
    • 根据当前阶段计算下一步的定时��周期
    • 更新定时器参数(动态调整脉冲频率)
    • 步数计数器 step_count 递增
  4. step_count 达到 total_steps 时停止定时器

速度控制原理

  • 周期 ↑ → 频率 ↓ → 速度 ↓
  • 周期 ↓ → 频率 ↑ → 速度 ↑

加减速通过逐步调整定时器周期实现平滑过渡。


常见问题

1. 电机不转或抖动

可能原因:

  • 定时器配置错误 → 检查 TIM8 是否配置为 PWM 模式
  • 脉冲信号未连接 → 用示波器检查 PWM 输出
  • 驱动器使能信号未拉低 → 检查 ENA 引脚电平
  • 加速度设置过大 → 降低 accelspeed

2. 电机失步

解决方案:

  • 降低加速度和速度参数
  • 增加驱动电流(在驱动器上调节)
  • 检查负载是否过大

3. 电机只能单向旋转

解决方案:

  • 手动控制 DIR 引脚电平实现方向切换:
    HAL_GPIO_WritePin(DIR_GPIO_Port, DIR_Pin, GPIO_PIN_SET);   // 正向
    HAL_GPIO_WritePin(DIR_GPIO_Port, DIR_Pin, GPIO_PIN_RESET); // 反向

4. 如何判断电机是否运动完成?

方法一:轮询状态变量

extern float step_count;
extern float total_steps;

if (step_count >= total_steps) {
    // 运动完成
}

方法二:检查定时器状态

if (__HAL_TIM_GET_FLAG(&htim8, TIM_FLAG_UPDATE) == RESET) {
    // 定时器已停止,运动完成
}

5. 支持其他步距角的电机吗?

支持,修改 start() 函数中的步数计算:

// 原代码(1.8°/步)
total_steps = angle / 1.8;

// 改为 0.9°/步(400 步/转)
total_steps = angle / 0.9;

// 改为 1.8° + 16 细分(3200 步/转)
total_steps = (angle / 1.8) * 16;

技术细节

定时器频率计算

T1_FREQ = 0.676 * 10000 / 10;  // 定时器频率参数
A_SQ = 2 * 0.0314 * 100000;    // 加速度参数

这些常数基于 168MHz 系统时钟和特定的算法推导,如需移植到其他平台,需重新计算。

步数计算公式

n1 = speed * speed / (0.0628 * accel);  // 加速段步数
n2 = speed * speed / (0.0628 * decel);  // 减速段步数

基于运动学方程 $v^2 = 2as$ 推导。


版本信息

  • 版本: v1.0
  • 日期: 2025-04-10
  • 作者: SimpleAstronaut
  • 平台: STM32F4 + HAL 库

开源协议

本项目采用 GNU General Public License v3.0 开源协议。

详见 LICENSE 文件。


示例代码

完整示例:连续运动

#include "main.h"
#include "step_motor.h"

extern float step_count;
extern float total_steps;

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_TIM8_Init();
    
    // 使能电机
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
    
    while (1)
    {
        // 正向旋转 360 度
        HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);
        start(360.0);
        
        // 等待运动完成
        while (step_count < total_steps) {
            HAL_Delay(10);
        }
        HAL_Delay(1000);
        
        // 反向旋转 360 度
        HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);
        start(360.0);
        
        while (step_count < total_steps) {
            HAL_Delay(10);
        }
        HAL_Delay(1000);
    }
}

技术支持

如有问题或建议,请提交 Issue 或 Pull Request。

GitHub: SimpleAstronaut/Step_motor

一个简易易用的步进电机驱动

注意:本项目遵循GPL3.0开源协议

优势

  • 简单易用,仅需调用一个函数即可

  • 轻量化,不依赖其他外部库

  • 负载低,空闲时不开启定时器占用资源

用法

驱动使用定时器输出单脉冲控制步进电机PUL脉冲,DIR和ENA需要自行配置,驱动只包含PUL脉冲输出,注意使用的是高级定时器,定时器主频168MHz

在正确完整导入驱动,正确设置定时器和pwm单脉冲之后,在需要的地方调用

void start(float angle);

注意angle为相对角度,默认上电时刻为角度0点,会自动计算梯形加减速

此时驱动会自行开启定时器,进入定时器中断,驱动会自动向TIM8_CH1对应IO发送脉冲

开发说明

驱动计算相关参数都在step_motor.c的全局变量中,可供修改的部分如下所示

//参数设置
float accel = 0.5;     //加速度
float decel = 0.5;     //减速度
float speed = 20;      //最高速度

此外,驱动提供状态监测接口,全局变量如下所示

float step_count = 0.0f;		 // 当前步数
float total_steps = 0.0f;		 // 总步数

int status = 0; 				 // 0停止 1加速 2匀速 3减速
int mode = 0;							//三角形或梯形

另外,如果需要,可以修改定时器相关配置

About

A simple and easy-to-use stepper motor driver

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages