PIO Quick Start: On‑Board LED Blink — Principles & Code Walkthrough
This example uses RP2040‑PIO in MicroPython to blink Pico’s onboard LED via state‑machine without CPU‑loop blocking.
【Preliminary Note】The original hardware example in this article was written based on the RP2040. The actual hardware used in this hands-on demonstration features the W55RP20 as the main controller chip. The circuit logic and UF2 flashing operation principles are universally applicable, with only the main controller model differing. The original chip model mentioned in the circuit descriptions below is provided for reference purposes only.
PIO controls the on-board LED to blink
elegance-devkit v1\Demo\29 PIO_LED folder of the resource package we provide.# Python env : MicroPython v1.23.0
# -*- coding: utf-8 -*-
# @Time : 2024/7/27 下午11:48
# @Author : 李清水
# @File : main.py
# @Description : 通过PIO控制板载LED灯闪烁
# ======================================== 导入相关模块 ========================================
# 导入硬件相关的模块
from machine import Pin
# 导入时间相关的模块
import time
# 导入RP2040相关的模块
import rp2
# ======================================== 全局变量 ============================================
# ======================================== 功能函数 ============================================
# 定义一个 PIO 程序,将输出引脚初始化为低电平
@rp2.asm_pio(set_init=rp2.PIO.OUT_LOW)
def blink() -> None:
"""
定义一个闪烁LED灯的PIO程序。
Args:
None
Returns:
None
Description:
该PIO程序通过设置引脚的高低电平来控制LED灯的闪烁。
高电平和低电平各持续160个时钟周期,总周期为320个时钟周期。
"""
# 标记程序的起始位置
wrap_target()
# 将输出引脚设置为高电平,并延迟 31 个时钟周期
set(pins, 1) [31]
# 以下nop指令无操作,并延迟 31 个时钟周期
nop() [31]
nop() [31]
nop() [31]
nop() [31]
# 将输出引脚设置为低电平,并延迟 31 个时钟周期
set(pins, 0) [31]
# 以下nop指令无操作,并延迟 31 个时钟周期
nop() [31]
nop() [31]
nop() [31]
nop() [31]
# 程序跳转到wrap_target()处
wrap()
# ======================================== 自定义类 ============================================
# ======================================== 初始化配置 ==========================================
# 上电延时3s
time.sleep(3)
# 打印调试信息
print("FreakStudio : Use PIO to control onboard LED")
# 创建状态机0,加载blink()程序,设置PIO执行频率为 系统时钟/2000 Hz,设置引脚为25号引脚
sm = rp2.StateMachine(0, blink, freq=2000, set_base=Pin(25))
# ======================================== 主程序 ===========================================
# 启动状态机0
sm.active(1)
# 延时5s
time.sleep(5)
# 关闭状态机0
sm.active(0)blink, which is a PIO program used to control the blinking of the LED. This function uses the @rp2. asm_pio decorator to define the PIO program, and sets the initial state, frequency and pins of the program.sm is created, which loads the previously defined blink function, sets its frequency to 2000Hz, and assigns pin 25 as the corresponding pin.sm to make it start executing the blink function, so as to control the LED to blink. Then wait for 5 seconds, and finally shut down the finite-state machine sm to stop the LED from blinking.the blink function is a PIO program, which is designed to change the state of the LED at each iteration. Specifically, it sets the output pin to a high level, holds it for a period of time (implemented by the nop instruction), then sets the pin to a low level and holds it for another period of time. This process repeats continuously, creating the blinking effect of the LED.sm is responsible for executing blink function. When the finite-state machine is activated (sm. active (1)), it will start executing the blink function; when the finite-state machine is deactivated (sm. active (0)), it will stop executing the blink function, and the configured frequency determines the blinking speed of the LED.wrap_target()
...
wrap() # 程序跳转到wrap_target()处label('loop')
...
jmp('loop') # 程序跳转到loop处set(pins, 1) # 高电平
set(pins, 0) # 低电平set (pins, 1)/ set (pins, 0) Instruction: The instruction itself consumes 1 clock cycle, with a latency of 31 clock cycles, totaling 32 clock cycles consumed.nop () Instruction: Each nop () consumes 1 clock cycle, plus an additional latency of 31 clock cycles, so each nop () consumes a total of 32 clock cycles, and 4 nop () s consume a total of 128 clock cycles.set (pins, 1) 4 instances of nop ()= 32 + 128 = 160 clock cycles.set (pins, 0) 4 instances of nop ()= 32 + 128 = 160 clock cycles.GP28, and the input command is as follows:sm = rp2.StateMachine(0, blink, freq=2000, set_base=Pin(28))
sm.active(1)