4. WM8960 寄存器概览与初始化流程
好,这一章咱们来啃 WM8960 的寄存器。说实话,我第一次看 WM8960 的数据手册时,也被那密密麻麻的寄存器表吓了一跳——整整 56 个寄存器,每个 9 位,加起来 500 多个控制位。但别慌,实际项目中常用的也就那么十几个。我习惯把寄存器分成几类来理解,这样思路就清晰多了。
4.1 寄存器地址映射
WM8960 的寄存器地址范围是 0x00 ~ 0x3F,每个寄存器 9 位数据。注意,是 9 位,不是 8 位。这一点很容易踩坑——你如果用标准的 I²C 8 位写操作,数据会错位。
地址映射的规律其实很简单:
- 0x00 ~ 0x0F:电源管理与复位
- 0x10 ~ 0x1F:音频接口与时钟
- 0x20 ~ 0x2F:音频路径与混音器
- 0x30 ~ 0x3F:音量控制与附加功能
我整理了一张常用寄存器速查表,建议你收藏:
| 地址 | 寄存器名称 | 核心功能 |
|---|---|---|
| 0x00 | Reset | 软件复位,写入 0x00 复位芯片 |
| 0x01 | Power Management 1 | 主电源开关,VREF、VMID 使能 |
| 0x02 | Power Management 2 | 输入/输出 PGA 电源控制 |
| 0x03 | Power Management 3 | 左/右声道混音器电源 |
| 0x04 | Audio Interface | I²S 格式、字长、主从模式 |
| 0x05 | Clock Gen Control | SYSCLK 分频、PLL 使能 |
| 0x06 | Additional Control | DAC/ADC 采样率、去加重 |
| 0x07 ~ 0x0A | GPIO / Jack Detect | GPIO 功能、耳机插入检测 |
| 0x10 ~ 0x15 | Left/Right Input PGA | 输入增益、静音控制 |
| 0x18 ~ 0x1D | Left/Right Output Mixer | 混音器通路选择 |
| 0x2A ~ 0x2F | DAC / ADC Control | 数字音量、软静音、过采样 |
| 0x30 ~ 0x33 | Left/Right Speaker Volume | 扬声器输出音量(每步 0.5 dB) |
| 0x34 ~ 0x37 | Left/Right Headphone Volume | 耳机输出音量 |
#define WM8960_REG_PWR1 0x01,这样代码可读性高得多,也方便后期维护。
4.2 关键寄存器功能说明
寄存器虽多,但真正需要你手写的就那么几个。我挑几个核心的讲讲,其他的你用到时再查手册就行。
4.2.1 电源管理寄存器(0x01 ~ 0x03)
这三个寄存器是 WM8960 的命门。上电顺序错了,芯片可能不工作,甚至烧坏。我见过有人把 VREF 和 VMID 的使能顺序搞反,结果输出端一直有直流偏置,喇叭滋滋响。
Power Management 1 (0x01):
- Bit 8: VREF 使能(必须先开)
- Bit 7: VMID 使能(VREF 稳定后再开)
- Bit 6: AINL/AINR 偏置使能
- Bit 5: 数字核心电源使能
- Bit 4: 偏置发生器使能
Power Management 2 (0x02):
- Bit 8: 左声道输入 PGA 使能
- Bit 7: 右声道输入 PGA 使能
- Bit 6: 左声道 ADC 使能
- Bit 5: 右声道 ADC 使能
- Bit 4: 左声道输出混音器使能
- Bit 3: 右声道输出混音器使能
- Bit 2: 左声道 DAC 使能
- Bit 1: 右声道 DAC 使能
Power Management 3 (0x03):
- Bit 8: 左声道扬声器输出级使能
- Bit 7: 右声道扬声器输出级使能
- Bit 6: 左声道耳机输出使能
- Bit 5: 右声道耳机输出使能
- Bit 4: 左声道 LINEOUT 使能
- Bit 3: 右声道 LINEOUT 使能
4.2.2 音频接口控制寄存器(0x04)
这个寄存器配置 I²S 通信格式。说白了,就是告诉 WM8960:STM32 那边用什么格式发数据给你。
关键位:
- Bit 8: 主从模式选择 — 0 为主模式,1 为从模式。我一般用从模式,让 STM32 提供 BCLK 和 LRCLK。
- Bit 7: BCLK 极性 — 0 为正常,1 为反相。通常保持默认 0。
- Bit 6: LRCLK 极性 — 0 为左声道低电平,1 为左声道高电平。I²S 标准是左声道低电平。
- Bit 5: 字长选择 — 0 为 16 位,1 为 20 位,2 为 24 位,3 为 32 位。我常用 16 位或 24 位。
- Bit 4: 格式选择 — 0 为 I²S,1 为左对齐,2 为右对齐,3 为 DSP 模式。
举个例子,如果你用 STM32 的 I²S 外设,格式通常配成:从模式、I²S 格式、16 位字长、BCLK 和 LRCLK 都正常极性。对应的寄存器值就是 0b00000010,即 0x02。
4.2.3 时钟使能寄存器(0x05)
WM8960 内部有一个 SYSCLK,所有数字模块(ADC、DAC、滤波器)都靠它驱动。SYSCLK 可以来自外部 MCLK,也可以来自内部 PLL。
关键位:
- Bit 8: PLL 使能 — 1 为开启 PLL
- Bit 7: SYSCLK 分频系数 — 0 为不分频,1 为 2 分频
- Bit 6: SYSCLK 源选择 — 0 为 MCLK,1 为 PLL 输出
- Bit 5: BCLK 分频使能 — 用于从 BCLK 产生 SYSCLK
我常用的配置是:外部提供 12.288 MHz MCLK,SYSCLK 直接取 MCLK 不分频。这样 ADC/DAC 的采样率正好是 48 kHz(256 倍过采样)。
4.2.4 音频路径控制(0x08 ~ 0x0D)
这部分控制信号怎么从输入走到输出。WM8960 的路径很灵活,但也容易配错。我画了一张简化的路径图:
从图上你能看到,录音时信号走「LINE_IN → PGA → ADC → I²S」,播放时走「I²S → DAC → 混音器 → SPK_OUT」。每个节点都有对应的使能位和音量控制,缺一个都不行。
4.3 初始化序列设计
好了,寄存器功能都清楚了,接下来就是怎么把它们串起来。初始化序列是 WM8960 能否正常工作的关键。我踩过的坑不少,下面这个序列是我验证过多次的,你照着来基本不会出问题。
4.3.1 上电顺序
WM8960 的上电顺序有严格的时间要求。我总结成 5 步:
- 硬件上电:先给 DVDD(1.8V)和 AVDD(3.3V)供电。注意 DVDD 必须先于或同时于 AVDD 上电。
- 等待电源稳定:至少等 10 ms,让内部 LDO 和参考电压稳定下来。
- 软件复位:向寄存器 0x00 写入 0x00,复位所有寄存器到默认值。
- 使能 VREF 和 VMID:先开 VREF,等 5 ms 后再开 VMID。VMID 的电压是 AVDD/2,作为模拟信号的参考地。
- 使能数字核心和偏置:打开数字核心电源和偏置发生器,再等 2 ms。
4.3.2 时钟启动
时钟是 WM8960 的心脏。我习惯用外部 MCLK,省去配置 PLL 的麻烦。时钟启动步骤:
- 确保外部 MCLK 已经稳定(用示波器看一下波形,别偷懒)。
- 配置寄存器 0x05:选择 MCLK 作为 SYSCLK 源,不分频。
- 配置寄存器 0x04:设置 I²S 格式、字长、从模式。
- 使能 BCLK 和 LRCLK(由 STM32 的 I²S 外设提供)。
如果你非要用 PLL,那就要算分频系数了。公式是:
PLL 输出频率 = MCLK × (N × 2) / (R × 2^K)
其中 N、R、K 是 PLL 配置参数,具体值查手册 Table 42
说实话,PLL 配置挺烦的,我一般只在 MCLK 频率不匹配时才用。比如你只有 12 MHz 晶振,但想要 48 kHz 采样率,那就得开 PLL 把 12 MHz 倍频到 12.288 MHz。
4.3.3 接口配置
接口配置就是让 WM8960 和 STM32 对上话。我以 I²S 从模式、16 位数据、48 kHz 采样率为例:
// 步骤1:软件复位
WM8960_WriteReg(0x00, 0x00);
HAL_Delay(10);
// 步骤2:使能 VREF 和 VMID
WM8960_WriteReg(0x01, 0x0180); // VREF=1, VMID=1
HAL_Delay(5);
// 步骤3:使能数字核心和偏置
WM8960_WriteReg(0x01, 0x01B0); // 加上 DIGEN=1, BIASEN=1
HAL_Delay(2);
// 步骤4:配置时钟
WM8960_WriteReg(0x05, 0x0000); // SYSCLK 来自 MCLK,不分频
// 步骤5:配置音频接口
WM8960_WriteReg(0x04, 0x0002); // 从模式,I²S 格式,16 位
// 步骤6:使能输入路径(录音)
WM8960_WriteReg(0x02, 0x01E0); // 左 PGA=1, 右 PGA=1, 左 ADC=1, 右 ADC=1
// 步骤7:使能输出路径(播放)
WM8960_WriteReg(0x03, 0x01C0); // 左 SPK=1, 右 SPK=1, 左 HP=1, 右 HP=1
// 步骤8:设置音量(避免爆音)
WM8960_WriteReg(0x30, 0x0019); // 左扬声器音量 -30 dB
WM8960_WriteReg(0x31, 0x0019); // 右扬声器音量 -30 dB
4.3.4 完整的初始化流程图
把上面这些步骤串起来,就是一张完整的初始化流程图:
这张图我建议你打印出来贴在工位上。每次调试 WM8960 时,按图索骥,哪一步卡住了就去查对应的寄存器配置,效率会高很多。