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配置流程串起来了。你可以把它当成一个检查清单:

WM8960 I2C配置与寄存器初始化流程 WM8960 I2C配置与寄存器初始化流程 1. I2C地址确认 (0x1A / 0x34) 2. 软件复位 (R0 = 0x0000) 3. 电源管理 (R25, R26) 4. 音频接口 (R7, R8) 5. 音量设置 & 取消静音 ⚠ 每一步之间建议加2-5ms延时,确保模拟电路稳定