class I2S —— Inter-IC Sound 匯流排協定

I2S 類別以控制器模式驅動 Inter-IC Sound(I2S)匯流排——由 MCU 產生位元時脈(SCK)與字元選擇時脈(WS),並在 SD 線上交換取樣資料。此驅動程式支援背景持續執行 DMA,因此 Python 端只需持續為內部取樣緩衝區補充資料即可。不支援周邊裝置/僅接收模式。

可用於接有 I2S 周邊的 STM32 OpenMV 相機以及 OpenMV Cam RT1062。OpenMV Cam AE3(alif port)未提供此功能。

STM32 OpenMV 相機上的 I2S(2)SPI(2) 共用接腳——位元時脈位於 P2(SCK),字元選擇位於 P3(NSS),而序列資料線則遵循 SPI 資料方向慣例:TX 使用 P0(MOSI),RX 使用 P1(MISO)。

範例——輸出(TX)。建構一個 TX 匯流排,以 44.1 kHz、16 位元單聲道取樣驅動外部音訊 DAC,並搭配 16384 位元組(16 KiB)的 DMA 後備緩衝區:

from machine import I2S, Pin

audio_out = I2S(
    2,
    sck=Pin("P2"), ws=Pin("P3"), sd=Pin("P0"),
    mode=I2S.TX,
    bits=16,
    format=I2S.MONO,
    rate=44100,
    ibuf=16384,
)

範例——輸入(RX)。建構一個 RX 匯流排,以 22.05 kHz、32 位元立體聲(左右交錯)從麥克風擷取,並搭配 16384 位元組(16 KiB)的 DMA 後備緩衝區:

from machine import I2S, Pin

audio_in = I2S(
    2,
    sck=Pin("P2"), ws=Pin("P3"), sd=Pin("P1"),
    mode=I2S.RX,
    bits=32,
    format=I2S.STEREO,
    rate=22050,
    ibuf=16384,
)

傳輸方法可用於三種方式:

阻塞式——write()readinto() 僅在操作完成後才返回:

num_written = audio_out.write(buf)   # blocks until buf is drained
num_read = audio_in.readinto(buf)    # blocks until buf is filled

非阻塞式——以 irq() 安裝一個回呼函式,傳輸方法會立即返回。當 DMA 清空 TX 緩衝區或填滿 RX 緩衝區時,回呼函式會從 MicroPython 排程器執行:

audio_out.irq(i2s_callback)
num_written = audio_out.write(buf)   # returns immediately

audio_in.irq(i2s_callback)
num_read = audio_in.readinto(buf)    # returns immediately

asyncio——I2S 是一個串流,可由 asyncio.StreamReaderasyncio.StreamWriter 包裝:

swriter = asyncio.StreamWriter(audio_out)
swriter.write(buf)
await swriter.drain()

sreader = asyncio.StreamReader(audio_in)
num_read = await sreader.readinto(buf)

建構函式

class machine.I2S(id: int, *, sck: Pin, ws: Pin, sd: Pin, mck: Pin | None = None, mode: int, bits: int, format: int, rate: int, ibuf: int)

以給定的 id 建構一個 I2S 物件:

  • id 用於識別特定的 I2S 匯流排;它與開發板及 port 相關

所有 port 均支援的僅限關鍵字參數:

  • sck 是序列時脈線的接腳物件

  • ws 是字元選擇線的接腳物件

  • sd 是序列資料線的接腳物件

  • mck 是主時脈線的接腳物件;主時脈頻率為取樣率 * 256

  • mode 指定接收或傳送

  • bits 指定取樣大小(位元),16 或 32

  • format 指定聲道格式,STEREO 或 MONO

  • rate 指定音訊取樣率(Hz);這是 ws 訊號的頻率

  • ibuf 指定內部緩衝區長度(位元組)

對所有 port 而言,DMA 會在背景持續執行,讓使用者應用程式可在內部緩衝區與 I2S 周邊單元之間傳輸取樣資料的同時執行其他操作。增大內部緩衝區的大小,有可能延長使用者應用程式在發生欠載(underflow,例如 write 方法)或溢位(overflow,例如 readinto 方法)之前可執行非 I2S 操作的時間。

方法

init(*, sck: Pin, ws: Pin, sd: Pin, mck: Pin | None = None, mode: int, bits: int, format: int, rate: int, ibuf: int) None

引數說明請參閱建構函式

deinit() None

解除初始化 I2S 匯流排

readinto(buf: bytearray) int

將音訊取樣讀取到 buf 所指定的緩衝區。buf 必須支援緩衝區協定,例如 bytearray 或 array。「buf」的位元組順序為小端序(little-endian)。對於 Stereo 格式,左聲道取樣在右聲道取樣之前。對於 Mono 格式,會使用左聲道取樣資料。返回讀取的位元組數

write(buf: bytes) int

寫入 buf 中所含的音訊取樣。buf 必須支援緩衝區協定,例如 bytearray 或 array。「buf」的位元組順序為小端序(little-endian)。對於 Stereo 格式,左聲道取樣在右聲道取樣之前。對於 Mono 格式,取樣資料會同時寫入左右兩個聲道。返回寫入的位元組數

irq(handler: Callable[[I2S], None]) None

設定回呼函式。當 buf 被清空(write 方法)或變滿(readinto 方法)時,會呼叫 handler。設定回呼函式會使 writereadinto 方法改為非阻塞式操作。handler 會在 MicroPython 排程器的環境中被呼叫。

static shift(*, buf: bytearray, bits: int, shift: int) None

buf 中所含的所有取樣進行位元位移。bits 指定取樣大小(位元)。shift 指定每個取樣要位移的位元數。正值為左移,負值為右移。通常用於音量控制。每位移一個位元,取樣音量會改變 6dB。

常數

RX: int

用於將 I2S 匯流排 mode 初始化為接收

TX: int

用於將 I2S 匯流排 mode 初始化為傳送

STEREO: int

用於將 I2S 匯流排 format 初始化為立體聲

MONO: int

用於將 I2S 匯流排 format 初始化為單聲道