这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 【静音步进电机控制实践】成果帖:基于STM32F103CB+TMC2209(st

共3条 1/1 1 跳转至

【静音步进电机控制实践】成果帖:基于STM32F103CB+TMC2209(standAlone模式)步进电机控制项目报告(本文由AI生成,功能通过实测)

助工
2026-07-12 16:24:26     打赏


 

 

STM32F103CB + TMC2209
步进电机控制项目报告

基于 TIM2 PWM 硬件脉冲生成 + STEP/DIR 定频控制

 

MCU

STM32F103CBT6

驱动芯片

TMC2209

系统时钟

72 MHz

工具链

Keil MDK-ARM

 

目录

1. 项目概述

2. 系统框图

3. 硬件设计 电路原理图与引脚分配

4. 软件架构设计

5. 主要参数情况

6. 实现步骤

7. 软件调试要点

8. 项目代码清单

9. 如何开启运行


1. 项目概述

本项目基于 STM32F103CBT6 微控制器和 Trinamic TMC2209 步进电机驱动芯片,实现步进电机的定频脉冲运动控制。系统采用 STEP/DIR 接口模式,通过 STM32 硬件定时器 (TIM2) 生成精确的 PWM 脉冲信号驱动 TMC2209,支持多档微步细分切换和正反转控制。

核心特性

· 硬件脉冲生成:TIM2 CH1 PWM 输出 STEP 脉冲,1μs 脉宽,频率可达 300,000 Hz

· 多档微步:支持 1/81/161/321/64 四种细分模式,通过 MS1/MS2 引脚切换

· 精确步数控制:TIM2 更新中断计数,到达目标步数自动停止

· 方向控制:DIR 引脚电平切换正反转

· 使能管理:ENN 低有效,支持驱动使能/失能

· 位置追踪:维护有符号绝对位置计数器

· 预留串口:USART1 (115200 8N1) 已配置,可扩展上位机通信

技术规格一览

MCU 型号

STM32F103CBT6 (Cortex-M3, LQFP48)

Flash / RAM

128 KB / 20 KB

系统时钟

72 MHz (HSE 8MHz × PLL9)

驱动芯片

TMC2209 (standalone STEP/DIR 模式)

电机类型

两相四线步进电机,步距角 1.8°

每转整步数

200 (360° / 1.8°)

脉冲生成方式

TIM2 CH1 PWM 硬件输出

脉冲宽度

1 μs (CCR1 = 72 @ 72MHz)

频率范围

1,097 ~ 24,000,000 Hz (代码限速 1,100 ~ 300,000)

HAL 固件版本

STM32Cube FW_F1 V1.8.6

代码生成工具

STM32CubeMX V6.15.0

IDE / 编译器

Keil MDK-ARM V5.32, ARMCC V5.06


2. 系统框图

以下为系统总体架构框图,展示各功能模块之间的信号流向与连接关系:

┌─────────────┐         ┌──────────────────────────────────────────┐         ┌──────────────┐

│   HSE 晶振  │         │           STM32F103CBT6                 │         │   TMC2209    │

│   8 MHz     │────────▶│  ┌────────┐  ┌──────────────┐           │  PA0    │              │

└─────────────┘  PD0    │  │PLL ×9  │  │  TIM2 CH1    │───────────│────────▶│  STEP  ◀──   │

                 PD1    │  │72 MHz  │  │  PWM 脉冲    │           │  PA1    │  DIR   ◀──   │

┌─────────────┐         │  └────────┘  │  ARR+CCR1=72 │           │────────▶│  ENN   ◀──   │

│ J-Link/SWD  │         │              └──────────────┘           │  PA2    │  MS1   ◀──   │

│ PA13/PA14   │────────▶│  ┌──────────────┐  ┌──────────┐         │────────▶│  MS2   ◀──   │

└─────────────┘         │  │  GPIO        │  │  NVIC    │         │  PA3    │              │

┌─────────────┐         │  │ DIR/ENN/MS   │  │ TIM2_IRQ │         │────────▶│  A1 ── A+    │

│   电源      │         │  └──────────────┘  └──────────┘         │  PA4    │  A2 ── A-    │

│ 3.3V / 12V  │────────▶│  ┌──────────────┐                       │────────▶│  B1 ── B+    │

└─────────────┘         │  │ USART1 (预留)│                       │         │  B2 ── B-    │

                        │  └──────────────┘                       │         └──────┬───────┘

                        └──────────────────────────────────────────┘                │

                                                                                     

                                                                              ┌──────────────┐

                                                                              │   步进电机    

                                                                              │ 1.8° 两相四线

                                                                              └──────────────┘

 

2-1 系统总体框图

数据流说明

信号路径

说明

HSE 8MHz → PLL ×9 → 72MHz

系统时钟源,驱动 TIM2 定时器 (APB1×2 = 72MHz)

TIM2 CH1 PWM → PA0 → TMC2209 STEP

硬件生成精确脉冲,频率由 ARR 控制

GPIO PA1~PA4 → DIR/ENN/MS1/MS2

软件控制方向、使能、细分

TIM2 更新中断 → NVIC → Handler

每个脉冲周期计数,到目标步数停止

TMC2209 → 电机线圈 A+/A-/B+/B-

驱动芯片内部 H 桥输出电流驱动电机

J-Link SWD → STM32

程序烧录与在线调试


3. 硬件设计 电路原理图与引脚分配

3.1 电路连接原理图

┌─────────────────────────────┐                    ┌──────────────────────────────┐

│     STM32F103CBT6           │                    │          TMC2209             │

│                             │                    │                              │

│  VDD ●                      │              ┌────▶│  STEP                        │

│  GND ●                      │              │     │  DIR                         │

│  PD0/OSC_IN ●───┐           │              │     │  ENN                         │

│  PD1/OSC_OUT ●──┤ Y1 8MHz   │     PA0 ─────┤     │  MS1                         │

│                 └───        │     PA1 ─────┤     │  MS2                         │

│  PA0/TIM2_CH1 ●─────────────┼─────          │     │                              │

│  PA1          ●─────────────┼──────────────┤     │  A1 ────── A+ (电机线圈A)    │

│  PA2          ●─────────────┼──────────────┤     │  A2 ────── A-                │

│  PA3          ●─────────────┼──────────────┤     │  B1 ────── B+ (电机线圈B)    │

│  PA4          ●─────────────┘               │     │  B2 ────── B-                │

│                             │               │     │                              │

│  PA9/USART1_TX ● (预留)     │               │     │  VS ◀── 12V 电机供电         

│  PA10/USART1_RX ● (预留)    │               │     │  5V_OUT (内部LDO)           │

│  PA13/SWDIO  ● (调试)       │               │     │  GND ◀── 公共地              

│  PA14/SWCLK  ● (调试)       │               │     │                              │

└─────────────────────────────┘               │     └──────────────────────────────┘

                                               │                  │

                                               │           ┌──────┴───────┐

                                               └───────────│   步进电机    

                                                           │ 1.8°/200/

                                                           │  两相四线    

                                                           └──────────────┘

 

3-1 STM32 TMC2209 电路连接原理图

3.2 引脚分配表

STM32 引脚

功能

TMC2209 引脚

GPIO 模式

初始电平

说明

PA0

TIM2_CH1

STEP

AF_PP

PWM 脉冲输出,1μs 脉宽

PA1

GPIO Output

DIR

PP

LOW

方向:LOW=CW, HIGH=CCW

PA2

GPIO Output

ENN

PP

HIGH

使能:LOW=使能, HIGH=失能

PA3

GPIO Output

MS1

PP

HIGH

细分选择位 0

PA4

GPIO Output

MS2

PP

HIGH

细分选择位 1

PA9

USART1_TX

AF_PP

串口发送 (预留)

PA10

USART1_RX

Input

串口接收 (预留)

PA13

SWDIO

AF

SWD 调试接口

PA14

SWCLK

AF

SWD 调试接口

PD0

OSC_IN

HSE 外部晶振输入

PD1

OSC_OUT

HSE 外部晶振输出

3.3 TMC2209 微步细分真值表

MS2

MS1

细分

每转脉冲数

步距角


LOW

LOW

1/8

1,600

0.225°


LOW

HIGH

1/32

6,400

0.05625°


HIGH

LOW

1/64

12,800

0.028125°


HIGH

HIGH

1/16 (默认)

3,200

0.1125°


供电说明

TMC2209 VS 引脚接 12V 电机供电,内部 LDO 输出 5V 供逻辑使用。

STM32 使用独立 3.3V 供电,两者共地。

STEP/DIR/ENN/MS1/MS2 均为 3.3V 逻辑电平,TMC2209 兼容 3.3V 输入。

 


4. 软件架构设计

4.1 分层架构

┌──────────────────────────────────────────────────────────────────────┐

│  应用层 — main.c                                                     │

│  演示循环: 遍历 8 种微步/速度配置, 正反转各 2 圈                      

└──────────────────────────────┬───────────────────────────────────────┘

                               

                               

┌──────────────────────────────────────────────────────────────────────┐

│  运动控制层 — stepper.c / stepper.h                                   │

│  TIM2 PWM 定频脉冲 + 更新中断步数计数 + 位置追踪                      

└──────────────────────────────┬───────────────────────────────────────┘

                               

                               

┌──────────────────────────────────────────────────────────────────────┐

│  驱动 HAL — tmc2209.c / tmc2209.h                                 │

│  DIR 方向 / ENN 使能 / MS1+MS2 细分引脚控制                           

└──────────────────────────────┬───────────────────────────────────────┘

                               

                               

┌──────────────────────────────────────────────────────────────────────┐

│  STM32 HAL (FW_F1 V1.8.6)                                         │

│  HAL_GPIO · HAL_TIM (PWM) · HAL_UART · HAL_RCC · HAL_CORTEX          │

└──────────────────────────────┬───────────────────────────────────────┘

                               

                               

┌──────────────────────────────────────────────────────────────────────┐

│  CMSIS Cortex-M3 + startup_stm32f103xb.s                             │

└──────────────────────────────────────────────────────────────────────┘

 

4-1 软件分层架构

4.2 时钟树配置

  ┌──────────┐     ┌──────────┐     ┌──────────┐     ┌──────────────┐

  │   HSE    │────▶│  PLL ×9  │────▶│  SYSCLK  │────▶│ AHB /1       │

  │ 8 MHz    │     │ 72 MHz   │     │ 72 MHz   │     │ → APB2 /1    │

  └──────────┘     └──────────┘     └──────────┘     │ = 72 MHz     │

                                                      └──────────────┘

                                                ┌──────────────┐

                                           ┌───▶│ APB1 /2      │

                                           │    │ = 36 MHz     │

                                           │    └──────┬───────┘

                                           │           │ ×2 (自动)

                                           │           ▼

                                           │    ┌──────────────┐

                                           └────│  TIM2        │

                                                │ = 72 MHz     │

                                                └──────────────┘

 

  备注:APB1 预分频 = /2, 定时器时钟自动 ×2 → TIM2 = 72 MHz

        Flash 等待周期 = 2 (LATENCY_2)

        PWR 时钟使能, AFIO 时钟使能 (JTAG 禁用, 保留 SWD)

 

4-2 STM32 时钟树配置

4.3 脉冲生成与中断机制

┌──────────────────┐     ┌──────────────────┐     ┌──────────────────┐     ┌──────────────────┐

│ 1. Stepper_Move()│────▶│ 2. TIM2 PWM      │────▶│ 3. 更新中断      │────▶│ 4. 步数计数      

│    计算 ARR      │     │    PA0 输出脉冲  │     │    TIM2_IRQ      │     │    step_count++  │

│    设方向        │     │    CCR1=72 (1μs) │     │    每周期触发    │     │    position+=dir │

│    启动 PWM      │     │                  │     │                  │     │                  │

└──────────────────┘     └──────────────────┘     └──────────────────┘     └────────┬─────────┘

                                                                               

                                          ┌────────────────────────────────────┘

                                          

                                    ┌─────────────┐     否     ┌──────────────┐

                                    到达目标?  │───────────▶│ 继续 PWM     │

                                    └──────┬──────┘            └──────────────┘

                                      

                                          

                               ┌──────────────────┐

                               │ 5. 停止 PWM       │

                               │    禁中断         

                               │    complete=1     │

                               └──────────────────┘

 

    主循环: while(!Stepper_IsComplete()) {} → 检测完成标志 进入下一次运动

 

4-3 脉冲生成与中断计数流程

4.4 TIM2 定时器配置详解

定时器时钟:  72 MHz (APB1 = 36 MHz, 定时器自动 ×2)

预分频 PSC:   0 (不分频)

计数模式:    向上计数

PWM 模式:    PWM1 (CNT < CCR1 时输出高)

ARR:         动态修改 = 72000000 / speed - 1

CCR1:        72 (固定, 1μs 脉冲宽度)

ARR 预装载:   禁用 (即时生效)

中断:        TIM_IT_UPDATE, 优先级 2

 

脉冲频率 f = 72MHz / (ARR+1)

脉冲周期 T = (ARR+1) / 72MHz

高电平时间 = CCR1 / 72MHz = 72 / 72MHz = 1μs

 


5. 主要参数情况

5.1 电机与驱动参数

参数

说明

步距角 (整步)

1.8°

每整步旋转角度

每转整步数

200

360° / 1.8° = 200

电机类型

两相四线

A+/A-/B+/B- 四线输出

驱动模式

STEP/DIR standalone

UART, 纯引脚控制

默认细分

1/16

MS2=1, MS1=1 (上电默认)

5.2 脉冲频率与转速关系

核心公式:f = RPM × 200 × microstep / 60 (Hz)

细分

每转脉冲数

50 RPM

100 RPM

150 RPM

300 RPM

600 RPM

1/1 全步

200

167 Hz

333 Hz

500 Hz

1,000 Hz

2,000 Hz

1/8

1,600

1,333 Hz

2,667 Hz

4,000 Hz

8,000 Hz

16,000 Hz

1/16

3,200

2,667 Hz

5,333 Hz

8,000 Hz

16,000 Hz

32,000 Hz

1/32

6,400

5,333 Hz

10,667 Hz

16,000 Hz

32,000 Hz

64,000 Hz

1/64

12,800

10,667 Hz

21,333 Hz

32,000 Hz

64,000 Hz

128,000 Hz

5.3 定时器约束参数

约束项

说明

TIM2 时钟频率

72,000,000 Hz

STEPPER_TIM_FREQ 宏定义

ARR 上限

65,535

16 位定时器寄存器上限

ARR 安全下限

200

STEPPER_MIN_ARR, 防脉冲过窄

最小脉冲频率

1,097 Hz

72MHz / 65536 ≈ 1098 Hz

最大脉冲频率

24,000,000 Hz

72MHz / 3 (ARR_MIN=200 )

代码限速下限

1,100 Hz

Stepper_Move() 内部保护值

代码限速上限

300,000 Hz

Stepper_Move() 内部保护值

脉冲宽度

1 μs

CCR1 = 72, 固定不变

5.4 演示程序配置表

主循环依次遍历以下 8 种配置,每种配置正转 2 1s → 反转 2 1s

序号

细分

每转脉冲数

脉冲频率 (Hz)

等效转速 (RPM)

每次步数 (2)

0

1/8

1,600

1,333

50

3,200

1

1/8

1,600

2,667

100

3,200

2

1/8

1,600

4,000

150

3,200

3

1/8

1,600

8,000

300

3,200

4

1/16

3,200

2,667

50

6,400

5

1/16

3,200

5,333

100

6,400

6

1/16

3,200

8,000

150

6,400

7

1/16

3,200

16,000

300

6,400

约束注意

全步模式下,低于 330 RPM 时脉冲频率 < 1100 HzARR 超过 65535 导致 16 位定时器溢出。

解决方案 1:给 TIM2 加预分频 (PSC > 0) 降低时钟;

解决方案 2:切换到微步模式,同转速下脉冲频率按微步倍数提高。

 


6. 实现步骤

1. STM32CubeMX 工程配置

STM32CubeMX V6.15.0 中选择 MCU 型号 STM32F103CBT6 (LQFP48)。配置 HSE 为外部晶振 8MHzPLL 倍频 ×9 生成 SYSCLK 72MHzAPB1 预分频 /2 = 36MHz (TIM2 时钟自动 ×2 = 72MHz)APB2 = 72MHzFlash 等待周期设为 2

2. GPIO 引脚配置

配置 PA0 TIM2_CH1 复用推挽输出 (STEP 脉冲)PA1~PA4 为推挽输出 (DIR/ENN/MS1/MS2)PA9/PA10 配置为 USART1_TX/RX (预留)PA13/PA14 保留为 SWD 调试接口。在 MSP 初始化中禁用 JTAG,仅保留 SWD

3. TIM2 PWM 定时器配置

配置 TIM2 PWM 模式 1,通道 1 输出。PSC=0 (不分频)ARR 初始值 1000 (后续动态修改)CCR1=72 (1μs 脉冲宽度)。使能 TIM2 更新中断,NVIC 优先级设为 2。禁用 ARR 预装载以确保频率切换即时生效。

4. 生成代码框架

使用 STM32CubeMX 生成 Keil MDK-ARM V5.32 工程。生成内容包括:startup_stm32f103xb.s 启动文件、system_stm32f1xx.c 系统初始化、HAL 驱动库、外设初始化函数 (MX_GPIO_Init, MX_TIM2_Init, MX_USART1_UART_Init)、中断服务框架 (stm32f1xx_it.c)

5. 编写 TMC2209 驱动层 (tmc2209.c/h)

定义引脚宏 (STEP/DIR/ENN/MS1/MS2 端口和引脚号)。实现方向枚举 (CW/CCW) 和微步枚举 (1/8, 1/16, 1/32, 1/64)。实现 TMC2209_Init() 初始化引脚状态 (ENN=HIGH 失能, DIR=LOW 顺时针, MS=1/16)。实现 apply_microstep_pins() 根据 MS2/MS1 真值表输出引脚电平。实现使能/失能/方向/细分设置函数及状态查询函数。

6. 编写运动控制层 (stepper.c/h)

定义 Stepper_t 结构体 (running/step_count/target_steps/position/direction/complete)。定义硬件常量 (TIM_FREQ=72MHz, PULSE_WIDTH=72, MIN_ARR=200, ARR_MAX=65535, MIN_SPEED=1097, MAX_SPEED=24000000)。实现 Stepper_Move(steps, dir, speed):速度保护方向设置→ARR 计算状态初始化启动 PWM+中断。实现 Stepper_TIM2_IRQHandler():计数位置更新到达目标后停止。实现停止/状态查询/完成标志清除函数。

7. 编写主程序 (main.c)

定义微步/速度配置表 s_cfg_table[],包含 8 种组合 (1/8 1/16 4 档转速)。在 main() 中依次初始化 HAL→时钟→GPIO→TIM2→USART1→TMC2209→Stepper。使能驱动后进入主循环:取配置设细分正转 N 等完成1s→反转 N 等完成1s→切换下一配置。

8. 中断服务函数对接

stm32f1xx_it.c 中实现 TIM2_IRQHandler(),直接调用 Stepper_TIM2_IRQHandler()。该函数检查更新中断标志,清除标志后执行步数计数和完成判断。

9. 编译与烧录

Keil MDK-ARM 中编译工程 (ARMCC V5.06, -O1 优化, C99 模式)。使用 J-Link 通过 SWD 接口烧录 HEX 文件到 STM32F103CBT6。验证电机按预期正反转,观察不同微步/转速下的运行效果。

10. 调试与验证

通过 J-Link 在线调试,观察 s_stepper 结构体变量变化,验证步数计数和位置追踪。使用示波器测量 PA0 脉冲波形,确认脉冲频率和 1μs 脉宽。验证细分切换后电机运行精度。确认 ARR 在各种速度下不溢出 16 位范围。


7. 软件调试要点

7.1 调试环境

调试器

J-Link (SWD 接口, PA13/PA14)

IDE

Keil MDK-ARM V5.32

编译器优化

-O1 (Level 1)

调试信息

包含 (Debug 模式)

Flash 烧录地址

0x08000000 (128KB)

堆栈配置

Stack 0x400 (1KB), Heap 0x200 (512B)

7.2 关键调试变量

// Keil Watch 窗口中监控以下变量:

s_stepper.running       // 1=运动中, 0=停止

s_stepper.step_count    // 已完成步数 (递增)

s_stepper.target_steps  // 目标步数

s_stepper.position      // 绝对位置 (有符号, 正负表示方向)

s_stepper.direction     // +1=CW, -1=CCW

s_stepper.complete      // 1=运动完成

 

// TMC2209 驱动状态:

s_direction             // 当前方向

s_enabled               // 使能状态

s_microstep             // 当前细分设置

 

7.3 常见问题与排查

现象

原因

排查方法

电机不转

ENN 为高 (失能)

检查 PA2 电平,确认 TMC2209_Enable() 已调用

电机抖动/堵转

脉冲频率过高或供电不足

降低 speed 参数,检查 12V 电源电流是否充足

步数不准

中断被更高优先级抢占

确认 TIM2 中断优先级 (2) 足够高,SysTick 15

ARR 溢出

低转速下 ARR > 65535

检查 speed 是否 >= 1100,或使用微步模式

细分切换异常

运动中切换 MS 引脚

确保在 Stepper_IsComplete() 后再切换细分

方向错误

DIR 电平与预期相反

检查 TMC2209_SetDirection() 逻辑,CW=LOW, CCW=HIGH

HardFault

栈溢出或空指针

检查调用栈,Stack 最大使用 152B (配置 1024B)

7.4 示波器验证要点

PA0 (STEP) 波形验证

使用示波器探头测量 PA0 引脚波形,验证:

  脉冲高电平宽度 = 1μs (CCR1=72 @ 72MHz)

  脉冲频率 = 配置表中的 speed (1333 Hz, 2667 Hz )

  波形为标准方波,上升沿/下降沿陡峭

  运动期间持续输出,停止后立即拉低

 

7.5 编译输出分析

输出文件

TMC2209_SD_TEST.hex / .axf

最大栈使用

152 字节 (配置 1024B, 使用率 15%)

堆配置

512 字节

Flash 起始地址

0x08000000

RAM 起始地址

0x20000000

编译状态

0 Error, 0 Warning


8. 项目代码清单

8.1 源文件结构

TMC2209_SD_TEST/

├── TMC2209_SD_TEST.ioc              # STM32CubeMX 配置文件

├── keilkilll.bat                    # 编译清理脚本

├── Core/

│   ├── Inc/                         # 头文件目录

│   │   ├── main.h                   # 主头文件 (引脚宏定义)

│   │   ├── tmc2209.h                # TMC2209 驱动 HAL 层头文件

│   │   ├── stepper.h                # 步进电机控制头文件

│   │   ├── stm32f1xx_it.h          # 中断处理声明

│   │   └── stm32f1xx_hal_conf.h    # HAL 库配置

│   │

│   └── Src/                         # 源文件目录

│       ├── main.c                   # 主程序 (303)

│       ├── tmc2209.c                # TMC2209 驱动实现 (97)

│       ├── stepper.c                # 步进电机控制实现 (119)

│       ├── stm32f1xx_it.c          # 中断服务函数 (213)

│       ├── stm32f1xx_hal_msp.c     # HAL MSP 回调 (26)

│       └── system_stm32f1xx.c      # CMSIS 系统初始化

├── Drivers/                         # HAL 驱动库 + CMSIS

│   ├── CMSIS/                       # ARM CMSIS 核心 + DSP + NN

│   └── STM32F1xx_HAL_Driver/        # STM32F1 HAL 驱动源码

└── MDK-ARM/                         # Keil 工程目录

    ├── TMC2209_SD_TEST.uvprojx      # Keil 工程文件

    ├── startup_stm32f103xb.s        # 启动汇编文件

    ├── JLinkSettings.ini            # J-Link 设置

    └── TMC2209_SD_TEST/             # 编译输出

        ├── TMC2209_SD_TEST.hex      # HEX 烧录文件

        ├── TMC2209_SD_TEST.axf      # 可执行文件

        └── TMC2209_SD_TEST.map      # 内存映射表

 

8.2 核心代码 — tmc2209.c 驱动层

// TMC2209 细分引脚控制 — MS2/MS1 真值表

static void apply_microstep_pins(TMC2209_Microstep_t microstep)

{

    GPIO_PinState ms1, ms2;

    switch (microstep) {

        case TMC2209_MICROSTEP_8:   ms2=RESET; ms1=RESET; break; /* 1/8  */

        case TMC2209_MICROSTEP_32:  ms2=RESET; ms1=SET;   break; /* 1/32 */

        case TMC2209_MICROSTEP_64:  ms2=SET;   ms1=RESET; break; /* 1/64 */

        case TMC2209_MICROSTEP_16:

        default:                    ms2=SET;   ms1=SET;   break; /* 1/16 */

    }

    HAL_GPIO_WritePin(TMC2209_MS1_PORT, TMC2209_MS1_PIN, ms1);

    HAL_GPIO_WritePin(TMC2209_MS2_PORT, TMC2209_MS2_PIN, ms2);

}

 

// 使能驱动 (ENN 低有效)

void TMC2209_Enable(void) {

    HAL_GPIO_WritePin(TMC2209_EN_PORT, TMC2209_EN_PIN, GPIO_PIN_RESET);

    s_enabled = 1U;

}

 

8.3 核心代码 — stepper.c 运动控制

// 启动定频脉冲运动

int8_t Stepper_Move(uint32_t steps, uint8_t dir, uint32_t speed)

{

    if (steps == 0U) { return -2; }

    if (s_stepper.running) { return -1; }

 

    /* 速度保护 */

    if (speed < MIN_SPEED) { speed = MIN_SPEED; }

    if (speed > MAX_SPEED) { speed = MAX_SPEED; }

 

    /* 方向设置 */

    if (dir == (uint8_t)TMC2209_DIR_CCW) {

        TMC2209_SetDirection(TMC2209_DIR_CCW);

        s_stepper.direction = -1;

    } else {

        TMC2209_SetDirection(TMC2209_DIR_CW);

        s_stepper.direction = 1;

    }

 

    /* ARR 计算: 72MHz / speed - 1 */

    uint32_t arr = STEPPER_TIM_FREQ / speed;

    if (arr > STEPPER_TIM_ARR_MAX) { arr = STEPPER_TIM_ARR_MAX; }

    if (arr < STEPPER_MIN_ARR) { arr = STEPPER_MIN_ARR; }

 

    s_stepper.step_count   = 0U;

    s_stepper.target_steps = steps;

    s_stepper.complete     = 0U;

    s_stepper.running      = 1U;

 

    __HAL_TIM_SET_COUNTER(&htim2, 0U);

    __HAL_TIM_SET_AUTORELOAD(&htim2, arr - 1U);

    __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, STEPPER_PULSE_WIDTH);

 

    __HAL_TIM_CLEAR_FLAG(&htim2, TIM_FLAG_UPDATE);

    __HAL_TIM_ENABLE_IT(&htim2, TIM_IT_UPDATE);

    HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);

 

    return 0;

}

 

