4. I2S总线协议:数字音频的“高速公路”
做音频嵌入式开发,I2S 是你绕不开的协议。说白了,它就是数字音频芯片之间传数据的标准接口。我最早接触 I2S 是在一个便携播放器项目里,当时 Codec 和 MCU 之间老是对不上声音,查了半天才发现是左右对齐模式配错了。从那以后,我对 I2S 的时序就格外上心。
这一节,咱们就把 I2S 的物理层、时序、三种常见模式、TDM 以及时钟关系彻底讲透。
4.1 物理层与信号线
I2S 总线通常只需要 3 根核心信号线,外加一根可选的主时钟线。你想想看,比起并行接口,这布线省了多少事。
| 信号线 | 全称 | 作用 |
|---|---|---|
| SCK | Serial Clock (位时钟) | 每个脉冲传输 1 bit 数据 |
| WS | Word Select (帧时钟) | 区分左/右声道,高电平=左声道,低电平=右声道 |
| SD | Serial Data | 数据线,串行传输音频采样值 |
| MCLK | Master Clock (主时钟) | 可选,用于 Codec 内部 PLL 或 Σ-Δ 调制器 |
4.2 标准 I2S 时序
标准 I2S 的时序有个关键特征:WS 在 SCK 的下降沿之后变化,而数据在 SCK 的上升沿被采样。这样做的好处是,数据有半个 SCK 周期的建立时间,对接收端更友好。
我画了一张时序图,帮你把信号关系看清楚:
注意看,WS 变化后,数据线并不会立即送出 MSB,而是延迟一个 SCK 周期。这是标准 I2S 和左对齐模式最大的区别。我刚开始做的时候没注意这个细节,结果左右声道数据串位了,排查了好久。
4.3 三种数据对齐模式
实际项目中,你会发现 I2S 设备并不都按标准时序来。常见的还有左对齐和右对齐模式。我整理了一张对比表:
| 模式 | MSB 位置 | WS 与数据关系 | 常见场景 |
|---|---|---|---|
| 标准 I2S | WS 变化后第 2 个 SCK | WS 变化后延迟 1 SCK | 飞利浦协议,最通用 |
| 左对齐 | WS 变化后第 1 个 SCK | WS 变化同时开始传数据 | 日本厂商 Codec,如 AKM |
| 右对齐 | 数据帧末尾对齐 | LSB 对齐到 WS 变化前 | 旧式 DSP 或特定 Codec |
4.4 TDM 时分复用模式
当你要接多个 Codec 或者多通道音频时,TDM 就派上用场了。TDM 本质上是在一条数据线上分时传输多个声道的数据。
举个例子,8 通道 TDM 的时序是这样的:
- WS 不再只是左右声道切换,而是变成帧同步信号
- 每个 WS 周期内,依次传输 Slot 0 ~ Slot 7
- 每个 Slot 可以配置为 16/24/32 bit
我参与过一个车载音响项目,用了 8 通道 TDM 来传输 5.1 声道加两个麦克风。一条 SD 线搞定所有,布线简单多了。
TDM 配置要点:
- Slot 数量必须与通道数匹配
- 每个 Slot 的位宽要一致
- WS 频率 = 采样率 × 帧长度(所有 Slot 位宽之和)
4.5 主时钟与位时钟的关系
这是很多初学者容易搞混的地方。MCLK 和 SCK 到底是什么关系?
简单说:MCLK 是 SCK 的整数倍。常见的倍数关系有:
| 采样率 (fs) | 位宽 | 声道数 | SCK | MCLK (256×fs) | MCLK (384×fs) |
|---|---|---|---|---|---|
| 48 kHz | 16 bit | 2 | 1.536 MHz | 12.288 MHz | 18.432 MHz |
| 48 kHz | 24 bit | 2 | 2.304 MHz | 12.288 MHz | 18.432 MHz |
| 96 kHz | 24 bit | 2 | 4.608 MHz | 24.576 MHz | 36.864 MHz |
你发现没有?MCLK 是固定的 256×fs 或 384×fs,而 SCK 会随位宽变化。这是因为 MCLK 是给 Codec 内部 PLL 用的,它需要稳定的时钟来生成内部调制频率。SCK 则是数据传输时钟,位宽越大,SCK 越高。
4.6 实际项目中的时钟配置流程
最后,我分享一下我在项目中配置 I2S 时钟的步骤:
- 确定采样率 fs:比如 48 kHz
- 确定位宽和声道数:比如 24 bit 立体声
- 计算 SCK:SCK = fs × 位宽 × 声道数 = 48k × 24 × 2 = 2.304 MHz
- 选择 MCLK 倍数:常用 256×fs = 12.288 MHz
- 配置 MCU 时钟分频器:确保 MCLK 和 SCK 是整数倍关系
- 验证时序:用示波器看 WS 是否等于 fs,SCK 是否稳定
嗯,这一步验证千万别省。我见过有人代码配对了,但 PCB 走线太长导致 SCK 信号变形,Codec 就是不工作。示波器一看,波形都圆了。
核心公式:
SCK = fs × 位宽 × 声道数
MCLK = fs × 倍数(256、384、512 等)
MCLK 必须是 SCK 的整数倍,且倍数 ≥ 2
I2S 协议本身不复杂,但细节决定成败。对齐模式、时钟关系、TDM 配置,每一个点都可能在项目中给你挖坑。把这一节吃透,后面 Codec 驱动开发你会顺手很多。