🛠 Première machine à états PIO : un blink sans CPU
Objectives
Understand the RP2040 signature feature: PIO (Programmable I/O) — 2 blocks of 4 programmable state machines that create low-level interfaces without consuming CPU time. You will write a small state machine that blinks the GP25 LED at 1 Hz autonomously, leaving the main core free for other tasks. Each SM has 4 registers (X, Y, FIFO, OSR) and executes its instructions in 1 cycle.
Hardware
- 1 × Raspberry Pi Pico
- MicroPython rp2 firmware (see the MicroPython tutorial in this series) — the shortest path to discovering PIO
- No external components (onboard GP25 LED)
Complete code
# pio_blink.py — d'après la quick reference MicroPython rp2
from machine import Pin
import rp2
@rp2.asm_pio(set_init=rp2.PIO.OUT_LOW)
def blink_1hz:
# 1000 cycles par moitié à freq=2000 -> 0,5 s
set(pins, 1) # LED ON
set(x, 31) [6]
label("high")
nop [29] # 30 cycles par boucle
jmp(x_dec, "high")
set(pins, 0) # LED OFF
set(x, 31) [6]
label("low")
nop [29]
jmp(x_dec, "low")
sm = rp2.StateMachine(0, blink_1hz, freq=2000, set_base=Pin(25))
sm.active(1) # la PIO clignote seule
# Le CPU est 100 % libre : la tâche ci-dessous tourne en parallèle
import time, machine
aux = machine.Pin(21, machine.Pin.OUT) # >
while True:
aux.toggle
time.sleep_ms(7)
Expected verification
The GP25 LED blinks at 1 Hz continuously, even if you loop alongside on a busy CPU task (the auxiliary pin switches much faster in parallel). This proves that the timing is handled by the PIO hardware, not by software. Stop the script at the REPL: the SM stops, and the CPU must remain in control.
Common errors
- Miscounting cycles: each instruction takes 1 cycle,
[n]adds n wait cycles — the 1 Hz calculation is done manually (1000 cycles × 2 halves at 2 kHz). - Forgetting
set_init=rp2.PIO.OUT_LOW: the pin is not configured as a PIO output, so nothing is output. - Using an already occupied SM: the 8 SMs are shared among all PIO users.
- Expecting the PIO to continue after a reset: it runs as long as the MicroPython program is running, not after a reset.
- Confusing PIO frequency and period:
freq=2000is the SM clock, not the blinking frequency.
Other tutorials for this board
Code examples for this board
clignotante.pyPythonbouton-interruption.pyPythonpwm-servo.pyPythonlecture-adc.pyPythonneopixel.pyPythonoled-i2c.pyPython