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 區塊,編號為 01。對於任何其他 id 都會引發 ValueError

方法

gpio_base(base: machine.Pin | int | None = None, /) int

取得或設定此 PIO 區塊的 GPIO 基準位置。

RP2040 PIO 看到的是 GPIO 空間中的一個 32 接腳視窗;此視窗可從 GPIO0 或 GPIO16 開始。基準位置控制此 PIO 上所有狀態機目前生效的視窗。

若不帶引數,則傳回目前的基準位置(GPIO 接腳編號,016)。

若帶引數,則設定基準位置。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* 常數做 AND 運算來識別觸發的狀態機。

trigger 是一個或多個 IRQ_SM0 .. IRQ_SM3 的位元遮罩。預設會對任何狀態機觸發。

hard=True 會註冊一個硬中斷處理常式(回呼函式中不進行堆積配置)。

MicroPython 在每個 PIO 區塊上綁定 IRQ 0;IRQ 1 為保留用途,無法從 Python 存取。

常數

IN_LOW: int

傳遞給 asm_pio()out_init / set_init / sideset_init,使接腳啟動時為驅動為低電位的輸入(即三態,輸出緩衝區維持 0)。

IN_HIGH: int

傳遞給 asm_pio()out_init / set_init / sideset_init,使接腳啟動時為輸入,且輸出緩衝區維持 1。

OUT_LOW: int

傳遞給 asm_pio()out_init / set_init / sideset_init,使接腳啟動時為驅動於邏輯 0 的輸出。

OUT_HIGH: int

傳遞給 asm_pio()out_init / set_init / sideset_init,使接腳啟動時為驅動於邏輯 1 的輸出。

SHIFT_LEFT: int

傳遞給 asm_pio()StateMachine.init()in_shiftdir / out_shiftdir,使移位將位元朝 MSB 方向移動。

SHIFT_RIGHT: int

傳遞給 asm_pio()StateMachine.init()in_shiftdir / out_shiftdir,使移位將位元朝 LSB 方向移動。

JOIN_NONE: int

傳遞給 asm_pio()fifo_join,使狀態機擁有各自獨立的 4 字組 TX 與 RX FIFO(預設值)。

JOIN_TX: int

傳遞給 asm_pio()fifo_join,使 TX FIFO 透過併入 RX FIFO 而加倍為 8 字組。狀態機將無法再接收資料。

JOIN_RX: int

傳遞給 asm_pio()fifo_join,使 RX FIFO 透過併入 TX FIFO 而加倍為 8 字組。狀態機將無法再傳送資料。

IRQ_SM0: int

irq() trigger 旗標:狀態機 0 引發了它的 IRQ。

IRQ_SM1: int

irq() trigger 旗標:狀態機 1 引發了它的 IRQ。

IRQ_SM2: int

irq() trigger 旗標:狀態機 2 引發了它的 IRQ。

IRQ_SM3: int

irq() trigger 旗標:狀態機 3 引發了它的 IRQ。