class PIO —— 高级 PIO 用法¶
PIO 类封装了 RP2040 两个可编程 I/O(PIO)块中的一个。每个 PIO 块包含一段由四个独立状态机共享的指令内存(32 条指令),外加每个状态机的专用 FIFO 接口和一个 IRQ 控制器。
大多数脚本通过 StateMachine 与 PIO 交互——本类用于需要执行以下操作的高级用例:
通过
add_program()/remove_program()显式加载和移除程序。通过
gpio_base()在芯片的 32 引脚窗口范围内移动 PIO 的 GPIO 基址。通过
irq()挂接到块级 IRQ 标志。
有关汇编 PIO 程序的内容,请参见 rp2.asm_pio()。
构造函数¶
- class rp2.PIO(id: int)¶
返回由
id标识的 PIO 块的单例PIO对象。RP2040 有两个 PIO 块,编号为0和1。对于任何其他 id 都会引发ValueError。方法¶
- gpio_base(base: machine.Pin | int | None = None, /) int¶
获取或设置此 PIO 块的 GPIO 基址。
RP2040 PIO 看到的是 GPIO 空间中的一个 32 引脚窗口;该窗口可以从 GPIO0 或 GPIO16 开始。基址控制此 PIO 上所有状态机当前生效的窗口。
不带参数时,返回当前基址(GPIO 引脚号,
0或16)。带参数时,设置基址。
base可以是machine.Pin实例或整数引脚号,并且必须解析为 GPIO0 或 GPIO16。基址必须在此 PIO 块上添加任何程序或构造任何状态机之前设置。
- add_program(program: Callable) None¶
将
program加载到此 PIO 的指令内存中。生成的内存布局会在此 PIO 块上的所有状态机之间复用。每个 PIO 只有 32 条指令的程序内存,由所有程序共享;如果新程序放不下,此方法会引发
OSError(ENOMEM)。同一个程序可以加载到两个 PIO 实例上,但它们各自占用独立的内存区域。
- remove_program(program: Callable | None = None, /) None¶
从此 PIO 的指令内存中移除
program,为新程序释放空间。如果省略program,则移除当前加载在此 PIO 上的所有程序。移除一个未加载的程序属于空操作(不会引发异常)。
- state_machine(id: int, program: Callable | None = None, *args, **kwargs) StateMachine¶
返回此 PIO 块所拥有的四个
StateMachine实例之一。id是本地状态机索引(0——3)。如果提供了
program,则配置状态机来运行它——所有位置参数/关键字参数都会转发给StateMachine.init()。示例:
>>> rp2.PIO(1).state_machine(3) StateMachine(7)
返回对象的全局状态机 ID 为
pio_id * 4 + sm_id。
- irq(handler: Callable[[PIO], None] | None = None, trigger: int = IRQ_SM0 | IRQ_SM1 | IRQ_SM2 | IRQ_SM3, hard: bool = False) Callable¶
获取或配置此 PIO 的块级 IRQ。
handler是当任何被请求的状态机 IRQ 锁存时触发的回调。该处理函数接收此PIO实例作为其唯一参数;在处理函数内部,可以通过self.irq().flags()与IRQ_SM*常量进行按位与运算来识别触发的状态机。trigger是一个或多个IRQ_SM0..IRQ_SM3的位掩码。默认情况下任何状态机都会触发。hard=True注册一个硬中断处理函数(回调中不进行堆分配)。MicroPython 绑定了每个 PIO 块上的 IRQ 0;IRQ 1 是保留的,无法从 Python 访问。
常量¶
- SHIFT_LEFT: int¶
传递给
asm_pio()或StateMachine.init()的in_shiftdir/out_shiftdir,使移位将位向 MSB 方向移动。
- SHIFT_RIGHT: int¶
传递给
asm_pio()或StateMachine.init()的in_shiftdir/out_shiftdir,使移位将位向 LSB 方向移动。