1. 课程导论:I2S总线协议基础与音频编解码器WM8960概览

各位同学,欢迎来到这门课。我是你们的老朋友,一个在Linux音频驱动里摸爬滚打了十几年的工程师。今天咱们先不急着写代码,先把地基打牢。这一章,我们聊聊I2S总线协议和WM8960这颗编解码芯片。

音频驱动开发,说白了就是让CPU和音频芯片“说上话”。而I2S,就是它们之间最常用的“普通话”。WM8960呢,则是一个很典型的“听话方”——它知道怎么把数字信号变成声音,也知道怎么把声音变成数字信号。

核心认知: 搞懂I2S的时序和WM8960的寄存器,你就掌握了音频驱动开发的一半。剩下的,就是怎么在Linux框架里把它们“串”起来。

1.1 I2S总线协议:数字音频的“高速公路”

I2S,全称Inter-IC Sound,是飞利浦公司在80年代搞出来的。它的设计初衷很简单:让不同的音频芯片之间能干净地传输数字音频数据。

我刚开始接触I2S时,总觉得它跟SPI很像。确实,它们都是同步串行总线。但I2S有个关键区别——它专门为音频优化了数据格式。你想想看,音频数据是连续的流,不能有中断,所以I2S的帧同步信号(LRCLK)是50%占空比的方波,而不是SPI那种片选信号。

I2S的物理信号线

标准的I2S总线只需要三根线:

  • SCK(位时钟):也叫BCLK,决定每个数据位的传输速率。比如48kHz采样率、24位精度、双声道,SCK频率就是48k × 24 × 2 = 2.304MHz。
  • WS(声道选择):也叫LRCLK,高电平表示左声道,低电平表示右声道(也有反的,看具体芯片)。频率等于采样率。
  • SD(串行数据):就是音频数据线。数据在SCK的某个边沿被采样。

我的经验: 实际项目中,很多SoC会把I2S扩展成4根线——增加一条MCLK(主时钟)。MCLK通常是采样率的256倍或512倍,用来给编解码器内部锁相环提供参考。WM8960就需要MCLK,这点后面会细说。

I2S数据格式

I2S标准规定:数据在SCK的下降沿变化,在上升沿被锁存。WS信号在数据发送前的一个SCK周期切换。说白了,就是左声道数据紧跟着WS的跳变沿开始传输。

我遇到过不少新手,在调试时发现声音左右声道反了。原因往往是WS极性配置错了。嗯,这里要注意:不同厂商的I2S控制器,WS的极性定义可能不一样。有的认为高电平是左声道,有的认为是右声道。查手册时一定要看清楚。

参数 典型值 说明
采样率 8k / 16k / 44.1k / 48k / 96k Hz 决定WS频率
数据位宽 16 / 20 / 24 / 32 bit 每个采样点的位数
SCK频率 采样率 × 位宽 × 声道数 例如48k×24×2=2.304MHz
MCLK频率 采样率 × 256 / 384 / 512 WM8960常用12.288MHz

1.2 WM8960编解码器:一颗“全能型”音频芯片

WM8960是Wolfson(现属Cirrus Logic)推出的一款低功耗立体声编解码器。为什么选它作为课程的主角?因为它太典型了——集成了DAC、ADC、耳机放大器、扬声器驱动器、数字信号处理模块,几乎覆盖了消费级音频产品的所有需求。

我记得2015年做一个智能音箱项目,主控芯片是i.MX6,音频方案就是WM8960。当时选它的原因很简单:一颗芯片搞定所有音频通路,省PCB面积,省BOM成本。

WM8960的核心特性

  • 立体声DAC:信噪比98dB,支持24位/96kHz
  • 立体声ADC:信噪比94dB,支持24位/48kHz
  • 内置耳机放大器:可直接驱动16Ω/32Ω耳机
  • 内置扬声器驱动器:单声道1W@8Ω,BTL输出
  • 数字接口:I2S、左对齐、右对齐、DSP模式
  • 控制接口:I2C或SPI,用于配置寄存器
  • 内部锁相环:可从MCLK生成内部时钟

避坑指南: 我曾经在一个项目里,WM8960的扬声器输出一直有“噗噗”的噪声。查了两天才发现,是扬声器驱动器的电荷泵电容选型不对。WM8960的电荷泵需要4.7μF的陶瓷电容,我用了10μF,导致启动时序异常。所以,硬件设计时一定要严格按数据手册推荐的BOM来。

WM8960的音频通路

WM8960内部有两条主要的音频通路:

  1. 播放通路(DAC):数字音频数据 → 数字滤波器 → DAC → 混音器 → 耳机/扬声器输出
  2. 录音通路(ADC):麦克风输入 → 前置放大器 → ADC → 数字滤波器 → 数字音频数据

这两条通路可以同时工作,实现全双工通信。这也是为什么WM8960很适合VoIP和双向对讲设备。

1.3 I2S与WM8960的“握手”

现在我们把I2S和WM8960串起来看。CPU通过I2S接口发送数字音频数据给WM8960,WM8960的DAC把这些数据转换成模拟信号,再通过耳机或扬声器播放出来。反过来,麦克风采集的模拟信号,经过WM8960的ADC转换成数字数据,再通过I2S送回CPU。

控制通路呢?靠I2C或SPI。CPU通过I2C总线读写WM8960的寄存器,配置采样率、音量、增益、滤波器等参数。

下面这张图,是我画的一个典型系统框图,帮你理清数据流和控制流的关系。

I2S + WM8960 系统架构图 CPU / SoC I2S 控制器 WM8960 编解码器 I2S (SCK/WS/SD) I2C (SCL/SDA) 扬声器 8Ω / 1W 麦克风 驻极体 / MEMS DAC输出 ADC输入 说明: • 数据流:CPU ↔ I2S ↔ WM8960 ↔ 模拟端 • 控制流:CPU ↔ I2C ↔ WM8960 寄存器 • MCLK由CPU提供,WM8960内部PLL可选

1.4 为什么选择WM8960作为教学芯片?

市面上编解码器那么多,为什么我偏偏选WM8960?原因有三:

  • 文档齐全:WM8960的数据手册和应用笔记写得非常详细,寄存器描述清晰,时序图规范。这对初学者来说太重要了。
  • Linux支持成熟:内核里已经有现成的WM8960驱动(sound/soc/codecs/wm8960.c),代码质量高,注释丰富。你可以直接拿它当模板学习。
  • 功能全面但不复杂:它涵盖了音频编解码器的大部分典型功能模块,但又没有高端芯片那些花里胡哨的DSP算法。适合用来理解音频驱动的基本框架。

我的建议: 如果你手头有树莓派或i.MX系列的开发板,可以买一块WM8960的模块(淘宝上几十块钱),配合逻辑分析仪,边学边测。看波形、读寄存器、调参数,比光看书效率高十倍。

1.5 本章小结

这一章我们聊了I2S总线的基本概念——三根线、数据格式、时钟关系。也介绍了WM8960这颗编解码器的核心特性和音频通路。最后用一张系统框图,把CPU、I2S、WM8960、扬声器、麦克风之间的关系理清楚了。

说白了,音频驱动开发就是两件事:配好I2S的时序参数,配好WM8960的寄存器。后面的章节,我们会一步步深入,从设备树配置开始,到ALSA框架,再到WM8960驱动的具体实现。准备好了吗?