ESP32驱动PCM5102A播放SD卡音频

发布于:2024-12-06 ⋅ 阅读:(38) ⋅ 点赞:(0)

简介

PCM5102A模块是一款立体声DAC模块、音频数模转换器,内部集成了PCM5102芯片。PCM5102芯片是集成了立体声模数转换器(DAC),可实现出色的动态性能并提升针对时钟抖动的耐受度,凭借 DirectPath™电荷泵技术,PCM510xA器件提供2.1 VRMS中央接地输出(设计人员无需在输出上连接隔直电容)以及传统意义上与单电源线路驱动器相关的外部静音电路。集成了软静音也可以硬件静音,实现120dB静音信噪比(SNR)。集成线路驱动器的每个引脚支持低至1kΩ的负载,从而在性能上超过其他所有基于电荷泵的线路驱动器。器件上集成了具有BCK基准的高性能集成音频锁相环(PLL),可在内部生成SCK,免除了对于系统时钟(通常称为主时钟)的需要,从而实现一个3线制I2S连接并减少了系统电磁干扰(EMI)。智能时钟误差与PowerSense 欠压保护采用双层系统,能够消除喀嗒和噼啪声。相比许多传统的开关电容DAC 架构,能够将带外噪声控制在20dB的较低水平,从而减少下游放大器/ADC中的EMI和混叠。当时钟和电源系统出现错误,器件自动衰减数据并启动模拟静音电路。

在这里插入图片描述

模块参数

模块供电电压:DC3.3V 信噪比SNR:112dB 动态范围:112dB
满量程单端输出:2.1 VRMS采样频率:8KHz~384KHz 主时钟频率:50MHz
音频数据位数:16、24、32 工作环境温度:-40℃~85℃ 音频数据格式:IIS、左对齐
总谐波失真(THD+N at-1dBFS):-93dB
模块尺寸:31.8mm23.7mm6.35mm,带一个3.5mm耳机座

功能框图

在这里插入图片描述

引脚定义

PCM5102A芯片在手册上的引脚定义如下:

在这里插入图片描述
对于PCM5102A模块,我们只需了解其中几个引脚功能:

引脚 引脚功能
VCC 模拟电源vcc
3.3V 数字电源vcc
GND 数字/模拟电源地
FLT 滤波器选择:低电平 正常延迟 / 高电平 低延迟
DMP 44.1kHz采样率去重控制:低电平关 / 高电平开
SCL 系统时钟
BCK 位时钟
DIN 音频数据输入
LCK 字时钟
FMT 数据传输模式:低电平 I2S模式 / 高电平 左对齐模式
XMT 软静音控制:低电平 软静音开 / 高电平 软静音关

此外,我们还用到了SD卡模块,共 6 个引脚(GND、VCC、MISO、MOSI、SCK、CS),GND 为地,VCC 为供电电源,MISO、MOSI、SCK 为 SPI 总线,CS 为片选信号脚。
在这里插入图片描述
下面我们来简单了解下PCM5102A模块的通信接口及数据格式。

通信接口和通信数据格式

音频接口端口是一个三线串行端口,信号包括 LRCK、BCK 和 DIN。BCK 是串行音频比特时钟,用于将串行数据(DIN 上的数据)时钟传入音频接口的串行移位寄存器。串行数据在 BCK 上升沿时被时钟输入到 PCM510xA。LRCK 是串行音频左右声道字时钟。以下是PCM5102A支持的通信数据格式、比特深度以及支持的时钟速率。
在这里插入图片描述
PCM510xA 支持行业标准的音频数据格式,包括标准 I2S 和 左对齐(Left-justified) 格式。

I2S模式:
在这里插入图片描述
左对齐模式:
在这里插入图片描述
数据格式通过 FMT 引脚(引脚 16)选择, 低电平选择 I2S 格式,高电平选择 左对齐 格式。所有格式都要求使用 二进制补码格式的 MSB(最高有效位优先)音频数据,最多支持 32 位 音频数据。

通信流程

