คลาส I2S -- โปรโตคอลบัสเสียง Inter-IC¶
คลาส I2S ขับเคลื่อนบัสเสียง Inter-IC Sound (I2S) ในโหมดคอนโทรลเลอร์ -- MCU จะสร้างสัญญาณนาฬิกาบิต (SCK) และสัญญาณนาฬิกาเลือกคำ (WS) แล้วแลกเปลี่ยนข้อมูลตัวอย่างบนสาย SD ไดรเวอร์รองรับ DMA แบบต่อเนื่องในพื้นหลัง ทำให้ฝั่ง Python ต้องเพียงแค่คอยป้อนข้อมูลให้กับบัฟเฟอร์ตัวอย่างภายใน โหมด Peripheral/รับเท่านั้นไม่รองรับ
รองรับบน STM32 OpenMV cams ที่ต่อวงจร I2S peripheral และ OpenMV Cam RT1062 ไม่เปิดเผยบน OpenMV Cam AE3 (พอร์ต alif)
I2S(2) บน STM32 OpenMV cams ใช้พินร่วมกับ SPI(2) -- นาฬิกาบิตอยู่ที่ P2 (SCK), เลือกคำอยู่ที่ P3 (NSS) และสายข้อมูลอนุกรมเป็นไปตามแนวทาง SPI: TX ใช้ P0 (MOSI), RX ใช้ P1 (MISO)
ตัวอย่าง -- เอาต์พุต (TX) สร้างบัส TX เพื่อขับ DAC เสียงภายนอกที่ 44.1 kHz, 16 บิต mono พร้อมบัฟเฟอร์สำรอง DMA ขนาด 16384 ไบต์ (16 KiB):
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 บิต stereo (ซ้าย + ขวาสลับกัน) พร้อมบัฟเฟอร์สำรอง DMA ขนาด 16384 ไบต์ (16 KiB):
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() จะ return หลังจากการดำเนินการเสร็จสมบูรณ์เท่านั้น:
num_written = audio_out.write(buf) # blocks until buf is drained
num_read = audio_in.readinto(buf) # blocks until buf is filled
แบบไม่บล็อก -- ติดตั้งคอลแบ็กด้วย irq() และเมธอดการถ่ายโอนจะ return ทันที คอลแบ็กจะทำงานจาก MicroPython scheduler เมื่อ DMA ว่างบัฟเฟอร์ TX หรือเต็มบัฟเฟอร์ RX:
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 เป็น stream และสามารถห่อด้วย 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)
Constructor¶
- 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)¶
สร้างออบเจ็กต์ I2S ตาม id ที่กำหนด:
idระบุบัส I2S เฉพาะ ซึ่งขึ้นอยู่กับบอร์ดและพอร์ต
พารามิเตอร์แบบ keyword-only ที่รองรับในทุกพอร์ต:
sckคือออบเจ็กต์พินสำหรับสายนาฬิกาอนุกรมwsคือออบเจ็กต์พินสำหรับสายเลือกคำsdคือออบเจ็กต์พินสำหรับสายข้อมูลอนุกรมmckคือออบเจ็กต์พินสำหรับสายนาฬิกาหลัก ความถี่นาฬิกาหลักเท่ากับอัตราการสุ่มตัวอย่าง × 256modeระบุโหมดรับหรือส่งbitsระบุขนาดตัวอย่าง (บิต) ได้แก่ 16 หรือ 32formatระบุรูปแบบช่อง ได้แก่ STEREO หรือ MONOrateระบุอัตราการสุ่มตัวอย่างเสียง (Hz) ซึ่งเป็นความถี่ของสัญญาณwsibufระบุความยาวบัฟเฟอร์ภายใน (ไบต์)
สำหรับทุกพอร์ต DMA ทำงานต่อเนื่องในพื้นหลังและช่วยให้แอปพลิเคชันผู้ใช้สามารถทำการดำเนินการอื่นๆ ขณะที่ข้อมูลตัวอย่างถ่ายโอนระหว่างบัฟเฟอร์ภายในและหน่วย I2S peripheral การเพิ่มขนาดบัฟเฟอร์ภายในอาจเพิ่มเวลาที่แอปพลิเคชันผู้ใช้สามารถทำงานนอกเหนือจาก I2S ก่อนที่จะเกิด underflow (เช่น เมธอด
write) หรือ overflow (เช่น เมธอดreadinto)Methods¶
- init(*, sck: Pin, ws: Pin, sd: Pin, mck: Pin | None = None, mode: int, bits: int, format: int, rate: int, ibuf: int) None¶
ดูคำอธิบายอาร์กิวเมนต์ใน Constructor
- readinto(buf: bytearray) int¶
อ่านตัวอย่างเสียงลงในบัฟเฟอร์ที่กำหนดโดย
bufbufต้องรองรับโปรโตคอลบัฟเฟอร์ เช่น bytearray หรือ array การเรียงไบต์ของ "buf" เป็นแบบ little-endian สำหรับรูปแบบ Stereo ตัวอย่างช่องซ้ายจะนำหน้าช่องขวา สำหรับรูปแบบ Mono จะใช้ข้อมูลตัวอย่างช่องซ้าย คืนค่าจำนวนไบต์ที่อ่าน
- write(buf: bytes) int¶
เขียนตัวอย่างเสียงที่อยู่ใน
bufbufต้องรองรับโปรโตคอลบัฟเฟอร์ เช่น bytearray หรือ array การเรียงไบต์ของ "buf" เป็นแบบ little-endian สำหรับรูปแบบ Stereo ตัวอย่างช่องซ้ายจะนำหน้าช่องขวา สำหรับรูปแบบ Mono ข้อมูลตัวอย่างจะถูกเขียนไปทั้งช่องขวาและซ้าย คืนค่าจำนวนไบต์ที่เขียน
Constants¶