1. I2S总线协议详解:物理层、数据格式与时序

I2S(Inter-IC Sound)总线,说白了就是数字音频设备之间传音频数据的专用通道。我最早接触它是在做一款车载娱乐系统的时候,那时候被时序折腾得够呛——嗯,后面我会讲到那些坑。

先看一张整体结构图,把I2S的物理连接和数据流向搞清楚:

I2S 总线物理连接与数据流 主设备 (SoC / CPU) 产生BCLK + WS 从设备 (CODEC / DAC) 接收时钟 + 数据 BCLK(位时钟) WS(帧时钟 / LRCLK) SD(串行数据) 数据流向 主设备 → SD线 → 从设备(发送模式)或 从设备 → SD线 → 主设备(接收模式) 时序关键点 • BCLK下降沿采样数据(发送端在上升沿更新数据) • WS高电平 = 左声道,WS低电平 = 右声道(标准I2S)

1.1 物理层:三条线搞定音频传输

I2S总线只需要三根信号线:

  • BCLK(位时钟)——也叫串行时钟SCK。每个脉冲对应一个数据位。采样率 × 位深 × 声道数 = BCLK频率。比如44.1kHz × 16bit × 2ch = 1.4112MHz。
  • WS(字选择)——也叫帧时钟LRCLK。高电平传左声道,低电平传右声道。频率等于采样率。
  • SD(串行数据)——音频数据就靠这根线串行传输。可以是单向,也可以是双向(需要两根SD线)。
我的习惯:画原理图时,我会把BCLK、WS、SD三根线用不同颜色标出来——红色、紫色、橙色。这样查板子的时候一眼就能找到问题。曾经有一块板子音频没声音,我拿示波器一量,发现BCLK和SD线画反了……嗯,硬件工程师和我对视了三秒。

1.2 数据格式:三种主流对齐方式

I2S标准定义了数据怎么对齐到时钟上。实际项目里最常见的是这三种:

格式 数据与WS关系 MSB位置 典型应用
标准I2S 数据在WS变化后延迟1个BCLK WS变化后的第2个BCLK 飞利浦规范、大部分CODEC默认
左对齐 数据与WS变化对齐,无延迟 WS变化后的第1个BCLK 一些DAC、早期音频设备
右对齐 数据对齐到WS结束边界 LSB靠近WS边界 日本厂商、部分DSP

我举个例子帮你理解:假设16位数据,标准I2S格式下,WS跳变后先空一个BCLK,然后才传MSB。左对齐则是WS一变,马上传MSB。右对齐嘛……数据靠右对齐,左边补零。

我曾经踩过的坑:有一次调试一颗日本产的DAC芯片,规格书上写的是"Right Justified"。我按标准I2S配的,结果声音全是噪声。折腾了两天,最后发现右对齐模式下,数据位宽必须配成24位才能正常工作——芯片内部硬性要求。所以,拿到新芯片第一件事:仔细看数据格式说明,别想当然。

1.3 时序要求:上升沿、下降沿与建立时间

时序这东西,说白了就是时钟和数据之间的"默契"。I2S标准规定:

  • 发送端:在BCLK的上升沿更新数据(数据变化)
  • 接收端:在BCLK的下降沿采样数据(数据读取)

为什么要这样设计?因为数据在上升沿更新后,经过半个时钟周期的稳定时间,到下降沿时数据已经稳稳当当的了。这样能保证采样正确。

实际项目中,你还需要关注几个参数:

  • 建立时间(t_su):数据在BCLK下降沿之前必须保持稳定的最短时间
  • 保持时间(t_h):数据在BCLK下降沿之后必须保持稳定的最短时间
  • 时钟周期(t_cy):BCLK的频率决定了最大传输速率

一个经验值:大部分CODEC要求建立时间 ≥ 10ns,保持时间 ≥ 5ns。如果你的SoC跑在很高频率,BCLK可能快到几十MHz,这时候PCB走线长度、负载电容都会影响时序。我建议BCLK频率超过12.288MHz(对应192kHz/32bit/2ch)时,一定要做信号完整性仿真。

1.4 主从模式配置:谁产生时钟?

I2S总线有两种角色:

  • 主模式(Master):产生BCLK和WS时钟信号
  • 从模式(Slave):接收外部时钟,同步传输数据

一个系统里只能有一个主设备。通常SoC做主设备,CODEC做从设备。但也可以反过来——比如CODEC内部有PLL,能自己生成精确时钟,这时候CODEC做主,SoC做从。

配置 谁产生BCLK/WS 适用场景 注意事项
SoC主 / CODEC从 SoC 最常见,SoC提供系统时钟 CODEC必须支持从模式
CODEC主 / SoC从 CODEC CODEC有高精度PLL,或SoC时钟不准 SoC的I2S控制器必须支持从模式
外部时钟源 外部晶振/PLL 多设备同步,低抖动要求 需要额外的时钟分配电路
我建议:刚开始做I2S驱动时,先用主模式把SoC配好,CODEC配成从模式。这样调试时你只需要关注SoC这一侧的时钟配置。等主模式跑通了,再尝试从模式——否则两边都在等对方给时钟,死锁了都不知道。

1.5 多声道扩展:TDM模式

标准I2S只支持两个声道。那如果要做5.1声道、7.1声道或者更多通道呢?这时候就需要TDM(时分复用)模式。

TDM本质上还是那三根线,但WS不再区分左右声道,而是作为一个帧同步信号。每个BCLK周期传输一个声道的数据,多个声道按时间片轮转。

  • 标准I2S:WS = 左右声道标识,每帧2个时隙
  • TDM:WS = 帧起始标识,每帧N个时隙(N=2,4,6,8...)

举个例子:8声道TDM,采样率48kHz,位深24bit,BCLK频率 = 48k × 24 × 8 = 9.216MHz。每个帧里依次传声道0、声道1……声道7的数据。

注意:TDM模式下,所有设备共享同一条SD线。每个设备必须知道自己的时隙位置,不能抢别人的时隙。我曾经见过一个项目,两个CODEC的TDM时隙配置重叠了,结果数据互相干扰,声音里夹杂着"滋滋"的串扰声。排查了很久才发现是时隙偏移配错了1个BCLK。

1.6 调试I2S的实用技巧

最后分享几个我在项目中常用的调试方法:

  1. 示波器看波形:先看BCLK有没有,频率对不对。再看WS是不是在目标采样率。最后看SD线上有没有数据跳变。
  2. 逻辑分析仪抓协议:用逻辑分析仪解码I2S数据,确认数据格式(标准/左对齐/右对齐)和位深是否匹配。
  3. 发固定数据测试:比如发一串0xAAAA(1010 1010 1010 1010),看接收端能不能正确收到。这个模式在示波器上看起来是方波,很容易判断。
  4. 检查MCLK:很多CODEC除了BCLK和WS,还需要一个主时钟MCLK(通常是256×fs或512×fs)。MCLK不对,CODEC内部PLL锁不住,整个系统都不工作。

一句话总结:I2S就是三根线——BCLK定节奏,WS分左右,SD传数据。主从模式选对,数据格式配准,时序别超限,音频就能响。但实际项目中,往往就是这三根线的电平、时序、极性出问题。所以,示波器永远是你最好的朋友。