前言
Raspberry Pi Pico 上的 PIO(Programmable Input Output)是非常强大的硬件编程模块,能够实现精准的时序控制。本篇文章介绍一个简易的 PIO 程序,实现 LED 点亮与熄灭,并通过延时让状态保持可见。传统的 GPIO 控制 LED,往往需要通过软件延时实现“点亮保持”,但这会占用 CPU 资源。Pico 的 PIO 独立于主 CPU,能够硬件层面生成信号和控制时序,减少主控负担。
本例通过 PIO 程序控制 LED 引脚,在 2000Hz 频率下,实现 LED 点亮大约 0.5 秒、熄灭 0.5 秒的循环。
实例代码
from machine import Pin
from rp2 import PIO, asm_pio
@asm_pio(set_init=rp2.PIO.OUT_LOW)
def led_controller():
# 设置计数器 x 初值 31,最高就31喔,可以看我前几天的博文,讲解为啥最高就31:D
set(x, 31)
# 点亮 LED(对应 pin 输出高电平)
set(pins, 1)
label("led_on") # 不占用时钟周期
nop() [29] # 延时指令,等待30个时钟周期 (1 + 29延时 = 30周期)
jmp(x_dec, "led_on") # x递减,非零则继续循环延时,1个时钟周期
# x减到0后,切换状态准备熄灭
set(x, 31)
set(pins, 0) # 熄灭 LED(pin输出低电平)
label("led_off")
nop() [29]
jmp(x_dec, "led_off") # 熄灭状态延时
# 创建并启动状态机
sm = rp2.StateMachine(0, led_controller, freq=2000, set_base=Pin(25))
sm.active(1)
原理详解
-
频率设置:PIO 状态机频率设为 2000 Hz,即每个时钟周期 0.0005 秒(0.5 毫秒,1/2000)。
-
延时机制:
-
使用 nop() [29] 指令让程序每次循环消耗 30 个时钟周期。
-
通过寄存器 x 计数,从 31 递减到 0,累计延时约 31 × 30 = 930 个周期。
-
总延时约 930 × 0.0005s ≈ 0.465 秒,接近 0.5 秒。
-
-
状态切换:
-
先点亮 LED,延时后切换到熄灭状态,延时后再回到点亮,形成循环。
-
扩展思考
-
你可以通过调整 freq 或延时计数器 x 的初值和 nop 延时数,控制闪烁的速度。
-
结合主程序和状态机通信,可以实现更复杂的控制逻辑,例如响应外部输入、实现 PWM 调光等。
-
PIO 适合高精度时序需求,如通信协议、传感器信号处理等。
总结
本例展示了如何利用 Raspberry Pi Pico 的 PIO 功能,写一个简单但高效的 LED 控制程序。理解 PIO 的延时机制和状态机跳转是掌握其核心的关键。希望这篇文章能帮助你入门 PIO 编程,迈出硬件编程的重要一步。