第3章 STM32与WM8960的硬件连接:原理图设计要点与典型电路
硬件连接这事儿,说简单也简单,说复杂也复杂。我见过不少朋友,软件调得飞起,结果板子一回来,I2S没声音,I2C不通,最后查出来是原理图上一个电阻拉错了。嗯,这一章咱们就把这些坑提前填上。
WM8960这颗Codec,说白了就是个混合信号芯片。数字部分跟STM32打交道,模拟部分处理音频信号。中间但凡有一根线没接对,整个系统就哑巴了。我个人习惯是先画一张顶层连接图,把每个信号的角色搞清楚,再动手画原理图。
3.1 I2S引脚映射:选对引脚,少走弯路
STM32的I2S,其实是SPI接口的变种。说白了,就是复用了SPI的硬件资源。但有个关键点——不是所有SPI引脚都能当I2S用。我刚开始做音频项目时,就吃过这个亏,选了个不支持I2S的SPI引脚,结果板子回来只能飞线。
STM32的I2S接口,通常有以下几个信号:
- CK (BCLK):位时钟,WM8960上叫BCLK。这个时钟决定了音频数据的位速率。
- SD (DACDAT/ADCDAT):数据线。WM8960的DACDAT是输入,ADCDAT是输出。STM32的I2S是全双工的,一根线发,一根线收。
- WS (LRCLK):帧同步,也叫左右声道时钟。WM8960上叫LRCLK。频率等于采样率。
- MCK (MCLK):主时钟。这个信号不是所有STM32的I2S接口都有的,需要特别注意。
| STM32 信号 | WM8960 信号 | 功能说明 | 典型频率 |
|---|---|---|---|
| I2S_CK | BCLK | 位时钟,每个bit一个脉冲 | 采样率 × 位宽 × 2 |
| I2S_SD | DACDAT | 音频数据输出(STM32→Codec) | — |
| I2S_WS | LRCLK | 左右声道帧同步 | 等于采样率(如48kHz) |
| I2S_MCK | MCLK | 主时钟,Codec内部PLL参考 | 256×Fs 或 384×Fs |
3.2 I2C引脚映射:控制通道不能马虎
WM8960的寄存器配置,全靠I2C。STM32的I2C引脚,通常就是SCL和SDA。但这里有个坑——WM8960的I2C地址是7位地址0x1A(左对齐),写操作时地址字节是0x34,读操作是0x35。我见过有人把地址搞反了,调了两天没通。
引脚映射方面,STM32的I2C1、I2C2、I2C3都可以用。我个人习惯用I2C1,因为它的引脚(PB6-SCL, PB7-SDA)在大多数开发板上都引出来了,调试方便。
3.3 复位电路:WM8960的脾气你得摸清楚
WM8960的复位引脚是nRST,低电平有效。这个引脚不能悬空,必须接一个上拉电阻到VDDIO。我一般用10kΩ上拉,再加一个0.1μF电容到地,形成RC复位电路。
但这里有个时序要求:WM8960在上电后,nRST必须保持低电平至少10ms,然后拉高。如果复位时间不够,Codec内部状态机可能初始化不完全,导致I2C通信失败。
nRST ──┬── 10kΩ ── VDDIO (3.3V)
│
└── 0.1μF ── GND
STM32这边,可以用一个GPIO来控制nRST。我个人习惯用PB12,这样软件可以随时复位Codec,调试时很方便。
3.4 MCLK时钟源选择:频率不对,一切白费
MCLK是WM8960的心脏。没有MCLK,Codec内部的PLL和DAC/ADC都无法工作。MCLK的频率必须精确,常见的有12.288MHz、11.2896MHz、24.576MHz等。
MCLK的来源有两种方式:
- STM32的I2S_MCK输出:STM32的I2S接口可以产生MCLK,频率由PLL分频得到。这种方式最常用,省掉一个晶振。
- 外部有源晶振:如果STM32的I2S不支持MCLK输出,或者你需要更精准的时钟,可以用一个12.288MHz的有源晶振直接给WM8960。
| 采样率 (Fs) | MCLK = 256×Fs | MCLK = 384×Fs | 常用场景 |
|---|---|---|---|
| 48 kHz | 12.288 MHz | 18.432 MHz | 多媒体、USB音频 |
| 44.1 kHz | 11.2896 MHz | 16.9344 MHz | CD音质、音乐播放 |
| 96 kHz | 24.576 MHz | 36.864 MHz | 高保真录音 |
3.5 典型电路连接:一张图说清楚
下面是我在实际项目中用过的典型连接方式。STM32F407VG + WM8960,I2S2用于音频数据,I2C1用于控制,MCLK由STM32的I2S2_MCK提供。
STM32F407VG WM8960
----------- ------
PB13 (I2S2_CK) ──→ BCLK
PC3 (I2S2_SD) ──→ DACDAT
PB12 (I2S2_WS) ──→ LRCLK
PC6 (I2S2_MCK) ──→ MCLK
PB6 (I2C1_SCL) ──→ SCLK
PB7 (I2C1_SDA) ──→ SDIN
PB15 (GPIO) ──→ nRST (经10k上拉至3.3V)