4. PCM帧结构:帧同步信号、位时钟、数据线、帧格式详解

PCM(Pulse Code Modulation)接口是音频Codec与主控(CPU/DSP)之间最常用的数字音频传输总线。理解PCM帧结构是调试音频驱动的基石,任何位时钟偏移、帧同步错位或数据格式不匹配,都会导致无声、杂音或通道错乱。本节从物理信号到数据格式,逐层拆解PCM帧的完整结构。

4.1 PCM接口的三大信号线

一个标准的PCM总线由三根核心信号线组成,外加一根可选的MCLK(主时钟):

信号名称 缩写 方向(Codec侧) 功能描述
位时钟 BCLK / BITCLK 输入或输出 每个脉冲对应一个数据位,决定串行传输速率
帧同步 FSYNC / LRCLK / WS 输入或输出 标识一个音频帧的开始,同时指示左/右声道
数据线 DIN / DOUT / SDATA 输入或输出 串行传输音频采样数据,通常为二进制补码格式
主时钟(可选) MCLK / MASTER CLK 输入 为Codec内部Δ-Σ调制器提供基准时钟,频率通常为BCLK的整数倍
调试要点: 在驱动初始化阶段,务必确认BCLK与FSYNC的极性(上升沿/下降沿采样)以及MCLK与BCLK的分频关系。多数Codec要求MCLK = 256 × Fs 或 384 × Fs,其中Fs为采样率。

4.2 帧同步信号与位时钟的时序关系

帧同步信号(FSYNC)的频率等于音频采样率(Fs),即每秒钟的帧数等于采样率。位时钟(BCLK)的频率则取决于采样率、位宽和通道数:

BCLK = Fs × 通道数 × 位宽

例如:采样率 48kHz,立体声(2通道),16位宽:

BCLK = 48000 × 2 × 16 = 1.536 MHz

帧同步的占空比在不同模式下有差异:

  • 标准I²S模式: FSYNC为50%占空比的方波,高电平表示左声道,低电平表示右声道(或相反,取决于Codec配置)。
  • 左对齐/右对齐模式: FSYNC通常为短脉冲(一个BCLK周期宽度),在脉冲后立即开始传输数据。
  • DSP模式: FSYNC为短脉冲,且数据在FSYNC有效后延迟1个BCLK周期开始传输。
常见错误: 驱动中BCLK与FSYNC的极性配置错误是最常见的无声原因。例如,Codec要求在BCLK下降沿采样,但主控在上升沿发送数据,会导致数据错位一位。务必核对Codec数据手册中的时序图。

4.3 三种主流帧格式详解

PCM接口的帧格式定义了数据位与帧同步信号的对齐方式。主流格式包括左对齐(Left Justified)、右对齐(Right Justified)和DSP模式(DSP Mode / PCM Mode)。

4.3.1 左对齐(Left Justified)

左对齐格式中,数据字的最高位(MSB)在帧同步信号有效后的第一个BCLK周期立即开始传输。数据位紧贴帧同步边沿,没有延迟位。左对齐常用于早期DAC/ADC,兼容性较好。

  • 特点: MSB与FSYNC边沿对齐,无延迟位。
  • 适用场景: 部分老式Codec、飞利浦标准I²S的变体。
  • 驱动配置: 通常需要设置 SND_SOC_DAIFMT_LEFT_J。

4.3.2 右对齐(Right Justified)

右对齐格式中,数据字的最低位(LSB)在帧同步信号结束前的最后一个BCLK周期对齐。这意味着数据字的MSB可能不在帧开始处,而是根据位宽填充前导零。右对齐在早期日本厂商的Codec中较为常见。

  • 特点: LSB与FSYNC结束边沿对齐,高位补零。
  • 适用场景: 部分AKM、NJR系列Codec。
  • 驱动配置: 通常需要设置 SND_SOC_DAIFMT_RIGHT_J。

4.3.3 DSP模式(DSP Mode / PCM Mode)

DSP模式是一种时分复用(TDM)变体,帧同步信号为短脉冲,数据在FSYNC有效后延迟1个BCLK周期开始传输。左声道和右声道的数据连续传输,中间无间隙。DSP模式在蓝牙音频、数字无线麦克风和部分DSP Codec中广泛使用。

  • 特点: FSYNC为短脉冲,数据延迟1 BCLK,左右声道连续传输。
  • 适用场景: 蓝牙A2DP、Qualcomm WCD系列、TI TLV320系列。
  • 驱动配置: 通常需要设置 SND_SOC_DAIFMT_DSP_A(延迟1 BCLK)或 SND_SOC_DAIFMT_DSP_B(无延迟)。
避坑指南: DSP模式下的“延迟1 BCLK”是常见陷阱。如果主控配置为DSP_A(延迟1 BCLK),但Codec配置为DSP_B(无延迟),则数据会整体偏移1位,导致LSB丢失、MSB补零,产生严重失真。调试时务必通过逻辑分析仪抓取FSYNC与数据线的相对位置。

4.4 帧格式对比表

格式 FSYNC类型 MSB对齐位置 LSB对齐位置 延迟位 典型应用
左对齐 短脉冲或50%占空比 FSYNC有效边沿 帧内固定位置 0 老式DAC、飞利浦标准
右对齐 短脉冲 帧内高位补零 FSYNC结束边沿 0 AKM、NJR Codec
DSP模式(A/B) 短脉冲 FSYNC后1 BCLK(A)或0 BCLK(B) 帧结束前 0或1 蓝牙、DSP Codec、TDM

4.5 PCM帧结构SVG示意图

下图展示了标准I²S(左对齐变体)与DSP模式在一个完整帧内的数据排列差异。图中以16位立体声为例,BCLK频率为1.536 MHz,Fs = 48 kHz。

PCM帧结构对比:I²S左对齐 vs DSP模式 PCM帧结构对比:I²S左对齐 vs DSP模式(16位立体声) t BCLK I²S FSYNC 左声道(高电平) 右声道(低电平) I²S DATA 左声道数据(MSB→LSB) 右声道数据(MSB→LSB) DSP FSYNC 脉冲 脉冲 DSP DATA 左声道数据(延迟1 BCLK) 右声道数据(连续) 延迟1 BCLK 说明: I²S左对齐:MSB在FSYNC边沿立即传输,左右声道各占16 BCLK,FSYNC为50%占空比。 DSP模式:FSYNC为短脉冲,数据延迟1 BCLK后开始,左右声道连续传输,无间隙。

4.6 驱动中帧格式配置实战

在Linux ALSA驱动中,帧格式通过 snd_soc_dai_set_fmt() 接口配置。以下是一个典型的立体声PCM接口初始化代码片段:

/* 配置DAI格式:DSP模式,延迟1 BCLK,BCLK下降沿采样,FSYNC高电平有效 */
int ret = snd_soc_dai_set_fmt(codec_dai, 
                              SND_SOC_DAIFMT_DSP_A |
                              SND_SOC_DAIFMT_NB_NF |
                              SND_SOC_DAIFMT_CBS_CFS);
if (ret < 0) {
    dev_err(dev, "Failed to set DAI format: %d\n", ret);
    return ret;
}

/* 配置数据宽度为16位 */
ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x3, 0x3, 2, 16);
if (ret < 0) {
    dev_err(dev, "Failed to set TDM slot: %d\n", ret);
    return ret;
}

/* 配置系统时钟 */
ret = snd_soc_dai_set_sysclk(codec_dai, 0, 12288000, SND_SOC_CLOCK_IN);
if (ret < 0) {
    dev_err(dev, "Failed to set sysclk: %d\n", ret);
    return ret;
}
关键参数说明:
SND_SOC_DAIFMT_DSP_A:DSP模式,数据延迟1 BCLK。
SND_SOC_DAIFMT_NB_NF:正常BCLK极性(上升沿采样),正常FSYNC极性(高电平有效)。
SND_SOC_DAIFMT_CBS_CFS:Codec作为BCLK和FSYNC的从设备(由主控提供时钟)。
snd_soc_dai_set_tdm_slot():配置TDM时隙掩码为0x3(启用slot 0和1),每个slot宽度为16位。

4.7 调试检查清单

当PCM接口出现无声或杂音时,按以下顺序排查帧结构相关项:

  1. BCLK频率计算: 使用示波器或逻辑分析仪测量BCLK频率,确认与 Fs × 通道数 × 位宽 一致。
  2. FSYNC极性: 确认FSYNC高电平对应左声道还是右声道,与Codec数据手册一致。
  3. 数据对齐: 抓取FSYNC与数据线的相对位置,确认MSB是否在预期位置开始传输。
  4. 延迟位检查: 对于DSP模式,确认数据是否延迟了1个BCLK周期。
  5. 位宽匹配: 确认主控发送的位宽与Codec配置的位宽一致,避免高位截断或低位补零错误。
推荐工具: Saleae Logic Analyzer(逻辑分析仪)配合Sigrok PulseView,可以直观地解码PCM帧结构,自动标注通道和数据值。在驱动调试初期,使用该工具抓取一段音频数据,与预期值对比,能快速定位帧格式配置错误。