Funpack4-3 使用TMC4361A-BOB&TMC2160-BOB板卡连接步进电机实现电机控制
该项目使用了TMC4361A-BOB&TMC2160-BOB,实现了电机控制的设计,它的主要功能为:使用TMC4361A-BOB&TMC2160-BOB板卡连接步进电机实现电机控制。
标签
步进电机
TMC2160
TMC4361A
冲向天空的猪
更新2026-02-02
15

基于TMC4361A与TMC2160的步进电机控制系统项目总结报告

一、项目描述

1.1 项目介绍

本项目旨在开发一个基于TMC4361A运动控制器和TMC2160步进电机驱动器的电机控制系统,通过MicroPython编程实现对步进电机的精确控制。系统实现了定速旋转、指定角度旋转、指定圈数旋转以及正反转切换等核心功能.

TMC4361A是一款高性能运动控制器,支持多种运动模式,包括速度模式和位置模式,能够实现精确的速度和位置控制。TMC2160则是功能强大的步进电机驱动芯片,具有StealthChop2静音技术和SpreadCycle技术,能够在不同工况下提供出色的电机性能。

本项目采用模块化设计思想,将硬件控制、运动逻辑和用户交互分离,通过面向对象的方式构建了完整的电机控制系统架构。系统支持实时速度调节和精确定位,具有良好的可扩展性和易用性。

1.2 设计思路

本项目的整体设计遵循"分层解耦、模块化实现"的原则,主要包含以下几个层次:

硬件抽象层:设计通用的SPI通信类,封装底层SPI通信协议,提供统一的寄存器读写接口。这一层屏蔽了具体的硬件通信细节,为上层提供标准化的数据传输服务。

驱动控制层:分别实现TMC2160驱动器和TMC4361A控制器的封装类。TMC2160类负责电机驱动器的初始化和配置,包括电流设置、微步控制等;TMC4361A类负责运动控制逻辑,包括速度模式、位置模式的切换和运动参数配置。

系统接口层:设计MotorSystem类作为系统的统一接口,整合驱动器和控制器的功能,提供简洁易用的API,如speed()、angle()、turn()等方法,隐藏底层实现细节。

用户交互层:通过命令行接口实现用户与系统的交互,支持简单的命令解析和参数处理,使用户能够方便地测试和控制电机运动。

二、硬件介绍

2.1 硬件平台

本系统采用以下硬件平台:

  • 主控制器:RP2040
  • 运动控制器:TMC4361A-BOB评估板
  • 电机驱动器:TMC2160-BOB评估板
  • 执行机构:步进电机(标准200步/圈,支持256微步)

2.2 TMC4361A运动控制器

TMC4361A是一款高度集成的运动控制器,具有以下特点:

  • 支持多种运动模式:速度模式、位置模式、斜坡发生器模式
  • 内置加速和减速斜坡发生器,可实现平滑的运动曲线
  • 支持24位位置计数器和32位速度设定
  • 通过SPI接口进行配置和控制
  • 内置编码器接口(本项目中未使用)

TMC4361A的核心寄存器包括:

  • 0x00(GLOBAL_CONFIG):全局配置寄存器
  • 0x20(RAMP_MODE):运动模式选择(0x00=速度模式,0x04=位置模式)
  • 0x21(X_ACTUAL):当前实际位置寄存器
  • 0x24(V_MAX):最大速度寄存器
  • 0x28(A_MAX):最大加速度寄存器
  • 0x37(X_TARGET):目标位置寄存器

2.3 TMC2160电机驱动器

TMC2160是一款高性能步进电机驱动芯片,主要特性包括:

  • 支持高达46V的电机电压和4.5A的相电流
  • StealthChop2静音技术:在低速时实现几乎静音的电机运行
  • SpreadCycle技术:在高速时提供高精度的电流控制
  • 支持256微步分辨率
  • StallGuard2无传感器堵转检测
  • CoolStep动态电流调节,降低功耗

TMC2160的关键配置寄存器:

  • 0x00(GCONF):全局配置寄存器
  • 0x10(IHOLD_IRUN):电流控制寄存器(运行电流和保持电流)
  • 0x6C(CHOPCONF):斩波配置寄存器

2.4 硬件连接

系统通过SPI总线连接各个模块:

  • SPI时钟(SCK):连接到GPIO 18
  • SPI主机输出从机输入(MOSI):连接到GPIO 19
  • SPI主机输入从机输出(MISO):连接到GPIO 16
  • TMC2160片选(CS_DRV):连接到GPIO 17
  • TMC4361A片选(CS_CTRL):连接到GPIO 0
  • 时钟输出(CLK):连接到GPIO 15,输出16MHz参考时钟

SPI通信参数:波特率1Mbps,极性=1,相位=1(CPOL=1,CPHA=1)c9ea5b18eb9d223e89c13dc0ddebcf94.jpg


三、软件设计

3.1 系统架构

系统采用三层架构设计:

