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 端口)上未提供。
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.StreamReader / asyncio.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 总线;它与开发板和端口相关
所有端口都支持的仅关键字参数:
sck是串行时钟线的引脚对象ws是字选择线的引脚对象sd是串行数据线的引脚对象mck是主时钟线的引脚对象;主时钟频率为采样率 * 256mode指定接收或发送bits指定采样大小(位),16 或 32format指定声道格式,STEREO 或 MONOrate指定音频采样率(Hz);即ws信号的频率ibuf指定内部缓冲区长度(字节)
对于所有端口,DMA 在后台连续运行,允许用户应用程序在内部缓冲区与 I2S 外设单元之间传输采样数据的同时执行其他操作。增大内部缓冲区可能会延长用户应用程序在发生下溢(例如
write方法)或上溢(例如readinto方法)之前能够执行非 I2S 操作的时间。方法¶
- init(*, sck: Pin, ws: Pin, sd: Pin, mck: Pin | None = None, mode: int, bits: int, format: int, rate: int, ibuf: int) None¶
参数说明请参阅构造函数
- readinto(buf: bytearray) int¶
将音频采样读入由
buf指定的缓冲区。buf必须支持缓冲区协议,例如 bytearray 或 array。"buf" 的字节序为小端。对于立体声格式,左声道采样位于右声道采样之前。对于单声道格式,使用左声道采样数据。返回读取的字节数
- write(buf: bytes) int¶
写入
buf中包含的音频采样。buf必须支持缓冲区协议,例如 bytearray 或 array。"buf" 的字节序为小端。对于立体声格式,左声道采样位于右声道采样之前。对于单声道格式,采样数据会同时写入左右两个声道。返回写入的字节数
常量¶