1. PICO开发环境
这次控制核心是树莓派PICO,采用的语言是基于circuitpython的Python语言。首先就来下载和安装下pico的circuitpython包。进入到CircuitPython的官网,就可以直接看到下载的链接。

pico的固件烧录也是出奇的方便,安装按钮插入电脑的USB就可以看到一个U盘设备,直接把固件拖进去就烧录好了。
烧录完成就可以看到如下的内容,这里面code.py就是上电执行的代码。

至此开发环境算是搭建好了。
2. 步进电机
这次我采用的是42步进电机,这里的42意思就是4线两相。找到一张拆解的42步进电机图如下:

可以看到电机有4个出线端子,按照如下的控制方式就可以让电机转动起来。

下面就来看看电机控制驱动了。
3. TMS2209
TMC2209 步进驱动芯片,原德国Trinamic(先被ADI亚德诺收购)研发,于2019年正式发布,主打经济型静音两相步进驱动,广泛用于3D打印、云台、自动化设备。其核心参数:
供电:电机电压4.75~29VDC,兼容工业级12/24V主流设备;
电流:峰值2.8A,有效值2A RMS。适配市面上绝大多数的42/35/28/20 的两相步进电机;
封装:QFN28(5*5mm)内置散热焊盘,内部上下桥Mos 共340mΩ;
双接口:STEP/DIR脉冲 + 单线UART
本次采用的驱动板原理图如下。

驱动板的作用就是将单片机传来的控制信号转换成我们前面第2节分析的相信号,相信号的顺序影响电机的转动方向,相信号的变化速率就影响电机的转动速度。最简单的就是在enable的情况下,通过控制dir,step就可以控制电机的转动。
# SPDX-FileCopyrightText: 2025 Liz Clark for Adafruit Industries
#
# SPDX-License-Identifier: MIT
import time
import board
from digitalio import DigitalInOut, Direction
import usb_cdc
serial = usb_cdc.console
DIR = DigitalInOut(board.GP2)
DIR.direction = Direction.OUTPUT
STEP = DigitalInOut(board.GP3)
STEP.direction = Direction.OUTPUT
EN = DigitalInOut(board.GP4)
EN.direction = Direction.OUTPUT
EN.value = False
microMode = 8
moving_forward = True
is_running = False
speed_level = 5
step_state = False
next_toggle_time = 0.0
last_status_str = ""
status_update_time = 0.0
def get_delay():
min_freq = 50.0
max_freq = 1200.0
freq = min_freq + (speed_level - 1) * (max_freq - min_freq) / 9.0
return 1.0 / (2.0 * freq)
def get_status_str():
state = "运行" if is_running else "停止"
direction = "前进" if moving_forward else "后退"
freq = 1.0 / (2.0 * get_delay())
return f"状态: {state} | 方向: {direction} | 速度: {speed_level}/10 | 频率: {freq:.0f}Hz"
def show_help():
print("\n" + "=" * 50)
print("步进电机控制 (TMC2209) 非阻塞版")
print("=" * 50)
print("引脚: DIR=GP2, STEP=GP3, EN=GP4")
print("命令:")
print(" w - 前进(并启动)")
print(" s - 后退(并启动)")
print(" d - 加速")
print(" a - 减速")
print(" 空格 - 停止/启动切换")
print("=" * 50)
show_help()
print("\n准备就绪,等待命令...\n")
print(get_status_str() + " > ", end='')
while True:
now = time.monotonic()
if serial.in_waiting > 0:
raw = serial.read(1)
if raw:
cmd = raw.decode('utf-8').lower()
if cmd == 'w':
moving_forward = True
is_running = True
last_status_str = ""
elif cmd == 's':
moving_forward = False
is_running = True
last_status_str = ""
elif cmd == ' ':
is_running = not is_running
last_status_str = ""
elif cmd == 'd':
speed_level = min(speed_level + 1, 10)
last_status_str = ""
elif cmd == 'a':
speed_level = max(speed_level - 1, 1)
last_status_str = ""
if is_running:
DIR.value = moving_forward
if now >= next_toggle_time:
step_state = not step_state
STEP.value = step_state
next_toggle_time = now + get_delay()
current_status = get_status_str()
if current_status != last_status_str and (now - status_update_time) >= 0.2:
print("\r" + " " * 60 + "\r" + current_status + " > ", end='')
last_status_str = current_status
status_update_time = now
time.sleep(0.0001)至此就可以在串口工具下对电机进行控制了。


我要赚赏金
