|
I2S协议,全称Inter-IC Sound,主要用于在两个设备之间的同步串口中传输或接收音频数据。在数字设备中有许多需要音频通信的应用,例如添加麦克风或添加扬声器输出以播放某些音频。
在使用音频编解码器、DAC或 ADC的电子设备中有多种音频协议可用。最简单也可能是最好的方法之一是使用 I2S 协议,该协议使用简单的引脚配置并在两个数字音频设备之间进行通信。I2S 协议由飞利浦半导体(现为恩智浦半导体)设计,广泛应用于使用该协议进行数据通信的不同微控制器、编解码器、音频模块、麦克风。
接下来让我们探讨一下I2S的关键特性以及该协议如何在微控制器中工作。
I2S连接 I2S协议使用三根线进行通信。发射器和接收器之间的连接如下所示。
字选择 (WS) 或帧选择(FS) 线: 由于I2S协议同时使用立体声操作,因此可以使用WS引脚选择左声道或右声道。一般情况下,如果WP引脚处于低电平状态,则选择通道1或左通道,反之,如果WS引脚处于高电平状态,则使用右通道。 如果不考虑上述通道选择引脚,I2 协议使用两个在任何串行接口中最常见的引脚。
串行数据引脚或SD: I2S通信协议的第二根线是串行数据或承载数据信号的SD引脚。通过这条线传输数据采用2补码方式。
在I2S数据传输中,首先传输最高有效位 (MSB) ,这样做的原因很明显。在I2S中,从发送器传输到接收器,数据可以采用不同的字长。
因此,如果首先发送MSB,则发送器和接收器将不存在知道传输或传入多少位的相关性。
这就产生了一个新问题,因为接收器和发送器不知道字长,所以匹配数据变得困难,因为在数据传输过程中由于噪声和其他因素可能会丢失数据。这可以使用WS引脚解决。如果接收器的 WS大于发送器的WS,则该字被截断,最低有效数据位设置为0。如果接收器的WS小于发送器的WS,则LSB之后的位被忽略。
位时钟线或BCLK: I2S 通信的最后一个也是最重要的引脚是串行时钟 (SCK),也称为位时钟线 (BCLK)。顾名思义,它是一个时钟引脚,在串行数据通信协议中很重要。
它用于在同一循环中获取所有组件。BCLK线频率取决于采样率、每通道位数以及它使用的通道数。
I2S 时序图 在下图中,显示了时序:
在上面的时序图中,显示了三根线:BCLK、WS、SD。 BCLK 将为I2S线提供所需的时钟周期。 WS将其状态从右声道更改为左声道。
数据通过I2S传输,并在每个时钟周期发送。在I2S数据线的一个时钟周期开始传输MSB之前,WS引脚将其状态从一个通道更改为另一通道。这是因为接收器需要时间来存储先前发送的字并清除寄存器。
ESP32中的I2S控制器功能 ESP32是一种广受欢迎的低成本、支持WiFi和蓝牙的32位微控制器单元,支持I2S功能。
下面是ESP32的I2S控制器功能的完整列表。 ● I2S 控制器驱动程序可以作为系统主机或从机运行。 ● 它还能够充当I2S总线中的发送器或接收器。 ● ESP32有一个专用的 DMA 控制器,可以流式传输样本数据,而无需依赖CPU来复制和检查每个数据样本。 ● I2S外设也支持LCD。在此模式下,I2S数据开始通过并行总线进行通信。在某些LCD和相机模块中需要它。
I2S诺基亚音调发生器 让我们在I2S协议中连接一个扬声器,并使用ESP32 I2S生成一段诺基亚曲调。
然而,由于扬声器是一个模拟设备并且要驱动它,我们需要一个支持I2S的放大器;我们选择使用基于I2S的单声道放大器MAX98357A模块。
下图显示了模块的引脚排列。
模块的三个重要引脚是 BCLK、DIN 和 LRC。 DIN为数据输入引脚,与SD相同,LRC为左右声道选择引脚,与WS相同。
电路连接原理图如下:
ESP32的I2S示例代码 为了运行代码,sampleaac.h头文件包含转换为HEX格式的诺基亚曲调的aac。
头文件的格式是这样的: - const unsigned char sampleaac[] PROGMEM = { 0xFF, 0xF9, 0x5C, 0x80, 0x2E, …………. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xF2
- };
复制代码首先包含所有头文件 - #include "AudioGeneratorAAC.h"
- #include "AudioOutputI2S.h"
- #include "AudioFileSourcePROGMEM.h"
- #include "sampleaac.h"
复制代码
我们使用音频生成器AAC库,该库使用I2S协议生成音频。这可以在下面的 GitHub 中找到:https://github.com/earlephilhower/ESP8266Audio
之后,根据之前提供的引脚图设置引脚。 - #define Bit_Clock_BCLK 27
- #define Word_Select_WS 26
- #define Serial_Data_SD 25
复制代码
然后在setup函数中,设置I2S设备引脚。 - in = new AudioFileSourcePROGMEM(sampleaac, sizeof(sampleaac));
- aac = new AudioGeneratorAAC();
- out = new AudioOutputI2S();
- out -> SetGain(GAIN);
- out -> SetPinout(Bit_Clock_BCLK,Word_Select_WS,Serial_Data_SD);
- aac->begin(in, out);
- }
复制代码loop()函数一直循环播放示例AAC的音频。 - void loop(){
- if (aac->isRunning()) {
- aac->loop();
- } else {
- aac -> stop();
- Serial.printf("Sound Generator\n");
- delay(1000);
- }
- }
复制代码
使用I2S通信在ESP32上播放诺基亚曲调 现在我们知道了ESP32上的I2S通信是如何工作的,接下来就可以建立连接、上传代码并播放测试音频。在本文中,以诺基亚曲调为例。所有东西都已正确连接并准备好进行测试。
希望本文能帮助您在未来的所有项目中使用ESP32 I2S音频。如果您有任何问题,可以随时在本帖下面回复。
|