1. 课程导学与硬件准备:STM32与WM8960音频开发板介绍、I2S与I2C协议概述、所需硬件清单与接线图
1.1 这门课到底讲什么?
大家好,欢迎来到这门实战课。说实话,音频处理在嵌入式领域一直是个「看着不难,一动手就翻车」的方向。我自己早年做项目时,就因为在I2S时序上少配了一个时钟极性,结果喇叭里全是白噪声,排查了整整两天。
这门课的目标很直接——带你从零开始,用STM32通过I2S和I2C两条总线,把WM8960这颗音频编解码芯片跑起来。你会学到:
- 怎么配置I2S的时钟、帧格式和数据位宽
- 怎么通过I2C读写WM8960的内部寄存器
- 怎么让麦克风输入、耳机输出、喇叭播放都正常工作
- 怎么处理实际项目中常见的坑(比如POP声、时钟失锁、音量突变)
说白了,这不是一本芯片手册的翻译,而是我踩过坑之后总结出来的「能直接用的经验」。
1.2 先认识一下主角:WM8960音频芯片
WM8960是Wolfson(现属Cirrus Logic)推出的一款低功耗立体声编解码器。为什么选它?因为它在嵌入式音频圈子里实在太常见了——开发板、智能音箱、对讲机、便携录音设备,到处都有它的影子。
| 参数 | 数值 | 备注 |
|---|---|---|
| 工作电压 | 2.7V ~ 5.5V | 模拟部分可独立供电 |
| 音频分辨率 | 16/20/24/32 bit | 我一般用24 bit |
| 采样率 | 8k ~ 96k Hz | 常见48k |
| 信噪比 | 98 dB(DAC) | 够用,不发烧 |
| 接口 | I2S + I2C | 控制走I2C,数据走I2S |
| 内置功能 | MIC偏置、耳机驱动、喇叭功放 | 省掉不少外围 |
它的内部框图其实不复杂,核心就是:ADC把模拟音频转成数字,DAC把数字转回模拟,中间通过I2S跟STM32交换数据,而I2C负责告诉它「你用多少采样率」「增益开多大」「要不要静音」。
核心理解:I2C是控制通道,I2S是数据通道。一个管「怎么配」,一个管「怎么传」。这两个搞清楚了,WM8960就拿下了一半。
1.3 再说说I2S和I2C——两条总线各司其职
I2S(Inter-IC Sound)
I2S是数字音频设备之间传输音频数据的串行总线标准。它有三根主要信号线:
- BCLK(位时钟):每个bit一个脉冲,频率 = 采样率 × 位宽 × 通道数
- LRCK(帧时钟/左右声道选择):频率等于采样率,高电平左声道,低电平右声道
- SD(串行数据):音频数据,按位串行传输
举个例子:采样率48kHz、24bit、立体声,BCLK频率就是 48k × 24 × 2 = 2.304 MHz。嗯,这个数你后面配置时钟树时会用到。
我的经验:I2S的时钟极性配置最容易出错。STM32的I2S支持两种模式——CKPOL=0和CKPOL=1。我曾经因为手册看漏了一行,把数据采样沿搞反了,结果音频听起来像「水下说话」。后来我习惯先在示波器上抓BCLK和SD的相位关系,确认无误再往下走。
I2C(Inter-Integrated Circuit)
I2C是飞利浦发明的两线制串行总线,用于芯片间的低速控制通信。两根线:
- SCL(时钟线)
- SDA(数据线)
WM8960的I2C设备地址是7位,默认为0x1A(取决于ADDR引脚电平)。每次通信流程是:
- 主机发送起始条件
- 发送设备地址 + 写标志
- 从机应答
- 发送寄存器地址(1字节)
- 从机应答
- 发送数据(1字节)
- 从机应答
- 主机发送停止条件
说白了,就是「先告诉芯片我要写哪个寄存器,再告诉它写什么值」。后面我们会用HAL库的 HAL_I2C_Mem_Write() 来完成这个操作。
注意:WM8960的寄存器是9位地址 + 9位数据,但I2C传输时拆成了两个字节。具体怎么拼,第3章会详细讲。这里先记住:不要直接用8位寄存器地址去套,会出问题。
1.4 硬件清单——这些东西你得备齐
我建议你按这个清单准备,少走弯路:
| 序号 | 硬件 | 推荐型号/规格 | 数量 |
|---|---|---|---|
| 1 | STM32开发板 | STM32F407VGT6 / STM32H743 | 1 |
| 2 | WM8960音频模块 | WM8960核心板(带晶振) | 1 |
| 3 | 麦克风 | 驻极体麦克风(带偏置) | 1 |
| 4 | 耳机/喇叭 | 3.5mm耳机或8Ω小喇叭 | 1 |
| 5 | 杜邦线/排线 | 母对母、公对母各若干 | 若干 |
| 6 | 面包板 | 830孔 | 1 |
| 7 | USB转串口模块 | CH340 / FT232 | 1 |
| 8 | 示波器/逻辑分析仪 | 建议至少2通道,100MHz以上 | 1(可选但强烈推荐) |
关于开发板:我习惯用STM32F407,因为它的I2S外设比较完整,而且有专用的MCLK输出引脚。如果你用F1系列,注意它没有独立的MCLK,需要从BCLK分频或者外部提供。嗯,这个差异后面会专门讲。
1.5 接线图——照着连,别接反
下面这张图是STM32与WM8960模块之间的核心接线关系。我画成了SVG,方便你对照实物连接。
接线要点:
- MCLK(主时钟):STM32的PC6输出,接到WM8960的MCLKIN。没有MCLK,WM8960内部锁相环无法工作,音频会失真。我见过有人省掉这根线,结果声音像卡带一样。
- I2S_WS / LRCIN:帧同步信号,频率等于采样率。STM32的PB12接WM8960的LRCIN。
- I2S_CK / BCLKIN:位时钟。PB13接BCLKIN。
- I2S_SD / DIN:数据输出(STM32发数据给WM8960)。PB15接DIN。
- I2C_SCL / SCLK:时钟线。PB6接SCLK。
- I2C_SDA / SDIN:数据线。PB7接SDIN。
重要提醒:WM8960模块的供电电压通常是3.3V,但有些模块的模拟部分需要5V。接线前务必确认模块的VDD和VDDIO电压要求。我曾经因为给模拟部分供了3.3V,结果输出音量只有正常的一半,查了半天才发现是供电不足。
1.6 开发环境准备
软件方面,你需要准备:
- STM32CubeMX:用于生成初始化代码,配置时钟树和I2S/I2C外设
- Keil MDK / IAR / STM32CubeIDE:编译和下载代码,选你顺手的就行
- 串口调试助手:打印调试信息,我习惯用SSCOM或MobaXterm
- 逻辑分析仪软件:比如Saleae Logic,抓I2S和I2C波形用
这些工具的安装和基本使用,我默认你已经会了。如果还不太熟,网上教程很多,花半小时过一遍就行。
1.7 本章小结
这一章我们做了三件事:
- 搞清楚了WM8960是什么、能干什么
- 理清了I2S和I2C各自的分工——一个传数据,一个传控制
- 准备好了硬件和接线,明确了每个引脚怎么连