┌─────────────────────────────────────┐
│     用户交互层 (Main Loop)         │
│ 命令解析 -> 参数处理 -> 调用接口     │
└─────────────────────────────────────┘
                ↓
┌─────────────────────────────────────┐
│     系统接口层 (MotorSystem)       │
speed(), angle(), turn() 统一接口   │
└─────────────────────────────────────┘
                ↓
┌─────────────────────────────────────┐
│   控制层 (TMC4361A)驱动层 (TMC2160)
│ 运动模式管理     │ 电机驱动配置     │
└─────────────────────────────────────┘
                ↓
┌─────────────────────────────────────┐
│     硬件抽象层 (TMC_SPI_Device)     │
SPI通信、寄存器读写、数据转换       │
└─────────────────────────────────────┘
                ↓
┌─────────────────────────────────────┐
│         硬件层                     │
TMC4361A, TMC2160, 步进电机         │
└─────────────────────────────────────┘

3.2 软件流程图

主程序流程图

开始

初始化SPIGPIO

创建MotorSystem实例

等待用户输入

解析命令 (v/a/t/stop/exit)

  ├─ v: 速度模式 → 设置VMAX
  ├─ a: 角度模式 → 计算目标位置
  ├─ t: 圈数模式 → 计算目标位置
  ├─ stop: 停止 → 设置VMAX=0
  └─ exit: 退出 → 程序结束

返回等待输入

速度模式控制流程

调用speed(rps)

设置RAMP_MODE = 0x00 (速度模式)

计算速度值: vel = rps × 51200 × 256

处理负速度(使用补码表示)

写入VMAX寄存器 (0x24)

电机以指定速度持续旋转

位置模式控制流程

调用move_relative(delta_steps)

设置VMAX = 0 (安全停止)

设置RAMP_MODE = 0x04 (位置模式)

读取当前实际位置X_ACTUAL (0x21)

计算目标位置: target = current + delta

写入X_TARGET寄存器 (0x37)

恢复VMAX = 51200 << 8 (设定运行速度)

电机运动到目标位置后自动停止

3.3 核心代码实现及说明

3.3.1 SPI通信基础类

class TMC_SPI_Device:
   def __init__(self, spi, cs_pin):
       self.spi = spi
       self.cs = machine.Pin(cs_pin, machine.Pin.OUT, value=1)
       self.buf = bytearray(5)

   def _transfer(self, address, value=0, write=False):
       addr_byte = (address & 0x7F) | (0x80 if write else 0x00)
       self.buf[0] = addr_byte
       self.buf[1] = (value >> 24) & 0xFF
       self.buf[2] = (value >> 16) & 0xFF
       self.buf[3] = (value >> 8) & 0xFF
       self.buf[4] = value & 0xFF
       self.cs.low()
       receive_buf = bytearray(5)
       self.spi.write_readinto(self.buf, receive_buf)
       self.cs.high()
       return (receive_buf[1] << 24) | (receive_buf[2] << 16) |
              (receive_buf[3] << 8) | receive_buf[4]

代码说明

  • 这是基础的SPI通信类,封装了与TMC芯片的通信协议
  • _transfer方法实现了完整的5字节SPI传输协议
  • 第一个字节为地址字节,bit7表示读/写操作(1=写,0=读)
  • 后续4字节为32位数据(大端格式)
  • 使用write_readinto同时发送数据和接收响应

3.3.2 TMC2160驱动器初始化

class TMC2160(TMC_SPI_Device):
   def __init__(self, spi, cs_pin):
       super().__init__(spi, cs_pin)
       self.init_driver()

   def init_driver(self):
       self.write_reg(0x00, 0x00000008)
       self.write_reg(0x10, 0x000A0506)
       self.write_reg(0x6C, 0x000100C3)

代码说明

  • 0x00 (GCONF = 0x00000008):使能位置使能(shaft)位,允许电机转动
  • 0x10 (IHOLD_IRUN = 0x000A0506):
    • IHOLD(保持电流)= 6,节省能耗
    • IRUN(运行电流)= 10(约31%最大电流),提供足够扭矩
    • IHOLDDELAY(保持电流延迟)= 5,电机停止后逐步降低电流
  • 0x6C (CHOPCONF = 0x000100C3):
    • 使能StealthChop2静音模式
    • 配置微步为256细分,提高分辨率
    • 设置斩波参数,优化电机运行质量

3.3.3 TMC4361A速度控制实现

def rotate_constant(self, rps):
   """速度模式:rps为正负表示方向"""
   # 设置为速度模式
   self.write_reg(0x20, 0x00000000)
   
   # 计算速度:每秒脉冲数 × 2^8
   # 1 RPS = 51200 脉冲/
   vel = int(rps * 51200 * 256)
   
   # 处理负速度(使用补码表示)
   if vel < 0:
       vel = (0xFFFFFFFF + vel + 1) & 0xFFFFFFFF
       
   self.write_reg(0x24, vel)

