ESP32-S3_ES8311音频输出使用
ES8311是一款单声道音频编解码器,集成 ADC 和 DAC,专注于音频信号的双向处理:
- 双向编解码:包含 1 路 ADC(模拟输入转数字)和 1 路 DAC(数字转模拟输出),支持麦克风输入和扬声器输出。
- 低功耗设计:工作功耗仅 14mW,适合电池供电设备(如便携式音箱、智能耳机)。
- 高动态范围:DAC 信噪比达 110dB,ADC 为 100dB,兼顾录音和播放的音质平衡。
- 标准 I²S 接口:支持 Philips 标准 I²S、左对齐等格式,与主流主控芯片兼容性强。
电路图
程序编写
1.创建工程
复制官方给的例程文件中的sample_project工程到自建的例程文件夹中并将名字改为ES8311。
右键用VSCode打开,修改工程名字。
2.打开官网提供的外设
同样用VScode打开。
找到ES8311的例程,复制到main.c文件中。
3.修改例程
1.去掉用不到的条件编译
从上往下依次来修改
将static i2s_chan_handle_t rx_handle = NULL;
和#if CONFIG_EXAMPLE_MODE_MUSIC
条件编译去掉。
rx_handle
是用来接收麦克风声音的,这里只用作输出声音,将rx_handle 给去掉。CONFIG_EXAMPLE_MODE_MUSIC
选着工作模块音乐模式和回声模式。将该条件编译去掉或者置一,使用音乐模式。
这句话的意思是通过检查宏CONFIG_EXAMPLE_BSP
是否未被定义的状态。(defined() 是预编译指令,用于检查宏是否存在)。来使用哪种IIC初始化的方式,这里我们使用这个上面的就行。为了简洁好看可以把红框框柱的条件编辑给删除掉。
同样这里的回声模式也可以删除掉。
在IIS初始化函数里将后面的初始化给去掉,使用上面的初始化。
使用音乐模式,也就是使用上面的函数,删除掉下面的条件编译。
主函数里面同样使用上面的音乐模式,删除掉下面的回声模式。
这时所有的条件编译已经修改好了,下面添加程序里用到的宏定义。
2.配置宏定义
新建config.h文件在这个里面放置宏的定义。
更换main.c上面的头文件。按照下面图中进行修改
当你工程找不到头文件如上面图中的头文件下面有波浪线时,可以打开控制面板(ctrl+shift+p),选择添加VS Code配置文件
这样就可以正确找到头文件的路径了。
继续回到添加宏定义。
添加IIC引脚,从原理图上可以看到sda,scl引脚为GPIO_NUM_1和GPIO_NUM_2。
添加es8311配置。从原理图上可以看到EP接到地上,对应地址为0x18,填ES8311_ADDRRES_0即可。ES8311_ADDRRES_0在es8311.h文件里有定义。如果该引脚接VCC了,地址选择ES8311_ADDRRES_1,对应地址为0x19。
其他的参数可以直接复制官方例程上的。
添加IIS驱动函数。具体的引脚可查看原理图。I2S_DI_IO
引脚没用到填-1即可。
取消接收通道。
3.添加音乐片段
将官网库里面的音乐片段复制到这个工程里。
4.添加ES8311库文件
到乐鑫提供的组件管理工具当中搜索ES8311。
选择第一个。
复制这串命令到ESP-IDF终端里运行
注意:这个终端别弄错了。不然运行不了
这时可以看到这里出现一个新的文件。
这个文件需要重新选择下目标芯片才能运行,生成es8311的库文件。
5.添加IO扩展芯片
由于esp32的引脚有限,这里使用了一款PCA9557PW的IO扩展芯片,来控制功放芯片的使能引脚。
该芯片通过IIC与ESP32通信,地址为0001 1A2A1A0。该图中A0脚被拉高所以地址为0001 1001即0x19。
我们来看一下这款芯片的使用规则。
控制寄存器
通过D1和D0这两位来决定使用哪个寄存器
0x00时:输入寄存器
只读(Read-Only)
存储当前 8 个 IO 口(P0~P7)的输入状态(无论 IO 口配置为输入还是输出,均可读取该寄存器获取引脚实时电平)。
位定义(每一位对应一个 IO 口):位 7~ 位 0:对应 P7~P0 的输入状态
0x01时:输出寄存器
可读可写(Read/Write)
设置 IO 口为输出模式时的输出电平(仅当 IO 口通过配置寄存器设为输出时有效)。
位定义(每一位对应一个 IO 口):位 7~ 位 0:对应 P7~P0 的输出电平。
0x02时:极性反转寄存器
可读可写(Read/Write)
反转输入寄存器(0x00)的读取极性(仅影响输入寄存器的数值,不改变实际引脚电平)。
位定义(每一位对应一个 IO 口):位 7~ 位 0:对应 P7~P0 的极性反转控制.
即:高电平为0,低电平为一。
0x03时:配置寄存器
可读可写(Read/Write)
设置每个 IO 口的方向(输入或输出),是核心配置寄存器。
位定义(每一位对应一个 IO 口):位 7~ 位 0:对应 P7~P0 的方向配置1:该 IO 口配置为输入模式(此时输出寄存器的设置无效)0:该IO 口配置为输出模式(受输出寄存器控制)
0xFF(复位后,所有 IO 口默认设为输入模式)
新建PCA9557PW.c和PCA9557PW.h文件。在CMakeLists.txt文件中加入PCA9557PW.c。
c
#include "PCA9557PW.h"
/*****读寄存器******/
esp_err_t PCA9557PW_ReadRegister(uint8_t addr,uint8_t *date,size_t len)
{
return i2c_master_write_read_device(I2C_NUM,PCA9557PW_I2C_ADDRESS,&addr,1,date,len,100);
}
/*****写寄存器******/
esp_err_t PCA9557PW_WriteRegister(uint8_t addr,uint8_t date)
{
uint8_t data[2];
data[0] = addr; // 寄存器地址
data[1] = date; // 寄存器数据
return i2c_master_write_to_device(I2C_NUM, PCA9557PW_I2C_ADDRESS, data, 2, 100);
}
// 初始化PCA9557 IO扩展芯片
void PCA9557PW_Init(void)
{
// 写入控制引脚默认值 DVP_PWDN=1 PA_EN = 0 LCD_CS = 1 (0000 0101)
PCA9557PW_WriteRegister(PCA9557PW_REG_OUTPUT, 0x05); // 设置输出寄存器
// 把PCA9557芯片的IO1 IO1 IO2设置为输出 其它引脚保持默认的输入(1111 0111)
PCA9557PW_WriteRegister(PCA9557PW_REG_CONFIG , 0xF8); // 设置配置寄存器
}
// 设置PCA9557芯片的某个IO引脚输出高低电平
esp_err_t pca9557_set_output_state(uint8_t gpio_bit, uint8_t level)
{
uint8_t data;
PCA9557PW_ReadRegister(PCA9557PW_REG_INPUT, &data, 1); // 读取当前IO状态
if(level){
data |= (1<<gpio_bit); // 设置对应位为1
}
else
{
data &= ~(1<<gpio_bit); // 设置对应位为0
}
return PCA9557PW_WriteRegister(PCA9557PW_REG_OUTPUT, data); // 写入新的输出状态
}
// 控制 PCA9557_LCD_CS 引脚输出高低电平 参数0输出低电平 参数1输出高电平
void lcd_cs(uint8_t level)
{
pca9557_set_output_state(LCD_CS_GPIO, level);
}
// 控制 PCA9557_PA_EN 引脚输出高低电平 参数0输出低电平 参数1输出高电平
void pa_en(uint8_t level)
{
pca9557_set_output_state(PA_EN_GPIO, level);
}
// 控制 PCA9557_DVP_PWDN 引脚输出高低电平 参数0输出低电平 参数1输出高电平
void dvp_pwdn(uint8_t level)
{
pca9557_set_output_state(DVP_PWDN_GPIO, level);
}
c
#pragma once
#include "driver/i2c.h"
#define I2C_SDA_IO (GPIO_NUM_1)
#define I2C_SCL_IO (GPIO_NUM_2)
#define I2C_NUM (I2C_NUM_0)
/*******PCA9557PW*******/
#define PCA9557PW_I2C_ADDRESS 0x19 // Default I2C address for PCA9557PW
#define PCA9557PW_REG_INPUT 0x00 // Input register
#define PCA9557PW_REG_OUTPUT 0x01 // Output register
#define PCA9557PW_REG_POLARITY 0x02 // 极性翻转寄存器
#define PCA9557PW_REG_CONFIG 0x03 //配置寄存器
#define LCD_CS_GPIO BIT(0) // PCA9557_GPIO_NUM_1
#define PA_EN_GPIO BIT(1) // PCA9557_GPIO_NUM_2
#define DVP_PWDN_GPIO BIT(2) // PCA9557_GPIO_NUM_3
void pa_en(uint8_t level);
void PCA9557PW_Init(void) ;
4.修改主函数并下载
1.添加PCA9557PW头文件

2.使能功放引用

3.下载运行
到此所有的程序已经完成了。