在上一篇帖子中,我已经将Raspberry Pi Pico-TMC2209-步进电机连接完毕Let'sdo2026年第1期—开箱与硬件连接-电子产品世界论坛,接下来我将基于MicroPython编写电机转动代码
程序需要实现以下功能:
1. STEP脉冲输出:使用 Pico 的 PWM 功能在 GP2 输出连续脉冲,作为 TMC2209 的 STEP 信号
2. DIR方向控制:使用 GP3 输出高低电平控制电机正反转
3. 两档速度控制
4. 加速/减速控制:逐步改变 STEP 频率,避免电机突然高速启动导致丢步
5. 方向切换保护:如果电机正在运行,并且需要切换方向,代码会先减速停下,再改变 DIR 电平,然后重新启动
接下来讲解代码
库函数导入和基本参数设定
from machine import Pin, PWM import time # ----------------------------- # Wiring: # Pico GP2 -> TMC2209 Step # Pico GP3 -> TMC2209 DIR # Pico GP4 -> TMC2209 EN # Pico 3V3 -> TMC2209 VIO # Pico GND -> TMC2209 GND # ----------------------------- STEP_PIN = 2 DIR_PIN = 3 EN_PIN = 4 step_pin = Pin(STEP_PIN, Pin.OUT) dir_pin = Pin(DIR_PIN, Pin.OUT) en_pin = Pin(EN_PIN, Pin.OUT) step_pwm = PWM(step_pin) # 如果方向和预期相反,把这里改成 True DIR_INVERT = False FULL_STEPS_PER_REV = 200 MICROSTEP = 16 STEPS_PER_REV = FULL_STEPS_PER_REV * MICROSTEP SLOW_SPEED = 320 # 约 6 rpm FAST_SPEED = 1600 # 约 30 rpm RAMP_STEP = 40 RAMP_DELAY = 0.02 current_speed = 0 current_direction = None
使能TMC2209:TMC2209 的 EN低电平有效,所以这里输出 0
def enable_driver(): # TMC2209 EN/ENN 通常低电平使能 en_pin.value(0) time.sleep_ms(50)
关闭驱动器:
关闭前会先调用 stop_motor() 停止 STEP 脉冲,然后将 EN 拉高,释放电机。
释放后电机不再保持力矩,可以手动转动,同时也能降低电机和驱动器发热。
def disable_driver(): stop_motor() time.sleep_ms(50) en_pin.value(1)
设置电机旋转方向
def apply_direction(clockwise=True): """ 设置 DIR。 注意:必须在 STEP 停止后调用更稳。 """ if DIR_INVERT: clockwise = not clockwise if clockwise: dir_pin.value(1) else: dir_pin.value(0) # 给 DIR 信号一点稳定时间 time.sleep_ms(10)
使用PWM输出STEP脉冲,可以调整频率控制电机转速
def set_step_frequency(freq_hz): global current_speed if freq_hz <= 0: stop_motor() return step_pwm.freq(int(freq_hz)) step_pwm.duty_u16(32768) # 50% duty current_speed = int(freq_hz)
停止STEP脉冲用于停止电机,但是并不会关闭TMC2209
def stop_motor(): global current_speed step_pwm.duty_u16(0) current_speed = 0 # 保证 STEP 静止为低电平 step_pin.value(0) time.sleep_ms(10)
将速度平滑地调整到目标转速
def ramp_to_speed(target_speed): global current_speed target_speed = int(target_speed) if target_speed <= 0: while current_speed > 0: current_speed -= RAMP_STEP if current_speed < 0: current_speed = 0 if current_speed == 0: stop_motor() else: set_step_frequency(current_speed) time.sleep(RAMP_DELAY) return if current_speed == 0: current_speed = RAMP_STEP set_step_frequency(current_speed) time.sleep(RAMP_DELAY) while current_speed != target_speed: if current_speed < target_speed: current_speed += RAMP_STEP if current_speed > target_speed: current_speed = target_speed else: current_speed -= RAMP_STEP if current_speed < target_speed: current_speed = target_speed set_step_frequency(current_speed) time.sleep(RAMP_DELAY)
按照指定方向和速度运行电机,如果当前电机正在运行,并且新方向和当前方向不同,它会先减速到 0,再切换方向
def run_speed(speed, clockwise=True): global current_direction enable_driver() # 如果正在运行,且方向要改变,先停稳 if current_speed > 0 and current_direction != clockwise: ramp_to_speed(0) time.sleep_ms(100) # 先设置方向,再启动 STEP apply_direction(clockwise) current_direction = clockwise ramp_to_speed(speed)
接下来设定快速转动,慢速转动以及按照指定rpm转动
def run_slow(clockwise=True): run_speed(SLOW_SPEED, clockwise) def run_fast(clockwise=True): run_speed(FAST_SPEED, clockwise) def run_rpm(rpm, clockwise=True): run_speed(rpm_to_step_freq(rpm), clockwise)
在主函数中,先正转慢速3秒,再反转慢速3秒,再正转快速3秒,再反转快速3秒
def main():
enable_driver()
print("Forward slow")
run_slow(True)
time.sleep(3)
print("Stop")
ramp_to_speed(0)
time.sleep(1)
print("Reverse slow")
run_slow(False)
time.sleep(3)
print("Stop")
ramp_to_speed(0)
time.sleep(1)
print("Forward fast")
run_fast(True)
time.sleep(3)
print("Stop")
ramp_to_speed(0)
time.sleep(1)
print("Reverse fast")
run_fast(False)
time.sleep(3)
print("Stop and release")
ramp_to_speed(0)
disable_driver()实现效果如下

完整工程代码如下
我要赚赏金
