这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 【静音步进电机控制实践】基于STM32C562RET6的滑轨步进电机控制实践

共2条 1/1 1 跳转至

【静音步进电机控制实践】基于STM32C562RET6的滑轨步进电机控制实践

高工
2026-06-28 20:45:40   被打赏 50 分(兑奖)     打赏

1. 引言

        步进电机在自动化设备中应用广泛。相较于直流电机,步进电机的优势在于其“开环即可定位”——只要给驱动器发送足够数量、合适频率的脉冲,转子就会严格按一个固定的角度步进,不需要额外的位置反馈。本次实践的对象是一台丝杆滑轨:滑块通过联轴器与一台两相步进电机相连,丝杆导程为已知常数,电机每收到一个有效 STEP 上升沿,滑块就会移动一段固定的距离(一个微步距)。基于这一物理事实,控制任务可以抽象为“在时间轴上产生指定数量、指定频率的 STEP 脉冲”,并通过另外两根信号线(DIR、EN)控制方向与驱动器使能。

        为了完整地体验一次“较新 MCU 平台”的嵌入式开发流程,本次实践特意选用了 ST 较新的 STM32C562RET6(属于 STM32C5 系列)作为主控。该 MCU 基于 Cortex‑M33,最高主频 144 MHz,原生支持 FPU、DSP 指令以及 TrustZone‑M,是 STM32 主线产品里一颗较新的型号。配套的开发板是 NUCLEO‑C562RE,板载 ST‑Link V3 Mini 调试器,可直接通过 USB 提供虚拟串口(VCP)、拖拽式烧录与 SWD 调试。本次任务是把上述的“产生 STEP 脉冲”这件事用嵌入式代码稳定地实现出来,并通过串口命令控制其行为。

        整个过程除了最终的功能实现,还顺便验证了以下几条“新平台开发体验”是否真的好用:
  • STM32CubeMX2 工具能否在 STM32C5 上产生干净、合规的初始化代码;

  • CMake + Ninja + arm‑gcc 工具链能否摆脱传统 IDE(Keil / IAR)完成工程构建;

  • HAL + 用户态应用层的边界划分是否清晰;

  • 串口、按键、LED 等基础外设能否用最少的手写代码接入。

2. 硬件平台

2.1 主控:NUCLEO-C562RE

        NUCLEO‑C562RE是ST围绕STM32C562RET6 推出的一款64引脚LQFP 评估板,主要资源如下:

项目说明
MCUSTM32C562RET6,Cortex‑M33,144 MHz
Flash / SRAM512 KB / 192 KB(具体以数据手册为准)
板上 ST‑LinkST‑Link V3 Mini,支持 VCP、SWD、拖拽烧录
用户 LEDLD2 / PA5(绿色,高电平点亮)
用户按键B1 / PC13(下拉,无外部上下电阻)
Arduino 兼容排针多数 GPIO 通过排针引出
板载 VCPUSB 桥接的虚拟串口,默认走 USART2(PA2/PA3,AF7)

        PA5与PC13是NUCLEO板上最经典的两个用户资源,复用它们不需要额外的飞线;而PA2/PA3则是板上USB转串口桥接的对外引脚,等同于一个接好 USB 线的串口调试助手。这三个引脚的分配为本次实践节省了大量时间。

2.2 驱动器与电机:TMC2206 + 两相步进电机

        TMC2206是德国Trinamic出品的一款静音两相步进电机驱动芯片,常见于3D打印机、相机滑轨、小型CNC等场景。其 STEP/DIR/EN 接口电平兼容3.3 V单片机,可以直接与STM32 GPIO相连。本次实践中我们用到的最小接线如下:

TMC2206 引脚接到 STM32 引脚备注
STEPPA9每个上升沿驱动电机前进一步(这里用作微步)
DIRPC5高/低电平决定旋转方向
EN(ENABLE)PA10TMC2206 默认低电平有效:EN = LOW 驱动器上电,EN = HIGH 驱动器释放
VM / GND外部电源(≥ 8 V)TMC2206 逻辑与功率部分解耦,逻辑侧与 MCU 共地
A1/A2/B1/B2接两相步进电机不在本项目代码范围内

2.3 整体硬件接线3d92c0ca-9932-4ae6-bb89-cce2e2429130.png


3. 软件设计

任务

        从用户视角看,本次任务可以拆成三条指令:

命令字节含义备注
0x01使能 ↔ 失能滑轨失能后滑块必须回到原点(位置 0)
0x02改变方向(仅在 RUNNING 状态生效)立即翻转 DIR 引脚
0x03切换速度档慢 400 step/s ↔ 快 1600 step/s

        为了让这三条命令“可观察”,还顺手补了几个小功能:

  • 上电时通过USART2打印 motor ctrl ready\n,确认初始化完成;

  • 板载LED(PA5)随状态变化:代表电机已使能,代表失能;

  • 板载按键(PC13)触发EXTI13上升沿中断,等价于0x01,方便在没有串口助手的时候单步调试。

状态机

        电机本身需要知道自己当前在做什么。“是否能发脉冲?方向是什么?速度档是什么?”——这些信息用一个有限状态机来描述最为自然。本次设计采用三态机:

┌─────────────┐
   boot ──▶│  DISABLED   │◀──── 0x01, pos==0
            │ EN=HIGH     │
            │ pos=5000    │
            │ TIM17 stopped│
            └──────┬──────┘
                   │ 0x01
                   ▼
            ┌─────────────┐  edge   ┌─────────────┐
            │  RUNNING    │◀──────▶│  RUNNING    │
            │ pulse out   │        │ (same state,│
            │ edge → 反向 │        │  dir bit 翻)│
            └──┬──────┬───┘        └─────────────┘
               │      │ 0x01 (pos>0)
               │      ▼
               │   ┌─────────────┐ pos==0 → DISABLED
               │   │  RETURNING  │ (or 0x01 立即停下)
               │   │ dir=REVERSE │
               │   └─────────────┘
               │ 0x03: 切 ARR
               │ 0x02: 翻转 dir bit(仅在 RUNNING)


        态机的语义如下:

