前言
Raspberry Pi Pico 的 PIO 模块赋予开发者近乎极限的 IO 时序控制能力。而其中的 side-set 是一个能够“同时控制额外引脚状态”的超级武器。今天我们通过一个极简而优雅的工程级应用:使用 一个 LED 主闪烁引脚 + 一个状态引脚,来完整演示 side-set 的用法及优势。
side-set 是什么?
简而言之,side-set 让你能在一条 PIO 指令执行的同时控制某些 GPIO 引脚的电平,而不会占用额外的指令周期。
这样你可以并发控制多个 IO 状态变化,非常适合用来:
-
模拟通信协议中的同步信号(如 I2S 的 WS、SPI 的 CLK)
-
输出调试波形(示波器对拍神器)
-
控制多引脚状态机的切换信号
-
LED 状态指示
示例代码
PIO代码
@rp2.asm_pio(sideset_init=rp2.PIO.OUT_LOW, set_init=rp2.PIO.OUT_LOW)
def blink_1hz2():set(x, 31) .side(1) [6]label("delay_high")nop() [7]nop() [7]nop() [7]nop() [5]jmp(x_dec, "delay_high")set(x, 31) .side(0) [6]label("delay_low")nop() [7]nop() [7]nop() [7]nop() [5]jmp(x_dec, "delay_low")
代码分析
-
每半个周期共 961 个指令周期(根据 jmp(x_dec, "delay_*") 运行 31 次,每次 31 个周期;
-
2000Hz 状态机频率下,总共 1922个时钟周期,约1秒;
-
side-set 引脚控制led亮灭交替变化。
主程序代码
from machine import Pin
import rp2sm = rp2.StateMachine(0, blink_1hz2, freq=2000,sideset_base=Pin(25) # 控灯
)sm.active(1)
有个小知识点
可以看到这张图8~12位,写的是Delay/side-set,Delay是设置延时用的,比如:
nop() [7]
这就是延时7个时钟周期,那么一共有5位,则可以延时31个时钟周期,
小知识点来了:
如果你设置了side-set,那么这条指令最多只能设置7个时钟周期!因为side-set占用了2位。
实际应用场景
1. 调试分析
通过 side-set 输出状态,可以轻松用逻辑分析仪/示波器捕捉闪烁信号,分辨出状态机运行状态、延迟是否正确等。
2. 通信协议帧信号
类似 I2S、SPI、UART 等协议中都需要帧开始/结束等“状态提示信号”,而 side-set 非常适合用来输出这种同步信号。
3. 触发外部事件
你甚至可以让 side-set 引脚连接到外部中断引脚,用来触发其他芯片的工作/同步检测。
总结
side-set 是 Pico PIO 中最具“魔法感”的特性之一。它允许你:
精准输出辅助信号(0 delay 并发)
不影响主逻辑流程
在硬实时控制中节省宝贵指令周期