树莓派 Pico 步进电机控制进阶:PIO 非阻塞式实现全指南

PIO 控制步进电机

这里,我们使用 PIO 实现步进电机单相驱动控制,关于单相驱动控制方法简单来说就是通过控制步进电机 4 对绕组的通断顺序和频率从而实现电机运动的精确角度和速度控制,具体内容可以查看 第四节GPIO通用输入输出 中关于步进电机的介绍,这里不再赘述。

可以看到,之前使用 GPIO 驱动步进电机时通常需要在主程序中通过循环和延时来控制引脚状态,这种方式会阻塞主程序导致 CPU 无法同时处理其他任务,而 PIO 是一个独立的硬件外设,可以并行运行,主程序可以继续执行其他任务(如处理传感器数据、通信等),而 PIO 负责精确控制步进电机。

并且,GPIO 的时序控制依赖于软件延时(如 time.sleep_ms()),其精度受限于操作系统的调度和 CPU 负载,但 PIO 可以以固定的时钟频率运行,提供更为精确的时序控制。

这里,我们使用风雅一号板-通用兼容扩展板上的长排针连接风雅一号板-步进电机驱动板上逻辑输入部分接口,使用引脚如下表所示:

ScreenShot_2026-06-09_193753_127.png

然后使用步进电机驱动板上逻辑输出部分接口与步进电机连接:

1280X1280 (4).PNG

同时,打开风雅一号板-步进电机驱动板上的拨码开关:

1280X1280.PNG

整体连接情况如下图所示:

1280X1280 (1).PNG

以下代码可以在我们提供的资料包中 elegance-devkit v1\Demo\34 PIO_StepMotor 文件夹找到。

示例代码如下:

# Python env   : MicroPython v1.23.0
# -*- coding: utf-8 -*-        
# @Time    : 2024/7/27 下午1:07   
# @Author  : 李清水            
# @File    : main.py       
# @Description : PIO类实验,通过PIO控制步进电机转动

# ======================================== 导入相关模块 ========================================

# 导入硬件相关的模块
from machine import Pin
# 导入PIO相关的模块
import rp2
# 导入时间相关的模块
import time

# ======================================== 全局变量 ============================================

# ======================================== 功能函数 ============================================

# @rp2.asm_pio装饰器用于定义一个 PIO 程序
# 在这里,它设置了 4 个 GPIO 引脚的初始状态为低电平,这四个引脚为set pin
@rp2.asm_pio(set_init=(rp2.PIO.OUT_LOW, rp2.PIO.OUT_LOW,
                       rp2.PIO.OUT_LOW, rp2.PIO.OUT_LOW))
def step_motor() -> None:
    """
​    定义步进电机控制的 PIO 程序。

​    Args:
​        None

​    Returns:
​        None

​    Description:
​        该 PIO 程序通过设置 4 个 GPIO 引脚的状态,控制步进电机的转动。
​        每个引脚依次设置为高电平,其他引脚为低电平,形成步进电机的单相控制序列。
​    """
​    ​# 标记了程序跳转目的地
    wrap_target()
    # 设置第一个引脚为高电平,其他引脚为低电平,后面的[7]表示这条指令执行后延时7个时钟周期
    # 考虑到set指令执行需要1个周期,步进电机每一步转动时间间隔为1 + 7 = 8 个时钟周期
    set(pins, 0b0001)   [7]
    # 依次设置其他 3 个引脚的状态,构成了完整的步进电机单相控制序列
    set(pins, 0b0010)   [7]
    set(pins, 0b0100)   [7]
    set(pins, 0b1000)   [7]
    # 将程序的执行跳转回wrap_target()处
    wrap()

# ======================================== 自定义类 ============================================

# ======================================== 初始化配置 ==========================================

# 上电延时3s
time.sleep(3)
# 打印调试信息
print("FreakStudio: Using PIO to control step motor")

# 初始化状态机实例:使用状态机 0运行step_motor()函数,PIO执行频率等于 系统时钟频率/2000
# 设置base pin(一系列当中引脚的第一个)为 GPIO 2
sm = rp2.StateMachine(0, step_motor, freq=2000, set_base=Pin(2))
sm.active(1)

# ========================================  主程序  ===========================================

while True:
    pass

这里,在 PIO 程序中我们通过 set 语句写入 4 位二进制数据来控制步进电机 4 对绕组的通断(设置引脚为高电平则 1 对绕组导通):

ScreenShot_2026-06-09_193833_440.png

我们也可以使用也可以 set 语句写入十进制的 1、2、4、8 或十六进位的 0x1、0x2…,效果是一样的。

烧录代码,可以看到步进电机实现转动,通过 PIO 外设的使用,我们实现了步进电机的非阻塞式驱动:

9f458cbf-e5dc-48e5-9346-5e93cbe98c91.png

4a2f2f2b-9ac4-4c10-a913-e16398a38003.jfif

9.gif

posted @ 2026-09-01 16:33  FreakStudio  阅读(10)  评论(0)    收藏  举报