// TIM2 更新中断 步数计数与停止

void Stepper_TIM2_IRQHandler(void)

{

    if (__HAL_TIM_GET_FLAG(&htim2, TIM_FLAG_UPDATE) == RESET) return;

    __HAL_TIM_CLEAR_FLAG(&htim2, TIM_FLAG_UPDATE);

 

    s_stepper.step_count++;

    s_stepper.position += s_stepper.direction;

 

    if (s_stepper.step_count >= s_stepper.target_steps) {

        HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_1);

        __HAL_TIM_DISABLE_IT(&htim2, TIM_IT_UPDATE);

        s_stepper.running  = 0U;

        s_stepper.complete = 1U;

    }

}

 

8.4 核心代码 — main.c 主循环

// 微步/速度配置表

MicrostepRevolutionCfg_t s_cfg_table[] = {

    { TMC2209_MICROSTEP_8,  FPPR *  8U, 1333U  },  /* 50 rpm  */

    { TMC2209_MICROSTEP_8,  FPPR *  8U, 2667U  },  /* 100 rpm */

    { TMC2209_MICROSTEP_8,  FPPR *  8U, 4000U  },  /* 150 rpm */

    { TMC2209_MICROSTEP_8,  FPPR *  8U, 8000U  },  /* 300 rpm */

    { TMC2209_MICROSTEP_16, FPPR * 16U, 2667U  },  /* 50 rpm  */

    { TMC2209_MICROSTEP_16, FPPR * 16U, 5333U  },  /* 100 rpm */

    { TMC2209_MICROSTEP_16, FPPR * 16U, 8000U  },  /* 150 rpm */

    { TMC2209_MICROSTEP_16, FPPR * 16U, 16000U },  /* 300 rpm */

};

 