状态含义EN 电平TIM17
DISABLED驱动器释放、滑轨可手动推动高(释放)停止
RUNNING在当前位置允许脉冲输出低(使能)启动
RETURNING强制 REVERSE 方向回到原点启动

        代码侧的关键变量声明:

static volatile motor_state_t s_state    = MOTOR_STATE_DISABLED;
static volatile motor_dir_t   s_dir      = MOTOR_DIR_FORWARD;
static volatile motor_speed_t s_speed    = MOTOR_SPEED_SLOW;
static volatile int32_t       s_position = (int32_t)MOTOR_INITIAL_POSITION;
static volatile uint8_t       s_timer_running = 0U;

STEP 脉冲发生器:TIM17

        要产生连续的STEP脉冲,最直观的做法是用一个硬件定时器在固定间隔翻转PA9。STM32C562上的TIM17接到APB2,预分频后正好可以做出我们想要的频率:
APB2 timer clock = 144 MHz
PSC = 143 → counter clock = 1 MHz
ARR = 1249 → 每 1.25 ms 一次更新事件(慢档,400 sps)
ARR = 311  → 每 0.625 ms 一次更新事件(快档,1600 sps)

        每次 TIM17 触发更新中断,ISR就把 STEP_PIN翻转一次。这样占空比天然是50%,远高于TMC2206 数据手册要求的 STEP 高/低电平最小100 ns。把速度档从 400 sps 调到 1600 sps,只需要改ARR,TIM17不需要重启。

        ISR 中对 STEP 的处理:
void HAL_TIM_UpdateCallback(hal_tim_handle_t *htim)
{
  if (htim != mx_tim17_gethandle())            { return; }
  if (s_state == MOTOR_STATE_DISABLED)         { return; }

  /* 翻转 STEP — 每次更新事件翻转一次,得到 50% 占空比 */
  static uint8_t s_step_state = 0U;
  s_step_state ^= 1U;
  HAL_GPIO_WritePin(STEP_PORT, STEP_PIN,
                    s_step_state ? STEP_ACTIVE_STATE : STEP_INACTIVE_STATE);

  /* 仅在上升沿计数一次,避免双计数 */
  if (HAL_GPIO_ReadPin(STEP_PORT, STEP_PIN) != STEP_ACTIVE_STATE) { return; }

  /* 越界自动反向 */
  if (s_dir == MOTOR_DIR_FORWARD)
  {
    if (++s_position >= (int32_t)MOTOR_MAX_TRAVEL_PULSES)
    {
      s_position = (int32_t)MOTOR_MAX_TRAVEL_PULSES;
      s_dir = MOTOR_DIR_REVERSE;
      motor_apply_dir();
    }
  }
  else
  {
    if (--s_position <= 0)
    {
      s_position = 0;
      if (s_state == MOTOR_STATE_RETURNING) { motor_enter_disabled(); return; }
      s_dir = MOTOR_DIR_FORWARD;
      motor_apply_dir();
    }
  }
}

USART2命令接口

        USART2在STM32CubeMX2中已经被配置为115200-8N1、AF7接到 PA2/PA3,并自动调用 mx_usart2_uart_init() 进入系统初始化流程。

        主循环每轮先看按键标志,再看队列里有没有未处理的字节:

while (1)
{
  if (s_btn_pending) { s_btn_pending = 0U; cmd_dispatch(CMD_ENABLE_TOGGLE); … }

  if (serial_get_byte(&b)) { cmd_dispatch(b); … }
}
        发送走HAL_UART_Transmit()阻塞模式。serial_puts("ok\n")在收到任何命令后回一行字符串,方便串口助手双向确认。

按键与 LED

  • PA5 / LED:在主循环里随状态刷新:motor_get_state() == DISABLED ? PA5_INACTIVE_STATE : PA5_ACTIVE_STATE。

  • PC13 / 按键:在 mx_gpio_default.c 里被 CubeMX2 配成 EXTI13 上升沿中断,并在同一文件中开启了对应的 NVIC。我们只需要在应用层重写弱回调 HAL_EXTI_TriggerCallback(),判断 handle 是否等于 mx_gpio_default_exti13_gethandle(),置一个 s_btn_pending 标志即可。主循环看到标志就当成一次 0x01 处理。

4.实测验证

【基于STM32C562RET6的滑轨步进电机控制实践】 https://www.bilibili.com/video/BV1S3Tg6cEaL/?share_source=copy_web&vd_source=6c53bcbe419a41b4d4827b64953cb205

总结

本次实践以NUCLEO‑C562RE+TMC2206为基础,完整地实现了一套“串口命令 → 滑轨步进电机往复运动”的最小可行系统:
  • 硬件 上利用了 NUCLEO 板自带的 ST‑Link VCP、用户 LED 与按键,只需外接一块 TMC2206 与两相步进电机即可构成完整闭环;

  • 软件 上借 STM32CubeMX2 自动生成的初始化代码,应用层只关注状态机与脉冲发生器,整体代码量小(应用层 ≈ 200 行 C 代码),结构清晰;

总体来说,STM32C5 这颗“新平台”给我们留下的印象是:寄存器定义和HAL接口都很成熟,工具链也已经跟上。




关键词: 成果          STM32C562RET6     滑轨     实践    

院士
2026-06-29 16:46:17     打赏
2楼

学习了,谢谢分享。


共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]