class StateMachine —— 访问 RP2040 的可编程 I/O 接口

StateMachine 类提供对 RP2040 的 PIO(可编程 I/O)接口的访问。

有关汇编 PIO 程序的内容,请参见 rp2.asm_pio()

构造函数

class rp2.StateMachine(id: int, program: Callable | None = None, *args, **kwargs)

获取编号为 id 的状态机。RP2040 有两个相同的 PIO 实例,每个实例有 4 个状态机:因此总共有 8 个状态机,编号从 0 到 7。

可选地用给定的程序 program 对其进行初始化:参见 StateMachine.init

init(program: Callable, freq: int = -1, *, in_base: machine.Pin | None = None, out_base: machine.Pin | None = None, set_base: machine.Pin | None = None, jmp_pin: machine.Pin | None = None, sideset_base: machine.Pin | None = None, in_shiftdir: int | None = None, out_shiftdir: int | None = None, push_thresh: int | None = None, pull_thresh: int | None = None) None

配置状态机实例以运行给定的 program

该程序被添加到此 PIO 实例的指令内存中。如果指令内存中已包含此程序,则复用其偏移量以节省指令内存。

  • freq 是运行状态机的频率,单位为 Hz。默认为系统时钟频率。

    时钟分频系数计算为 system clock frequency / freq,因此可能存在轻微的舍入误差。

    最小可能的时钟分频系数是系统时钟的 1/65536:因此在默认系统时钟频率 125MHz 下,freq 的最小值为 1908。要以更低的频率运行状态机,你需要用 machine.freq() 降低系统时钟速度。

  • in_base 是用于 in() 指令的第一个引脚。

  • out_base 是用于 out() 指令的第一个引脚。

  • set_base 是用于 set() 指令的第一个引脚。

  • jmp_pin 是用于 jmp(pin, ...) 指令的第一个引脚。

  • sideset_base 是用于 side-set 的第一个引脚。

  • in_shiftdir 是 ISR 移位的方向,可以是 PIO.SHIFT_LEFTPIO.SHIFT_RIGHT

  • out_shiftdir 是 OSR 移位的方向,可以是 PIO.SHIFT_LEFTPIO.SHIFT_RIGHT

  • push_thresh 是触发自动推送或条件再推送之前的位数阈值。

  • pull_thresh 是触发自动拉取或条件再拉取之前的位数阈值。

注意:用于 in_base 的引脚需要手动配置为输入(或其他方式),以便 PIO 能看到所需的信号(它们可以是输入引脚、输出引脚,或连接到不同的外设)。jmp_pin 也可以手动配置,但默认情况下将是一个输入引脚。

active(value: bool | int | None = None, /) bool

获取或设置状态机当前是否正在运行。

>>> sm.active()
True
>>> sm.active(0)
False
restart() None

重启状态机并跳转到程序的开头。

此方法使用 RP2040 的 SM_RESTART 寄存器清除状态机的内部状态。这包括:

  • 输入和输出移位计数器

  • 输入移位寄存器的内容

  • 延迟计数器

  • 等待 IRQ 的状态

  • 使用 StateMachine.exec() 运行的停滞指令

exec(instr: str | int) None

执行单条 PIO 指令。

如果 instr 是字符串,则使用 asm_pio_encode 从给定字符串编码该指令。

>>> sm.exec("set(0, 1)")

如果 instr 是整数,则将其视为已编码的 PIO 机器码指令并执行。

>>> sm.exec(rp2.asm_pio_encode("out(y, 8)", 0))
get(buf: 'bytearray | array | None' = None, shift: int = 0) int

从状态机的 RX FIFO 拉取一个字。

如果 FIFO 为空,则阻塞直到数据到达(即状态机推送一个字)。

返回前该值会向右移位 shift 位,即返回值为 word >> shift

put(value: 'int | bytes | bytearray | array', shift: int = 0) None

将字推送到状态机的 TX FIFO。

value 可以是整数、类型为 BHI 的数组,或 bytearray

此方法将阻塞直到所有字都已写入 FIFO。如果 FIFO 已满或变满,该方法将阻塞,直到状态机拉取足够的字以完成写入。

每个字首先向左移位 shift 位,即状态机接收到的是 word << shift

rx_fifo() int

返回状态机 RX FIFO 中的字数。值为 0 表示 FIFO 为空。

在调用 StateMachine.get() 之前,可用于检查是否有数据等待读取。

tx_fifo() int

返回状态机 TX FIFO 中的字数。值为 0 表示 FIFO 为空。

在使用 StateMachine.put() 推送另一个字之前,可用于检查是否有空间。

irq(handler: Callable[[StateMachine], None] | None = None, trigger: int = 0 | 1, hard: bool = False) Callable

返回给定 StateMachine 的 IRQ 对象。

可选地对其进行配置。

缓冲区协议

StateMachine 类支持 buffer protocol,允许直接访问每个状态机的发送和接收 FIFO。这主要是为了允许在配置 rp2.DMA() 通道时将 StateMachine 对象直接作为读或写参数传递。