// 主循环: 正转 反转 切换配置

while (1) {

    cfg = &s_cfg_table[cfg_idx];

    TMC2209_SetMicrostep(cfg->microstep);

    HAL_Delay(10);

 

    /* 正转 N */

    Stepper_Move(cfg->steps_per_revolution * TARGET_COUNT,

                 TMC2209_DIR_CW, cfg->speed);

    while (!Stepper_IsComplete()) {}

    Stepper_ClearCompleteFlag();

 

    HAL_Delay(1000);

 

    /* 反转 N */

    Stepper_Move(cfg->steps_per_revolution * TARGET_COUNT,

                 TMC2209_DIR_CCW, cfg->speed);

    while (!Stepper_IsComplete()) {}

    Stepper_ClearCompleteFlag();

 

    HAL_Delay(1000);

    cfg_idx = (cfg_idx + 1U) % cfg_len;

}

 

8.5 编译参与文件分组

Application/MDK-ARM

startup_stm32f103xb.s

Application/User/Core

main.c, stm32f1xx_it.c, stm32f1xx_hal_msp.c, stepper.c, tmc2209.c

Drivers/STM32F1xx_HAL_Driver

hal.c, hal_rcc.c, hal_gpio.c, hal_tim.c, hal_uart.c, hal_dma.c, hal_cortex.c, hal_pwr.c, hal_flash.c, hal_exti.c

