3. I2C配置与寄存器概览:WM8960 I2C地址、关键寄存器初始化流程
好,咱们正式开始动手之前,得先把WM8960的“门牌号”和“开关”搞清楚。说白了,STM32要跟WM8960说话,全靠I2C这条线。地址搞错了,后面全是白忙活。
我记得刚入行那会儿,有一次调一块板子,I2C怎么都扫不到设备。折腾了半天,最后发现是地址的7位和8位模式搞混了。嗯,这种坑踩过一次就忘不了了。
3.1 WM8960的I2C地址
WM8960的I2C地址是7位地址,默认是0x1A(二进制:001 1010)。
但这里有个容易迷糊的地方——你写代码的时候,左移一位变成8位地址,那就是0x34。很多HAL库的I2C函数直接传7位地址就行,但有些底层驱动要传8位。你得看清楚自己用的库是怎么要求的。
地址速查表
| 配置方式 | 7位地址 | 8位地址(左移1位) |
|---|---|---|
| 默认(CSB_LDO=0) | 0x1A | 0x34 |
| 备用(CSB_LDO=1) | 0x1B | 0x36 |
我的习惯:初始化I2C之后,第一件事就是读WM8960的寄存器0x00(Software Reset),看看能不能读到0x00。能读到,说明I2C通了。这一步能省掉后面一大半的排查时间。
3.2 关键寄存器一览
WM8960有56个寄存器,每个16位宽。但咱们不用全背下来,真正初始化必须碰的,也就那么几个。我把它们分成三类:
- 复位与ID:R0 (0x00) – Software Reset
- 电源管理:R25 (0x19) – Power Management 1、R26 (0x1A) – Power Management 2
- 音频接口:R7 (0x07) – Audio Interface 1、R8 (0x08) – Audio Interface 2
你想想看,如果电源没开,后面配什么都是白搭。所以我个人的初始化顺序是:复位 → 开电源 → 配音频接口 → 配其他。
3.3 初始化流程详解
第一步:软件复位
上电后,WM8960内部状态不确定。先写R0为0x00,让它复位到默认值。
// 写寄存器0x00,数据0x00
uint8_t reg_addr = 0x00;
uint16_t reg_val = 0x0000;
WM8960_WriteReg(reg_addr, reg_val);
// 读回来验证
uint16_t readback = WM8960_ReadReg(0x00);
if (readback != 0x0000) {
// I2C有问题,或者芯片没响应
Error_Handler();
}
我曾经踩过的坑:复位之后不要立刻写下一个寄存器。WM8960内部模拟部分需要一点稳定时间。我一般加个5ms的延时,虽然手册没写,但实测能避免一些奇怪的初始化失败。
第二步:打开电源
R25和R26控制着芯片内部各个模块的供电。默认全是关闭的,所以音频出不来声音。
咱们先开最基本的:
// R25 (0x19): Power Management 1
// 打开VMID、VREF、AINL、AINR
WM8960_WriteReg(0x19, 0x00C0); // Bit7=VMID_EN, Bit6=VREF_EN
// R26 (0x1A): Power Management 2
// 打开左声道DAC、右声道DAC
WM8960_WriteReg(0x1A, 0x01F0); // Bit8=LDACEN, Bit7=RDACEN, Bit6=LOUT1EN, Bit5=ROUT1EN
这里要注意,VMID和VREF是模拟电路工作的基准电压。不开它们,后面的DAC和ADC都是摆设。
第三步:配置音频接口
R7和R8决定了STM32和WM8960之间怎么传数据。I2S格式、位宽、主从模式都在这里。
// R7 (0x07): Audio Interface 1
// 配置为I2S格式,16位数据,左对齐
WM8960_WriteReg(0x07, 0x004A); // Bit6:5=10 (I2S format), Bit4:3=01 (16-bit)
// R8 (0x08): Audio Interface 2
// 配置为主模式,采样率48kHz
WM8960_WriteReg(0x08, 0x0000); // 默认主模式,SR=48kHz
一个小技巧:如果你不确定STM32的I2S配置和WM8960是否匹配,先把WM8960设成从模式(Slave),让STM32做主。这样时钟相位问题少一些。等调通了再改主从。
3.4 完整的初始化序列
下面是我个人项目里常用的初始化序列,你可以直接参考:
void WM8960_Init(void) {
// 1. 复位
WM8960_WriteReg(0x00, 0x0000);
HAL_Delay(5);
// 2. 打开电源
WM8960_WriteReg(0x19, 0x00C0); // VMID + VREF
HAL_Delay(2);
WM8960_WriteReg(0x1A, 0x01F0); // DAC + 输出使能
// 3. 配置音频接口
WM8960_WriteReg(0x07, 0x004A); // I2S, 16bit
WM8960_WriteReg(0x08, 0x0000); // 主模式, 48kHz
// 4. 设置音量(后面章节细讲)
WM8960_WriteReg(0x0A, 0x00FF); // 左声道DAC音量最大
WM8960_WriteReg(0x0B, 0x00FF); // 右声道DAC音量最大
// 5. 取消静音
WM8960_WriteReg(0x02, 0x0100); // 左声道DAC取消静音
WM8960_WriteReg(0x03, 0x0100); // 右声道DAC取消静音
}
3.5 知识结构图
下面这张图把WM8960的I2C配置流程串起来了。你可以把它当成一个检查清单: