# stepper-Motor **Repository Path**: xuelaoda/stepper-Motor ## Basic Information - **Project Name**: stepper-Motor - **Description**: No description available - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2026-07-08 - **Last Updated**: 2026-07-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 嵌入式步进电机驱动库 轻量级纯C步进电机控制库,支持多电机注册、梯形加减速、多种运动模式。通过硬件抽象层解耦底层IO,可零修改移植到各类MCU平台。 ![image-20260610205519564](IMAGE/image-20260610205519564.png) ## 特性 - 支持多电机同时控制(数量可配置) - 梯形加减速(线性加减速),运动平滑 - 速度模式 / 位置模式 / 归零模式 - 正负限位开关保护 - 外部脉冲反馈驱动位置计数(编码器/PWM中断) - 1ms定时器软件计数,不依赖PWM硬件 - 纯整数定点运算,无浮点依赖 - 硬件抽象层设计,移植仅需实现5个IO函数 ## 架构概览 ``` ┌─────────────────────────────────────────────────────────┐ │ 用户应用层 │ │ stepper_move_position() / stepper_move_speed() / ... │ └────────────────────────┬────────────────────────────────┘ │ ┌────────────────────────▼────────────────────────────────┐ │ stepper_motor.c │ │ stepper_tick() 每1ms: │ │ - 状态机驱动 │ │ - 梯形加减速计算 │ │ - 输出目标频率 → set_output_freq(id, freq) │ │ │ │ stepper_feed_steps() ← 外部反馈实际脉冲数 │ │ - 更新 position │ │ - 更新 steps_to_go (位置模式) │ └───────────┬─────────────────────────────────▲───────────┘ │ 输出频率 │ 反馈步数 ┌───────────▼─────────────────────────────────┴───────────┐ │ 硬件抽象层 (stepper_port.h) │ │ set_enable / set_direction / set_output_freq │ │ get_limit_pos / get_limit_neg │ └───────────┬─────────────────────────────────▲───────────┘ │ │ ┌───────────▼─────────────────────────────────┴───────────┐ │ 底层硬件 │ │ GPIO / 定时器PWM / 编码器中断 │ │ │ │ PWM中断或编码器中断中调用: │ │ stepper_feed_steps(id, 1); // 每个脉冲反馈一步 │ └─────────────────────────────────────────────────────────┘ ``` ## 文件结构 ``` stepper_config.h - 用户可配置参数(电机数量、默认加速度等) stepper_port.h - 硬件抽象层接口定义 stepper_motor.h - 公共API和类型定义 stepper_motor.c - 核心实现(状态机、加减速、tick) main.c - Windows平台测试程序 ``` ## 快速上手 ### 1. 实现硬件接口 ```c #include "stepper_motor.h" void my_set_enable(uint8_t id, uint8_t enable) { /* GPIO控制使能 */ } void my_set_direction(uint8_t id, uint8_t dir) { /* GPIO控制方向 */ } uint8_t my_get_limit_pos(uint8_t id) { /* 读正限位开关 */ } uint8_t my_get_limit_neg(uint8_t id) { /* 读负限位开关 */ } void my_set_output_freq(uint8_t id, uint32_t hz) { /* 设置定时器PWM频率 */ } stepper_io_t io = { .set_enable = my_set_enable, .set_direction = my_set_direction, .get_limit_pos = my_get_limit_pos, .get_limit_neg = my_get_limit_neg, .set_output_freq = my_set_output_freq, }; ``` ### 2. 初始化和注册电机 ```c stepper_init(&io); // 注册电机0:加速度2000步/秒², 减速度2000步/秒², 最大速度5000步/秒 stepper_register(0, 2000, 2000, 5000); ``` ### 3. 在1ms定时器中调用tick ```c void Timer1ms_IRQHandler(void) { stepper_tick(); } ``` ### 4. 在PWM中断或编码器中断中反馈步数 ```c // PWM脉冲完成中断 —— 每输出一个脉冲调用一次 void PWM_Pulse_IRQHandler(void) { stepper_feed_steps(0, 1); } // 或者编码器计数中断 —— 批量反馈 void Encoder_IRQHandler(void) { uint32_t count = read_encoder_count(); stepper_feed_steps(0, count); } ``` ### 5. 控制电机运动 ```c // 位置模式:正方向走10000步,最大速度3000步/秒 stepper_move_position(0, 10000, 3000); // 速度模式:正方向持续运行,速度2000步/秒 stepper_move_speed(0, STEPPER_DIR_POS, 2000); // 归零模式:向负方向寻找限位 stepper_home(0, STEPPER_DIR_NEG, 500); // 减速停止 stepper_stop(0); ``` ## API参考 ### 初始化 | 函数 | 说明 | |------|------| | `stepper_init(io)` | 初始化库,传入硬件IO接口 | | `stepper_register(id, accel, decel, max_speed)` | 注册电机 | ### 运动控制 | 函数 | 说明 | |------|------| | `stepper_move_speed(id, dir, speed)` | 速度模式,持续运行 | | `stepper_move_position(id, steps, speed)` | 位置模式,相对移动 | | `stepper_home(id, dir, speed)` | 归零模式,找限位开关 | | `stepper_stop(id)` | 带减速停止 | | `stepper_emergency_stop(id)` | 紧急停止(无减速) | ### 外部反馈 | 函数 | 说明 | |------|------| | `stepper_feed_steps(id, steps)` | 外部脉冲反馈,更新位置和剩余步数 | ### 状态查询 | 函数 | 说明 | |------|------| | `stepper_get_state(id)` | 获取运行状态 | | `stepper_get_position(id)` | 获取当前位置(步) | | `stepper_get_speed(id)` | 获取当前速度(步/秒) | | `stepper_is_home_done(id)` | 查询归零是否完成 | ### 设置 | 函数 | 说明 | |------|------| | `stepper_set_position(id, pos)` | 手动设置当前位置 | | `stepper_set_accel(id, accel, decel)` | 修改加减速参数 | | `stepper_clear_error(id)` | 清除错误状态 | ### 周期调用 | 函数 | 说明 | |------|------| | `stepper_tick()` | 1ms定时器中周期调用 | ## 数据流说明 库的核心设计思路是**输出频率、输入步数**: 1. `stepper_tick()` 每1ms根据加减速算法计算出当前目标速度 2. 通过 `set_output_freq(id, freq)` 告知底层应输出的脉冲频率 3. 底层硬件产生实际脉冲(定时器PWM等) 4. 每产生一个实际脉冲,通过 `stepper_feed_steps(id, 1)` 反馈给库 5. 库根据反馈更新 `position` 和 `steps_to_go`,驱动状态机判断 这种设计确保位置计数来自真实脉冲输出(或编码器),而非内部推算,避免丢步误差累积。 ## 运动模式说明 ### 速度模式 指定方向和目标速度,电机加速到目标速度后持续运行,直到调用 `stepper_stop()` 触发减速停止。 ``` 速度 ▲ │ ┌──────────────────┐ │ / \ │ / \ └──────────────────────────── 时间 加速 匀速 减速 ``` ### 位置模式 指定目标步数和速度,电机自动计算加速、匀速、减速三个阶段,精确到达目标位置后停止。 ``` 速度 ▲ │ ┌────────────┐ │ / \ │ / \ └──────────────────────── 时间 加速 匀速 减速 ↑到达目标 ``` 减速点由公式 `s = v² / (2a)` 自动计算。如果目标步数不足以加速到最大速度,电机会在未达到匀速前直接进入减速。 ### 归零模式 向指定方向运动,加速到归零速度后匀速,直到对应方向的限位开关触发,立即停止并将当前位置设为0。 ## 配置参数 在 `stepper_config.h` 中修改: | 宏 | 默认值 | 说明 | |----|--------|------| | `STEPPER_MAX_NUM` | 4 | 最大电机数量 | | `STEPPER_TICK_PERIOD_MS` | 1 | tick周期(ms) | | `STEPPER_DEFAULT_ACCEL` | 1000 | 默认加速度(步/秒²) | | `STEPPER_DEFAULT_DECEL` | 1000 | 默认减速度(步/秒²) | | `STEPPER_MIN_SPEED` | 50 | 最小速度/启动速度(步/秒) | | `STEPPER_SPEED_SCALE` | 1000 | 速度定点放大倍数 | ## 硬件抽象层 库通过 `stepper_io_t` 结构体中的5个函数指针与硬件交互: | 接口 | 方向 | 说明 | |------|------|------| | `set_enable` | 输出 | 控制电机驱动器使能 | | `set_direction` | 输出 | 控制运动方向 | | `get_limit_pos` | 输入 | 正方向限位开关状态 | | `get_limit_neg` | 输入 | 负方向限位开关状态 | | `set_output_freq` | 输出 | 设置脉冲频率(核心输出) | `set_output_freq` 是最关键的输出接口——库只负责计算当前应输出的频率值,底层负责产生实际脉冲。 `stepper_feed_steps` 是最关键的输入接口——底层每产生一个实际脉冲就反馈给库,库据此更新位置。 ## 移植指南 将库移植到MCU只需四步: 1. 实现 `stepper_io_t` 中的5个函数(GPIO + 定时器) 2. 在1ms定时器中断中调用 `stepper_tick()` 3. 在 `set_output_freq` 中配置硬件定时器输出对应频率的脉冲 4. 在PWM脉冲中断或编码器中断中调用 `stepper_feed_steps(id, steps)` 库核心文件(stepper_config.h、stepper_port.h、stepper_motor.h、stepper_motor.c)无需任何修改。 ## 状态机 ``` IDLE ──move命令──► ACCEL ──达到目标速度──► CRUISE ──到达减速点──► DECEL ──速度归零──► IDLE │ ▲ └──────剩余步数不足以匀速──────────────────────┘ HOMING: ACCEL → 匀速运行 → 限位触发 → IDLE (position=0) ERROR: 任何运动中限位意外触发 → 立即停止 ``` ## 编译测试(Windows) ```bash gcc -Wall -Wextra -o stepper_test.exe main.c stepper_motor.c ./stepper_test.exe ``` 测试程序中通过 `sim_pulse_feedback()` 模拟底层PWM中断的脉冲反馈,验证完整的"输出频率→产生脉冲→反馈步数"闭环流程。