Drivers/CMSIS

system_stm32f1xx.c

预定义宏

USE_HAL_DRIVER, STM32F103xB

头文件路径

../Core/Inc; ../Drivers/STM32F1xx_HAL_Driver/Inc; ../Drivers/CMSIS/Device/ST/STM32F1xx/Include; ../Drivers/CMSIS/Include


9. 如何开启运行

9.1 硬件准备

器件

规格

说明

STM32F103CBT6 最小系统板

LQFP48, 72MHz, 128KB Flash

需有 8MHz 外部晶振

TMC2209 驱动模块

standalone 模块 (MS1/MS2 排针)

STEP/DIR/ENN/MS1/MS2 接口

步进电机

两相四线, 1.8° 步距角

NEMA17 或类似规格

直流电源

12V, ≥2A

电机供电

J-Link 调试器

SWD 接口

程序烧录与调试

杜邦线若干

母对母 / 公对母

板间连接

9.2 接线

STM32          TMC2209 模块

─────────────────────────────

PA0  ────────→  STEP

PA1  ────────→  DIR

PA2  ────────→  ENN

PA3  ────────→  MS1

PA4  ────────→  MS2

GND  ────────  GND   (共地)

 

TMC2209        步进电机

─────────────────────────────

A1   ────────→  线圈 A+

