动态执行指令:解锁 RP2040 PIO 更灵活的用法
PIO 使用 exec 执行 instr 寄存器指令
前面我们提到除了指令内存外,状态机还可以从其他三个来源执行指令:
MOV EXEC可以从Source指定的某个寄存器执行指令。OUT EXEC可以执行 OSR 移出的数据。- 从
SMx_INSTR控制寄存器执行指令,系统可以将指令直接写入该寄存器,以立即执行。
接下来,我们使用 StateMachine.exec() 方法对来自给定字符串 instr 的指令进行编码。
以下代码可以在我们提供的资料包中 elegance-devkit v1\Demo\31 PIO_Exec 文件夹找到。
示例代码如下:
# Python env : MicroPython v1.23.0
# -*- coding: utf-8 -*-
# @Time : 2024/7/28 上午11:16
# @Author : 李清水
# @File : main.py
# @Description : PIO类实验,在PIO程序中使用exec指令执行 pioasm 指令
# ======================================== 导入相关模块 ========================================
# 导入时间相关的模块
import time
# 导入RP2040相关的模块
import rp2
# 导入硬件相关的模块
from machine import Pin
# ======================================== 全局变量 ============================================
# ======================================== 功能函数 ============================================
# 使用装饰器定义了一个 PIO 程序:blink函数,不执行任何操作
@rp2.asm_pio(set_init=rp2.PIO.OUT_LOW)
def blink() -> None:
"""
定义一个空的 PIO 程序。
Args:
None
Returns:
None
Description:
该 PIO 程序不执行任何操作,仅作为状态机的占位程序。
"""
pass
# ======================================== 自定义类 ============================================
# ======================================== 初始化配置 ==========================================
# 上电延时3s
time.sleep(3)
# 打印调试信息
print("FreakStudio: PIO use exec instruction to execute pioasm instruction")
# 创建了一个状态机,将 blink() 函数作为程序,并设置频率为 系统时钟/2000 Hz,同时设置set_bases为GPIO25
sm = rp2.StateMachine(0, blink, freq=2000, set_base=Pin(25))
# ======================================== 主程序 ===========================================
# 启动状态机
sm.active(1)
while True:
# 状态机加载指令'set(pins, 1)'
sm.exec('set(pins, 1)')
# 延时1s
time.sleep(1)
# 状态机加载指令'set(pins, 0)'
sm.exec('set(pins, 0)')
# 延时1s
time.sleep(1)
其整体执行流程如下图所示:

烧录代码到 Pico,可以看到板载 LED 灯闪烁:


* `MOV EXEC` 可以从 `Source` 指定的某个寄存器执行指令。
* `OUT EXEC` 可以执行 OSR 移出的数据。
* 从 `SMx_INSTR` 控制寄存器执行指令,系统可以将指令直接写入该寄存器,以立即执行。
浙公网安备 33010602011771号