通过以上我们了解到PCM5102A是一款数字输入, 模拟量输出,内置DAC的一款模块,这个数字信号输入可以输入音频信号,然后经过DAC转换成模拟音频输出,那么我们可以使用ESP32,将SD卡的数字音频信号读取后,再把数据通过I2S协议传输给PCM5102A模块进行音频输出,这样我们就能通过读取SD卡的音频播放音乐了。

在这里插入图片描述

引脚接线

ESP32和PCM5102A

ESP32 PCM5102A
- VCC
3.3V 3.3V
GND GND
GND FLT、DMP、SCL (这里SCL悬空可能会有干扰,所以接地)
D27 BCK
D25 DIN
D26 LCK
GND FMT
3.3V XMT

ESP32和SD模块

ESP32 SD模块
D5 CS
D18 SCK
D23 MOSI
D19 MISO
5V VCC
GND GND

主要代码

#include "Arduino.h"
#include "Audio.h"
#include "SPI.h"
#include "SD.h"
#include "FS.h"

#define SD_CS          5
#define SPI_MOSI      23
#define SPI_MISO      19
#define SPI_SCK       18
#define I2S_DOUT      25
#define I2S_BCLK      27
#define I2S_LRC       26

Audio audio;
File audioFile;

void setup() {
    pinMode(SD_CS, OUTPUT);
    digitalWrite(SD_CS, HIGH);
    SPI.begin(SPI_SCK, SPI_MISO, SPI_MOSI);
    SPI.setFrequency(1000000);
    Serial.begin(115200);
   if (!SD.begin(SD_CS)) {
    Serial.println("初始化 SD 卡失败!");
    return;
  }
  Serial.println("SD 卡初始化成功!");

  // 打开 MP3文件
  audioFile = SD.open("/test.mp3");
  if (!audioFile) {
    Serial.println("无法打开音频文件!");
    return;
  }
  Serial.println("音频文件已打开!");

    audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);
    audio.setVolume(12); // 音量范围:0...21

    audio.connecttoFS(SD, "test.mp3");

}
void loop() {
  audio.loop();
}

在这个代码中,有几个关键的函数我们来看一下:

spi.h

  1. SPI.begin(SPI_SCK, SPI_MISO, SPI_MOSI);
    作用:初始化 SPI 接口

SPI_SCK(Serial Clock):时钟信号,由主设备产生,主设备通过 SCK 控制数据的传输时序。
SPI_MISO( Master Input Slave Output):主设备数据输入,从设备数据输出,从设备通过 MISO 线将数据发送到主设备。
SPI_MOSI(Master Output Slave Input):主设备数据输出,从设备数据输入,主设备通过 MOSI 线将数据发送到从设备。

  1. SPI.setFrequency(1000000);
    作用:设置 SPI 总线时钟的频率

SD.h

  1. SD.begin(SD_CS);
    作用:初始化 SD 卡片选引脚并挂载文件系统。

SD_CS: SD 卡的片选引脚。

Audio.h

  1. audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);
    作用:音频时钟引脚,配置音频数据的传输引脚,将音频信号通过硬件接口(如 I2S)发送到音频输出设备

I2S_BCLK:用于同步音频数据传输的时钟信号,此引脚传输音频数据流的时序信息。
I2S_LRC: 左/右声道选择引脚,用于确定音频数据是左声道还是右声道。
I2S_DOUT:数据输出引脚。

实验效果

在这里插入图片描述

总结

本文介绍了通过ESP32驱动PCM5102A实现播放SD卡音频的功能,主要过程是从SD卡读取音频文件,并通过I2S输出给PCM5102A进行播放,另外如果音频播放存在沙沙声或不稳定的情况,可能是接地不良或电源噪声导致的,实验过程中碰到的一个现象是出现噪声,后面发现PCM5102A的时钟线虽然没有用到但是不能悬空,否则会接触不良、音乐失真。此外检查ESP32和PCM5102A的GND连接,并确保使用稳定的电源,必要情况下可以在电源线上加入滤波电容,以实现音频信号的无损传输。