A2   ────────→  线圈 A-

B1   ────────→  线圈 B+

B2   ────────→  线圈 B-

 

TMC2209        电源

─────────────────────────────

VS   ────────→  +12V

GND  ────────→  GND

 

J-Link         STM32

─────────────────────────────

SWDIO ───────→  PA13

SWCLK ───────→  PA14

GND   ───────→  GND

Vref ────────→  3.3V

 

9.3 编译与烧录步骤

打开工程

双击 MDK-ARM\TMC2209_SD_TEST.uvprojx 打开 Keil MDK-ARM V5.32 工程。确认已安装 STM32F1xx DFP (Device Family Pack)

编译

F7 或点击 Build 按钮。预期输出: 0 Error(s), 0 Warning(s)。输出文件: MDK-ARM\TMC2209_SD_TEST\TMC2209_SD_TEST.hex

连接硬件

9.2 节接线表连接 STM32TMC2209、电机和电源。先接好所有线缆再上电。12V 电源给 TMC2209 供电,STM32 可由 J-Link 供电或独立 3.3V

烧录

F8 或点击 Download 按钮,通过 J-Link SWD 将程序烧录到 STM32。也可使用 J-Flash 直接烧录 HEX 文件。烧录完成后程序自动运行。

观察运行

上电后程序自动开始运行:电机先以 1/8 细分 50 RPM 正转 2 1s → 反转 2 1s → 切换到 100 RPM → ... 依此循环 8 种配置。

在线调试 (可选)

Ctrl+F5 进入调试模式。在 Watch 窗口添加 s_stepper 结构体变量,观察 step_countpositionrunning 等字段变化。可设置断点在 Stepper_TIM2_IRQHandler 验证中断计数。

9.4 修改配置指南

// 修改目标旋转圈数 (stepper.h):

#define TARGET_COUNT  2U    // 改为你需要的圈数

 

// 添加/修改转速配置 (main.c):

static const MicrostepRevolutionCfg_t s_cfg_table[] = {

    { TMC2209_MICROSTEP_16, FPPR * 16U, 5333U },  /* 100 RPM, 1/16 */

    // 添加更多配置...

};

 

// 计算脉冲频率: f = RPM × 200 × microstep / 60

// 示例: 600 RPM, 1/16 微步 → f = 600 × 200 × 16 / 60 = 32000 Hz

// 调用: Stepper_Move(3200 * 2, TMC2209_DIR_CW, 32000);

 

运行验证清单

  上电后电机立即开始转动 (延时约 10ms 用于细分切换稳定)

  正转 2 圈后停顿 1s,然后反转 2 圈回到原位

  • 8 种配置依次切换,转速和细分档位可见明显变化

  低转速 (50 RPM) 运行平稳,高转速 (300 RPM) 无堵转

  • 1/16 细分下运行噪音低于 1/8 细分

 效果演示:

image.png

TMC2209 步进电机控制项目报告 生成于 2026-07-12



专家
2026-07-12 22:08:59     打赏
2楼

好详细啊,2209的驱动范围还是很宽的


院士
2026-07-14 18:43:47     打赏
3楼

这么多的字,还需要自已一点一点的审,也挺麻烦的啊


共3条 1/1 1 跳转至

回复

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