先动手把概念摊开说清楚:I2S和PCM放在一起对比,是很多做音频板、嵌入式开发、甚至HiFi DIY的朋友都会纠结的事。尤其是画原理图、选codec芯片或者调蓝牙音频模块的时候,一边写着I2S,一边写着PCM,有人告诉你“这俩差不多”,又有人警告你“千万别接错”,搞来搞去头都大了。这篇就把里面的门道一层层拆开,从协议原理到实际接线,再到我踩过的坑,一次讲明白。
先说结论:I2S和PCM严格来说并不是同一个层面的概念。真正被拿来比较的,是一种叫I2S的数字音频总线协议,和另一种经常被简称为“PCM接口”的同步串行音频总线。两者干的都是同一件活:把PCM编码的数字音频数据从A点搬到B点。不同之处在于,搬数据的方式、时序格式、以及各自适合的应用场景,这两者是实打实不一样的,选错了轻则没声音,重则把芯片引脚配置搞到怀疑人生。
这篇文章适合三类人看:一类是刚入行的嵌入式工程师,正在调音频驱动;一类是自己在家里焊板子、做播放器、改蓝牙音箱的DIY玩家;还有一类是只想知道“我这块板子买回来该接哪个接口”的电子爱好者。不管你属于哪一类,看完之后至少不会再被I2S和PCM这两个词绕晕。
1. 先弄清楚:I2S和PCM哪个好,这个问题本身就问错了
很多入门的朋友第一次看到这两个词,都是从文章列表或者开发板说明里来的,下意识地以为它们是两种互斥的音频方案。但实际上,PCM全称是Pulse-Code Modulation,脉冲编码调制,它是一种把模拟信号变成数字信号的基本编码方法,也就是采样、量化、编码这一整套流程。无论是CD、WAV文件、蓝牙音频还是HDMI音频,只要是数字音频,底层几乎都是PCM数据。
I2S全称是Inter-IC Sound,是飞利浦在1986年左右订的一种数字音频总线标准。它做的事情是把已经编码好的PCM音频数据,用一组特定的时钟和数据线,在芯片与芯片之间传输。你可以把PCM理解成“货物”,把I2S理解成“运输货车”。货车运的是PCM货物,但货车本身不是货物。所以,“PCM和I2S哪个好”这种问法,就好像问“面粉和烤箱哪个好”一样,逻辑上就不太对。
1.1 I2S只是众多运输方式之一
I2S只是运输PCM数据的一种方式。除了I2S之外,还有TDM(时分复用)、PDM(脉冲密度调制)、S/PDIF(同轴/光纤)、USB Audio等方式在各自场景里运音频数据。不同的运输方式有不同的优缺点:I2S走的是短距离板内并行总线,S/PDIF适合长距离机顶盒到功放的音频连接,USB Audio适合做声卡,PDM则大量用于麦克风。
也就是说,I2S并不比其他接口高一等,它只是在“芯片与芯片之间传PCM音频”这件事上,用得最多、生态最成熟的一种方案。
1.2 大家口中的“PCM接口”其实另有所指
问题来了:既然PCM是编码方式,那为什么很多芯片手册、蓝牙模块资料上会明确写“PCM Interface”,而且引脚定义和I2S还长得差不多?那是因为在硬件圈子里,“PCM接口”早就被约定俗成地用来代指一种特定的同步串行音频总线,它的标准特征是用一个SYNC同步脉冲来标识每一帧音频数据开始,而不是像I2S那样用持续的高低电平来区分左右声道。
这种PCM接口大量出现在蓝牙音频芯片上,比如高通QCC系列、瑞昱、恒玄、杰理等主流蓝牙方案,和外挂DAC、DSP或者基带芯片之间的连接。它的最大本事是支持多时隙TDM传输,一条总线可以塞下多路音频数据。所以,大家在选型时真正要做的是“I2S总线”和“PCM总线”的对比,而不是拿编码方式和总线协议去比。
2. 时序细节才是分水岭:从波形角度重新认识两个接口
接口协议这东西,表面看是引脚命名不同,本质上是时序不同。要理解I2S和PCM的差异,必须把BCLK、LRCLK、SYNC这几个信号搞透。
I2S和PCM总线的底层结构很相似,都有位时钟(Bit Clock)、帧同步信号(LRCLK或SYNC)、数据线。而且数据格式都遵循一个基本原则:高位在前(MSB first),按位串行发送。区别主要体现在两个地方:一是帧同步信号的表现形式,二是数据相对同步信号的延迟和对齐方式。
2.1 I2S的四根线:LRCLK就是声道的开关
标准I2S总线通常是四根线:
- BCLK:位时钟,一个脉冲对应一个bit;
- LRCLK:也叫WS(Word Select),低电平表示左声道,高电平表示右声道(这个极性在不同芯片上不一定一致,需要看手册);
- DIN:数据输入到DAC/ADC的线;
- DOUT:数据从DAC/ADC输出的线。
I2S最典型的特征是数据要比LRCLK变化晚一个BCLK周期,也就是所谓的“延迟一拍”。这一拍是为了让接收端在BCLK的下一个边沿稳定采样数据,降低时序冲突风险。同时,LRCLK是连续翻转的方波,频率等于音频采样率(比如44.1kHz)。所以用示波器一看,LRCLK是一条持续的方波,像“左右开关”一样,一个周期对应左右声道各一个采样点。
2.2 PCM接口的SYNC脉冲:一枪打出去,大家分时抢位置
PCM接口同样有BCLK,但帧同步信号不叫LRCLK,常叫做SYNC或FSYNC。关键区别在于,SYNC不是持续方波,而是在每帧开始的时候给一个固定宽度的脉冲。根据SYNC的宽度和数据延迟,业界又分成PCM_A和PCM_B两种标准格式:
- PCM_A:SYNC脉冲宽度等于一个帧长(在双声道时就是一整个BCLK周期×位数的时间),数据在SYNC沿之后延迟1个BCLK;
- PCM_B:SYNC脉冲宽度只有半个帧长,数据延迟0个BCLK。
PCM接口最大的优势是支持TDM(时分复用)。SYNC脉冲标记了帧的起点,帧里面可以划分多个时隙(Slot),每个时隙可以放一路音频数据。标准I2S虽然也可以做TDM扩展,但市面上的I2S外设寄存器大多只支持双声道简单模式。而PCM接口天生就是按多时隙设计的,这在需要同时传多路麦克风、多声道音频、或者DSP级联的时候非常方便。
2.3 I2S还有一堆格式变体,别被“标准”两个字坑了
很多人以为I2S只有一种格式,实际不是。I2S家族里常见的包括标准I2S格式、左对齐(Left Justified)格式、右对齐(Right Justified)格式,也就是索尼的日本电子工业协会格式。它们的数据和LRCLK对齐方式不一样:
- 标准I2S:数据延迟LRCLK变化一个BCLK;
- 左对齐:数据紧跟着LRCLK边沿立刻开始,不延迟;
- 右对齐:数据在LRCLK边沿之后延迟到最后一个bit刚好对齐帧尾部。
codec芯片的寄存器设置里通常会有“Audio Interface Format”这一项,选择I2S还是左对齐右对齐,就必须和MCU侧的外设配置完全一致。否则最常见的现象就是时机不对,出现音量极小、丢码甚至无声。
3. 场景决定选型:到底什么样的设计选I2S,什么样的选PCM
搞懂了时序差异,选型就顺理成章了。我经常对人说,选接口不是看谁先进,而是看你手里有什么芯片、场景要什么功能。
我自己做过的板子里,大部分消费级音频产品,比如ESP32播放器、树莓派DAC解码板、耳机放大器,都是用I2S的。而涉及到蓝牙音频、多麦克风阵列、DSP降噪链路的产品,则大量使用PCM/TDM接口。这背后有一定的产业惯性,但更多是技术需求驱动。
3.1 选I2S的高频场景:HiFi解码、本地播放器、MCU音频
I2S在MCU和DAC之间几乎成了默认配置。拿最常见的一块DAC芯片比如ESS公司的ES9018K2M、AKM家的AK4493,或者入门级的CS4344、MAX98357A来说,数字输入引脚基本都是标准的I2S四线。MCU侧更是如此,ESP32、STM32、RP2040等主流芯片都内置了I2S或者兼容I2S的外设。
选I2S的理由很实际:
- 生态成熟,网上例程、传感器模块、开发板资料最多;
- 双声道立体声场景直接匹配,寄存器配置简单;
- 字长灵活,16bit、24bit、32bit都可以配;
- 大部分Codec芯片的I2S从机模式都做得很标准,接上就能跑。
如果你的设计是MCU播放SD卡里的WAV,或者通过Wi-Fi拿流媒体数据然后本地解码,再接一块DAC芯片输出模拟信号,优先选I2S,基本不会出大问题。
3.2 选PCM的高频场景:蓝牙音频链路、多路复用、DSP级联
蓝牙音频芯片是PCM接口最常见的宿主。比如高通QCC系列的音频模块,和外挂的音频DSP、DAC或者降噪芯片之间,很多就是用PCM/TDM接口连接。原因是蓝牙耳机里经常要同时处理通话上行麦克风信号、下行播放信号、降噪参考信号等多路音频,TDM多时隙能力可以把这些数据全部塞到一组总线上传输。
PCM接口在多麦克风阵列里也很有优势。比如做智能音箱,一条PCM总线上挂4个或8个MEMS麦克风,通过TDM不同时隙把每一路麦克风的PCM数据传给主控DSP做波束成形和语音识别,比每一个麦克风单独接一条I2S总线省下大量引脚和布线空间。
如果你的设计蓝牙主控只给出了PCM接口,而外接DAC又只支持I2S,那就要在中间做桥接,通常有两种方案:一是换一个同时支持I2S和TDM的codec芯片,二是用MCU的SAI外设做格式转换,将PCM数据重新打包成I2S格式。别硬想着把两个不兼容的接口直接并线,那样大概率会得到一片噪声。
3.3 用一张表看看I2S和PCM的差异
| 对比项 | I2S总线 | PCM接口 |
|---|---|---|
| 帧同步信号 | LRCLK,持续方波,区分左右声道 | SYNC,脉冲信号,标记帧起点 |
| 声道支持 | 标准双声道,部分支持TDM扩展 | 支持多时隙TDM,天然多路 |
| 数据延迟 | 标准格式延迟1个BCLK | PCM_A延迟1个BCLK,PCM_B延迟0 |
| 常见格式变体 | 标准I2S、左对齐、右对齐 | PCM_A、PCM_B,以及各种私有变体 |
| 典型应用 | HiFi DAC、MCU音频、播放器 | 蓝牙音频、多麦克风阵列、DSP链路 |
| 调试难度 | 资料多,相对容易 | 时隙概念易错,需要仔细看手册 |
需要注意,这里说的“PCM接口支持多路”也不是所有芯片都支持那么多路,时隙数量和位宽受限于BCLK频率。比如BCLK只有2.048MHz,采样率48kHz,位宽16bit,那一个帧里只能容纳2个时隙多一点,想跑4路就超过了。选型时除了看接口格式,还要算一下BCLK时钟是否够用。
4. 硬件连接与软件配置实操:从原理图到波形验证
接口选定了,接下来就是真正动手的部分。这一节我把接线、电平、主从模式、寄存器配置以及示波器验证的要点全部过一遍。这些都是我在实际项目里反复确认过的东西,照着做能少走很多弯路。
4.1 硬件接线:四根线别接错,电平必须匹配
I2S和PCM在硬件接线级别几乎长得一模一样,都是BCLK、同步信号、数据输入、数据输出四根线。以I2S为例,典型接法是:
- MCU的BCLK接DAC的BCLK;
- MCU的LRCLK接DAC的LRCLK;
- MCU的DOUT接DAC的DIN;
- 如果板子还有录音功能,DAC的DOUT接MCU的DIN。
接线听起来简单,但实际最容易踩坑的第一个问题是逻辑电平。现在的codec芯片有3.3V版本,也有1.8V版本,还有一部分支持5V容忍。如果MCU输出3.3V,DAC的IO电源也是3.3V,那直接连没问题。如果DAC是1.8V电平,MCU是3.3V电平,直接连就可能把DAC的数字输入端打死。哪怕有些芯片手册写“内部有钳位保护”,长期工作也不稳妥。这种情况下要么加电平转换芯片,要么选择支持多种IO电压的codec芯片。第二个坑是主从模式。I2S总线上一端必须做主机,产生BCLK和LRCLK,另一端做从机,根据主机给的时钟来收发数据。如果两端都配成主机,引脚互相打架,很可能烧毁IO。反之两端都配成从机,则时钟没人产生,系统完全静默。
PCM接口的接线思路一样,只是把LRCLK换成SYNC引脚,接法照旧。
4.2 主时钟MCLK这个坑,很多人到打板回来才遇到
I2S标准本身不包含MCLK主时钟,但很多高性能DAC和Codec芯片却要求外部提供一个主时钟。MCLK通常是采样率的整数倍,常见有256倍(256fs)、384倍、512倍。比如采样率44.1kHz,MCLK典型值就是11.2896MHz或12.288MHz(针对48kHz系列)。
如果你的MCU没有输出MCLK,而DAC又要求必须给,解决办法有三条:一是用MCU的另一个定时器/时钟输出引脚产生MCLK;二是选一颗不需要MCLK的DAC芯片,比如内部自带PLL从BCLK恢复主时钟的型号;三是在DAC附近加一颗专用低抖动时钟芯片生成MCLK。这个坑很容易被忽视,原理图评审时一定要检查MCLK到底由谁提供。
4.3 MCU外设配置实例:ESP32和STM32
以ESP32为例,它内置了I2S外设,用Arduino环境写起来非常直接。核心参数有三个:采样率sampleRate、位深bitsPerSample、声道数channels。用ESP32输出I2S给MAX98357A功放时,典型配置是:
#include "driver/i2s.h" void setup() { i2s_config_t i2s_config = { .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX), .sample_rate = 44100, .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, .communication_format = I2S_COMM_FORMAT_STAND_I2S, .intr_alloc_flags = 0, .dma_buf_count = 8, .dma_buf_len = 1024 }; i2s_pin_config_t pin_config = { .bck_io_num = 26, .ws_io_num = 25, .data_out_num = 22, .data_in_num = I2S_PIN_NO_CHANGE }; i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL); i2s_set_pin(I2S_NUM_0, &pin_config); }这段代码里有几个细节容易出错。一是I2S_COMM_FORMAT_STAND_I2S表示用标准I2S格式,如果DAC支持左对齐,这里就要换成I2S_COMM_FORMAT_STAND_MSB。二是I2S_CHANNEL_FMT_RIGHT_LEFT表示左右声道都发送,如果你的音频数据是单声道,又想两边喇叭都响,就要用I2S_CHANNEL_FMT_ONLY_RIGHT或者ONLY_LEFT之类的配置,否则会有一边无声。
STM32的情况类似,但寄存器多,配置散落在好几个外设里。STM32的传统I2S外设挂在SPI上,配置时要选SPI模式为I2S,设置为主模式、标准格式、数据长度和帧长度。STM32H7系列的SAI外设功能更强,支持更多TDM时隙,更适合做PCM接口转换。SAI的配置坑主要在时隙数量和帧同步信号长度两个地方,FRLEN和FSPOL这两个字段填错,波形看起来是全乱的。
4.4 示波器验证:一眼看出I2S还是PCM
调音频驱动,我最推荐的工具是示波器和逻辑分析仪。接好线、写好代码后,先别急着听声音,用示波器同时抓BCLK和LRCLK或SYNC两根线,先看时钟有没有。
I2S模式下的LRCLK应该是连续的方波,频率和采样率一致,高低电平各占一半左右的时间。PCM模式下的SYNC则是脉冲,宽度可以是单个BCLK的若干倍,且只在帧起点出现。如果板子上同时有I2S和PCM接口,只看这两根波形就能立刻分辨出到底用的是哪种模式。
第二步看数据线。播放1kHz正弦波时,DIN或DOUT上的波形应该有规律的跳变。如果数据线一直是高或一直低,多半是主从模式配错,或者codec芯片的复位引脚没拉好,导致芯片没有进入工作状态。如果数据看起来在跳,但DAC输出没声音,就要怀疑LRCLK/SYNC和数据之间的对齐关系,进一步检查是标准I2S还是左对齐/右对齐。
5. 实测中常见问题与解决思路
这一节的内容全是我在调试过程中真实遇到过的问题。我在做蓝牙音箱模块时被PCM的SYNC脉宽坑过一次,做树莓派DAC扩展板时又被左右声道反调过一次。这些坑写出来,是希望大家别在同一个地方跌倒。
5.1 有声音但左右声道反了
这是一个看起来小、但特别影响体验的问题。听人声测试曲目时会觉得歌手的位置在右边而不是正中间,或者左右声道乐器完全换位。原因一般是两个:
- LRCLK的极性配置反了。I2S标准中LRCLK为低时表示左声道,有的codec芯片手册却默认高电平为左声道,如果没看清楚极性就配置,左右就会互换。
- DIN和DOUT接反。有的人焊板子时把MCU的DOUT接到了DAC的DOUT上,数据完全没有进去,自然什么都没得听。如果真的接反了,DAC数据输入悬空或者固定电平,通常不是简单左右互换,而是直接无声。
解决办法:先从软件里把声道极性配置翻转试试,很多外设寄存器里直接有左右声道选择位。软件搞不定再检查硬件接线。这种问题用示波器去量DIN波形,能很快定位。
5.2 开机爆音、一直有沙沙声
爆音问题在DAC和功放场景里特别多。最常见的两种表现是一上电就“砰”一声,或者播放时底噪明显。排查思路分三步走:
第一步,确认时钟是否稳定。BCLK有没有正常翻转?LRCLK是不是准确的44.1kHz或48kHz?MCLK有没有给?任何一个时钟缺失或频率不对,DAC内部数字滤波器就没法正常工作,输出自然是一堆杂音。
第二步,检查主从模式和数据格式。主机从机不匹配也会产生沙沙声,但表现形式往往是音量极小、声音断续的杂音。另外数据位宽不一致也会导致噪音,比如发送端是24bit数据,接收端配置成16bit,数据流中间错位,播放出来的声音就是破碎的。
第三步,排查电源和地线。很多“协议正常、波形漂亮、就是有底噪”的情况,责任不在数字接口本身,而在模拟电源纹波大、地线形成了环路、或者DAC输出到功放的走线太长。杜邦线连接时特别容易引入噪声,建议音频项目的I2S/PCM信号线尽量短,必要时用屏蔽线。
5.3 I2S设备想接PCM设备怎么转
这个问题几乎每周都会在论坛里看到有人问。常见的场景是:手里一块蓝牙芯片输出PCM接口,想接一块I2S输入的DAC;或者反过来,MCU只有I2S,想接一个PCM接口的多路ADC。
最简单的方案是换芯片,选一颗同时支持I2S和TDM/PCM的codec。现在不少codec芯片都支持TDM模式,也就是寄存器里可以把I2S格式切换成多时隙TDM格式,这种用法最省事。如果codec不支持,就只能用MCU做转接,用MCU的I2S接收端读取数据,再用另一个带TDM功能的定时器或SAI外设发送出去。单片机的实时性够不够,取决于数据位数和采样率,简单算一下DMA带宽就知道行不行。如果数据量太大,比如多路高采样率高位深音频同时转接,就得考虑CPLD/FPGA方案了。
5.4 测试时用逻辑分析仪比示波器更方便的场景
调试I2S/PCM数字信号,逻辑分析仪有它的独特优势:可以一次性抓很多通道,而且能自动解析协议。现在很多逻辑分析仪软件,比如Saleae、PulseView,都内置了I2S协议解析器,接上BCLK、LRCLK/SYNC、DATA几根线,软件直接把每个采样点的左右声道数值解析成列表。对于验证数据内容正确性,比示波器直观太多。
不过逻辑分析仪的采样率要足够高。抓音频BCLK通常需要几兆赫兹以上,如果采样率不够,波形会失真,协议解析也会出错。我个人习惯是:先用示波器确认时钟和基本时序,再用逻辑分析仪看数据内容。这两个工具配合起来,排障效率翻倍。
6. 最后分享一点个人经验
调试音频接口这东西,看起来是纯技术活,其实非常考验耐心,因为问题往往不是单一因素造成的。我自己最深的体会是:动手前先打开芯片手册看时序图,尤其注意极性、延迟、主从模式这几项,能省下好几个晚上的调试时间。做接口选型时也不用太纠结“谁比谁强”,先把手头模块的引脚和寄存器吃透,再根据场景选对应的接口方式,很多纠结自然就消失了。
再说一个小技巧:如果手头没有示波器,也可以用带PWM输入捕获功能的MCU去测量BCLK和LRCLK的频率,粗略判断时钟是否正常。虽然看不到波形细节,但至少能确认有没有信号、频率对不对。
数字音频接口的坑并不深,但细节密集。希望这篇梳理能让你少走几步弯路,真正动手时,多抓波形、多看手册,基本上就没有搞不定的问题。