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_LEFT或PIO.SHIFT_RIGHT。out_shiftdir 是 OSR 移位的方向,可以是
PIO.SHIFT_LEFT或PIO.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 可以是整数、类型为
B、H或I的数组,或bytearray。此方法将阻塞直到所有字都已写入 FIFO。如果 FIFO 已满或变满,该方法将阻塞,直到状态机拉取足够的字以完成写入。
每个字首先向左移位 shift 位,即状态机接收到的是
word << shift。
- rx_fifo() int¶
返回状态机 RX FIFO 中的字数。值为 0 表示 FIFO 为空。
在调用
StateMachine.get()之前,可用于检查是否有数据等待读取。
- tx_fifo() int¶
返回状态机 TX FIFO 中的字数。值为 0 表示 FIFO 为空。
在使用
StateMachine.put()推送另一个字之前,可用于检查是否有空间。
缓冲区协议¶
StateMachine 类支持 buffer protocol,允许直接访问每个状态机的发送和接收 FIFO。这主要是为了允许在配置 rp2.DMA() 通道时将 StateMachine 对象直接作为读或写参数传递。