树莓派Pico的pio例子
·
参考
diagram.json
{
"version": 1,
"author": "Anonymous maker",
"editor": "wokwi",
"parts": [
{
"type": "chip-scope",
"id": "scope1",
"top": 135.42,
"left": 369.6,
"attrs": {
"sampleTimeUs": "100",
"sampleTimeMs": "0",
"triggerChannel": "0",
"triggerMode": "1",
"crtColor": "0",
"trace0Color": "14",
"trace1Color": "12",
"trace2Color": "10",
"trace3Color": "2"
}
},
{ "type": "wokwi-pi-pico", "id": "pico", "top": 0, "left": 0, "attrs": {} },
{
"type": "wokwi-led",
"id": "led1",
"top": -2.67,
"left": -65.33,
"attrs": { "color": "red" }
},
{ "type": "wokwi-slide-switch", "id": "sw1", "top": 33.2, "left": -188.9, "attrs": {} },
{ "type": "wokwi-vcc", "id": "vcc1", "top": 115.96, "left": -163.2, "attrs": {} },
{ "type": "wokwi-gnd", "id": "gnd1", "top": 115.2, "left": -211.8, "attrs": {} }
],
"connections": [
[ "pico:GP5", "led1:A", "green", [ "h0" ] ],
[ "pico:GND.2", "led1:C", "black", [ "h0" ] ],
[ "scope1:D0", "pico:GP5", "green", [ "h-249.6", "v-182.4", "h-144", "v86.4" ] ],
[ "sw1:1", "gnd1:GND", "green", [ "v9.6", "h-28.8" ] ],
[ "sw1:3", "vcc1:VCC", "green", [ "v28.8", "h19.4", "v57.6", "h-9.6" ] ],
[ "sw1:2", "pico:GP4", "green", [ "v19.2", "h76.9", "v-28.8" ] ]
],
"dependencies": { "chip-scope": "github:Dlloydev/Wokwi-Chip-Scope@1.0.7" }
}
main.py (简单闪烁)
from machine import Pin
import rp2
# =========================
# PIO 程序:LED 闪烁
# =========================
@rp2.asm_pio(
set_init=rp2.PIO.OUT_LOW # LED 初始为低
)
def blink():
wrap_target()
set(pins, 1) [31] # LED ON,延时
nop() [31]
set(pins, 0) [31] # LED OFF,延时
wrap()
# =========================
# StateMachine 初始化
# =========================
sm = rp2.StateMachine(
0,
blink,
freq=2000, # PIO 时钟频率
set_base=Pin(5) # 板载 LED(Pico)
)
sm.active(1)
main.py (多个状态机一起工作)
from rp2 import PIO, StateMachine, asm_pio
from machine import Pin
import time
@asm_pio(set_init=PIO.OUT_LOW)
def led_quarter_brightness():
set(pins, 0)[2]
set(pins, 1)
@asm_pio(set_init=PIO.OUT_LOW)
def led_half_brightness():
set(pins, 0)
set(pins, 1)
@asm_pio(set_init=PIO.OUT_HIGH)
def led_full_brightness():
set(pins, 1)
sm1 = StateMachine(1, led_quarter_brightness, freq=2000, set_base=Pin(5))
sm2 = StateMachine(2, led_half_brightness, freq=2000, set_base=Pin(5))
sm3 = StateMachine(3, led_full_brightness, freq=2000, set_base=Pin(5))
print(2)
while(True):
sm1.active(1)
time.sleep(1)
sm1.active(0)
sm2.active(1)
time.sleep(1)
sm2.active(0)
sm3.active(1)
time.sleep(1)
sm3.active(0)
main.py (外部引脚决定如何闪烁)
from machine import Pin
import rp2
@rp2.asm_pio(set_init=rp2.PIO.OUT_LOW)
def gpio5_controller():
label("check")
jmp(pin, "high_mode") # GPIO4 == 1?
# Low mode: 1 high, 2 low
set(pins, 1) [31]
set(pins, 0) [31]
set(pins, 0) [31]
jmp("check")
label("high_mode")
# High mode: 2 high, 1 low
set(pins, 1) [31]
set(pins, 1) [31]
set(pins, 0) [31]
jmp("check")
# 配置引脚
Pin(4, Pin.IN, Pin.PULL_DOWN) # 确保输入稳定
sm = rp2.StateMachine(0, gpio5_controller, freq=5000, set_base=Pin(5), jmp_pin=Pin(4))
sm.active(1)
main.py cpu->pio(传递数据)
from machine import Pin
import rp2
import time
# ==============================
# 配置(固定 1 kHz 方波)
# ==============================
HALF_PERIOD_US = 500 # 半周期 500 µs → 完整周期 1 ms
PIN_OUT = 5
# ==============================
# PIO 程序:输出 n 个周期方波,半周期从 FIFO 获取
# ==============================
@rp2.asm_pio(
set_init=rp2.PIO.OUT_LOW,
autopull=False,
autopush=True # push 完成信号到 FIFO
)
def square_wave_n_cycles():
pull() # 获取半周期
mov(x, osr)
pull() # 获取周期数
mov(y, osr)
label("cycle")
# 高电平
set(pins, 1)
label("high_wait")
jmp(x_dec, "high_wait")
mov(x, osr) # 恢复 X
# 低电平
set(pins, 0)
label("low_wait")
jmp(x_dec, "low_wait")
mov(x, osr) # 恢复 X
# 周期计数
jmp(y_dec, "cycle")
# 完成信号
push() # 推送一个值到 CPU FIFO
# ==============================
# 初始化 StateMachine
# ==============================
sm = rp2.StateMachine(
0,
square_wave_n_cycles,
freq=1_000_000, # 1 MHz → 每条指令 1 µs
set_base=Pin(PIN_OUT)
)
sm.active(1)
# ==============================
# 核心函数:CPU 发送半周期 + 周期数,等待完成
# ==============================
def send_and_wait(half_period_us, cycles):
if cycles <= 0 or half_period_us <= 0:
return
sm.put(half_period_us - 1) # 半周期
sm.put(cycles) # 周期数
# 等待 PIO 推送完成信号
while sm.rx_fifo() == 0:
pass
sm.get() # 清空完成信号
while True:
print(f"输出固定 1 kHz 方波(半周期={HALF_PERIOD_US} µs)")
print("-" * 40)
cycles = 3
print(f"CPU 发: {cycles} 个周期")
send_and_wait(HALF_PERIOD_US, cycles)
print(f"PIO 执行完成 ({cycles} cycles)\n")
time.sleep_ms(200)
cycles = 5
print(f"CPU 发: {cycles} 个周期")
send_and_wait(HALF_PERIOD_US, cycles)
print(f"PIO 执行完成 ({cycles} cycles)\n")
print("全部完成!GPIO5 已输出对应方波周期")
main.py pio->cpu(传递数据)
from machine import Pin
import rp2
import time
PIN_IN = 4
@rp2.asm_pio()
def edge_detector():
in_(pins, 1)
mov(x, isr)
label("loop")
in_(pins, 1)
mov(y, isr)
jmp(x_not_y, "change")
jmp("loop")
label("change")
mov(isr, y)
push()
mov(x, y)
jmp("loop")
sm_in = rp2.StateMachine(0, edge_detector, freq=2000, in_base=Pin(PIN_IN))
sm_in.active(1)
print("检测 GPIO4 边沿...")
try:
while True:
if sm_in.rx_fifo():
level = sm_in.get() & 1
print(f"边沿!当前电平: {level}")
time.sleep_us(100)
except KeyboardInterrupt:
sm_in.active(0)
print("结束")
更多推荐



所有评论(0)