代码说明

  • 速度模式通过RAMP_MODE=0x00设置
  • 速度计算公式:vel = rps × 51200 × 256
    • 51200 = 200步/圈 × 256微步
    • 256 = TMC4361A内部小数部分精度(24+8位格式)
  • 负速度使用补码表示,这是标准的32位有符号数表示方法
  • 写入VMAX寄存器后,电机将以指定速度持续旋转

3.3.4 TMC4361A位置控制实现

def move_relative(self, delta_steps):
   """位置模式:delta_steps为脉冲数"""
   # 1. 停止当前运动(安全措施)
   self.write_reg(0x24, 0)
   
   # 2. 切换到位置模式
   self.write_reg(0x20, 0x00000004)
   
   # 3. 读取当前位置
   current_pos = self.read_reg(0x21)
   if current_pos & 0x80000000:
       current_pos -= 0x100000000
       
   # 4. 设置目标位置
   target = current_pos + int(delta_steps)
   self.write_reg(0x37, target)
   
   # 5. 恢复速度(允许运动)
   self.write_reg(0x24, 51200 << 8)

代码说明

  • 步骤1:先将VMAX设为0,确保电机停止,避免模式切换时的冲击
  • 步骤2:设置RAMP_MODE=0x04,进入位置模式
  • 步骤3:读取X_ACTUAL寄存器获取当前位置
    • 处理有符号32位数的转换(最高位为1表示负数)
  • 步骤4:计算并写入X_TARGET寄存器,设定目标位置
    • 相对运动:目标 = 当前 + 增量
  • 步骤5:恢复VMAX值,触发电机运动
    • 默认速度约为1 RPS(51200 << 8)
    • 电机将按照配置的加速度曲线运动到目标位置

3.3.5 MotorSystem系统接口

class MotorSystem:
   def __init__(self, clk_pin=15, sck=18, mosi=19, miso=16,
                cs_drv=17, cs_ctrl=0):
       self.clk = machine.PWM(machine.Pin(clk_pin))
       self.clk.freq(16000000)
       self.clk.duty_u16(32768)  # 50%占空比
       self.spi = machine.SPI(0, baudrate=1000000, polarity=1,
                              phase=1, sck=machine.Pin(sck),
                              mosi=machine.Pin(mosi), miso=machine.Pin(miso))
       self.driver = TMC2160(self.spi, cs_pin=cs_drv)
       self.controller = TMC4361A(self.spi, cs_pin=cs_ctrl)
       self.steps_per_rev = 51200  # 200 × 256

   def speed(self, val):
       """速度模式:val为RPS"""
       self.controller.rotate_constant(val)
   
   def angle(self, val):
       """角度模式:val为度数"""
       self.controller.move_relative((val/360)*self.steps_per_rev)
   
   def turn(self, val):
       """圈数模式:val为圈数"""
       self.controller.move_relative(val*self.steps_per_rev)

代码说明

  • 初始化
    • 配置16MHz时钟输出,为TMC芯片提供参考时钟
    • 配置SPI接口,CPOL=1,CPHA=1(SPI模式3)
    • 初始化TMC2160驱动器和TMC4361A控制器
    • 定义每圈步数为51200(200步×256微步)
  • speed(val)
    • 输入参数单位:RPS(每秒转数)
    • 正值表示顺时针旋转,负值表示逆时针旋转
    • 直接调用控制器的速度模式方法
  • angle(val)
    • 输入参数单位:度数
    • 自动将角度转换为脉冲数:脉冲 = (角度/360) × 每圈步数
    • 支持正负角度(正角度顺时针,负角度逆时针)
  • turn(val)
    • 输入参数单位:圈数
    • 自动将圈数转换为脉冲数:脉冲 = 圈数 × 每圈步数
    • 支持正负圈数(正数顺时针,负数逆时针)

3.3.6 用户交互主程序

try:
   motor = MotorSystem()
   print("System Online. Format: <v/a/t> <value>")
   while True:
       raw = input(">> ").strip().lower().split()
       if not raw: continue
       cmd, val = raw[0], float(raw[1]) if len(raw)>1 else 0
       
       if cmd == 'v':
           motor.speed(val)
           print(f"V-Mode: {val} RPS")
       elif cmd == 'a':
           motor.angle(val)
           print(f"P-Mode: {val} deg")
       elif cmd == 't':
           motor.turn(val)
           print(f"P-Mode: {val} turns")
       elif cmd == 'stop':
           motor.controller.stop()
           print("Stopped.")
       elif cmd == 'exit':
           break
except Exception as e:
   print(f"Error: {e}")

代码说明

  • 命令格式<命令> <数值>
  • 支持的命令
    • v <RPS>:速度模式,电机以指定RPS持续旋转
    • a <度数>:角度模式,电机旋转指定角度后停止
    • t <圈数>:圈数模式,电机旋转指定圈数后停止
    • stop:立即停止电机运动
    • exit:退出程序image.png


具体效果展示参考b站视频


附件下载
main_demo.py
团队介绍
个人
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号