1. 音频系统概述:数字音频基础与I2S协议详解
各位同学,欢迎来到这门实战课。我是你们的讲师,一个在嵌入式音频领域摸爬滚打多年的工程师。今天咱们先打好地基,聊聊数字音频的那些基础概念,还有I2S协议和WM8960这颗常用的编解码器。
说实话,音频处理这事儿,看着简单,但坑不少。我刚开始做音频项目时,就因为采样率没搞对,放出来的声音像磁带卡住了一样。嗯,咱们一步步来。
1.1 数字音频基础:采样率、位深、声道
模拟声音是连续的波形,但数字系统只能处理离散的0和1。怎么把连续的声音变成数字信号?这就靠三个关键参数:采样率、位深和声道数。
核心公式:音频数据速率 = 采样率 × 位深 × 声道数
举个例子:CD音质,44.1kHz × 16bit × 2声道 = 1.4112 Mbps
采样率(Sample Rate)
采样率就是一秒钟对模拟信号采样的次数,单位是Hz。根据奈奎斯特定理,采样率必须大于信号最高频率的两倍,才能无失真地重建信号。
- 8 kHz:电话语音,够用但音质差
- 44.1 kHz:CD标准,人耳能听到20kHz,两倍就是40kHz,留点余量
- 48 kHz:DVD、专业音频设备常用
- 96 kHz / 192 kHz:高解析音频,录音棚用得多
我个人习惯,做语音项目用16kHz或8kHz就够了,做音乐播放器至少44.1kHz。你想想看,采样率越高,数据量越大,对MCU和DMA的压力也越大。
位深(Bit Depth)
位深决定了每个采样点的精度,也就是动态范围。16bit能表示65536个等级,24bit能表示1677万个等级。
- 8 bit:早期游戏音效,底噪明显
- 16 bit:CD标准,动态范围96dB,够用
- 24 bit:录音室标准,动态范围144dB
- 32 bit:浮点处理,内部运算用
我在项目中遇到过一个问题:用16bit音频在WM8960上播放,总觉得底噪偏大。后来发现是增益设置和位深不匹配。嗯,细节决定成败。
声道(Channels)
- 单声道(Mono):一个声道,数据量最小
- 双声道(Stereo):左右声道,立体声效果
- 多声道:5.1、7.1等,需要多路I2S或TDM
| 参数 | 常见值 | 数据速率(双声道) | 适用场景 |
|---|---|---|---|
| 采样率 | 44.1 kHz | 1.4112 Mbps | CD音质播放 |
| 位深 | 16 bit | — | 通用音频 |
| 采样率 | 48 kHz | 1.536 Mbps | 视频配音 |
| 位深 | 24 bit | — | 高保真录音 |
1.2 I2S协议详解
I2S(Inter-IC Sound)是飞利浦公司制定的数字音频接口协议,专门用来在芯片之间传输音频数据。说白了,就是让MCU和编解码器能“对话”。
I2S总线信号
标准I2S有三条主要信号线:
- SCK(位时钟,BCLK):每个脉冲对应一个数据位。频率 = 采样率 × 位深 × 声道数
- WS(字选择,LRCK):左右声道切换信号。频率 = 采样率
- SD(串行数据):音频数据线,可以是输入或输出
有些系统还会加一条MCLK(主时钟),用于内部锁相环。WM8960就需要MCLK。
经验之谈:我建议你在设计PCB时,I2S的三条线尽量等长,避免信号偏移。曾经有个项目,因为BCLK和SD线长了5mm,导致高频噪声明显。嗯,高频信号就是这么敏感。
I2S数据格式
I2S标准格式下,数据在WS变化后的第二个BCLK上升沿开始传输。MSB在前,LSB在后。位深可以小于硬件位数,比如用16bit数据在32bit的帧里传输。
常见的I2S格式有:
- 标准I2S(Philips格式):WS变化后延迟一个BCLK开始传数据
- 左对齐(Left Justified):WS变化后立即传数据
- 右对齐(Right Justified):数据靠右对齐,LSB在BCLK末尾
- TDM(时分复用):多声道数据在同一总线上分时传输
WM8960支持标准I2S和左对齐格式。我一般用标准I2S,兼容性最好。
I2S时序参数
| 参数 | 说明 | 典型值 |
|---|---|---|
| BCLK频率 | 采样率 × 位深 × 声道数 | 44.1k×16×2=1.4112 MHz |
| LRCK频率 | 等于采样率 | 44.1 kHz |
| MCLK频率 | 通常是采样率的整数倍(256×, 384×) | 11.2896 MHz(44.1k×256) |
| 数据延迟 | WS变化到第一个数据位 | 1个BCLK周期 |
注意:STM32的I2S外设对MCLK有分频限制。我曾经因为MCLK频率设置不对,导致WM8960无法锁定时钟,声音断断续续。一定要查数据手册,算好分频系数。
1.3 WM8960编解码器简介
WM8960是Wolfson(现Cirrus Logic)出品的一款低功耗立体声编解码器。为什么选它?因为它功能全、音质好、而且便宜。我在好几个量产项目里都用过它。
主要特性
- 立体声DAC和ADC:24位精度,信噪比98dB以上
- 内置耳机放大器:可以直接驱动32Ω耳机,省掉外部功放
- 数字信号处理(DSP):3D增强、均衡器、自动电平控制
- 灵活的时钟管理:支持MCLK从11.2896 MHz到24.576 MHz
- I2S / 左对齐 / TDM接口:兼容主流MCU
- 低功耗:播放模式下典型功耗仅10mW左右
内部框图
下面这张图是我画的WM8960核心数据流,你看一眼就明白了。
WM8960与STM32的典型连接
在实际项目中,STM32通过I2S接口发送音频数据,通过I²C接口配置WM8960的寄存器。下面是我常用的引脚分配:
| STM32引脚 | WM8960引脚 | 功能 |
|---|---|---|
| PB13 (SCK) | BCLK | 位时钟 |
| PB12 (WS) | LRCK | 字选择 |
| PB15 (SD) | DIN | 数据输出 |
| PC6 | MCLK | 主时钟 |
| PB6 (I²C SCL) | SCLK | 控制时钟 |
| PB7 (I²C SDA) | SDIN | 控制数据 |
避坑指南:我曾经在布局时把MCLK走线绕了很远,结果WM8960锁相环失锁,声音有爆音。后来把MCLK走线缩短到2cm以内,问题解决。高频时钟线,越短越好。
1.4 本章小结
好了,这一章我们聊了数字音频的三个核心参数:采样率、位深、声道。记住了那个数据速率公式,后面做DMA配置时要用到。I2S协议也不复杂,三条线加一个时钟,搞清楚时序就行。WM8960是个好搭档,功能全、功耗低,后面几章我们会手把手配置它。