ESP32 学习笔记(七)I2S - Inter—IC Sound

I2S

概述

ESP32包含两个I2S外设。 这些外设可配置为通过I2S驱动程序输入和输出样本数据。

I2S 标准总线定义了三种信号:时钟信号BCK、声道选择信号WS 和串行数据信号SD。一个基本的I2S 数据总线有一个主机和一个从机。主机和从机的角色在通信过程中保持不变。ESP32 的I2S 模块包含独立的发送和接收声道,能够保证优良的通信性能。

I2S外设支持DMA,这意味着它可以传输使用样本数据流,而无需CPU读取或写入每个样本。

I2S输出也可以直接路由到数字/模拟转换器输出通道(GPIO 25和GPIO 26),直接产生模拟输出,而不是通过外部I2S编解码器。

对于高精度时钟应用,APLL时钟源可与.use_apll = true一起使用,ESP32将自动计算APLL参数。

如果use_apll = true且fixed_mclk> 0,则I2S的主时钟输出固定且等于fixed_mclk值。 音频时钟速率(LRCK)始终为MCLK除数,0<MCLK / LRCK / channels / bits_per_sample <64

这里写图片描述

图1 I2S 系统框图

图1是ESP32 I2S 模块的结构框图,图中”n” 对应为0 或1,即I2S0 或I2S1。每个I2S 模块包含一个独立的发送单元(Tx) 和一个独立的接收单元(Rx)。发送和接收单元各自有一组三线接口,分别为时钟线BCK,声道选择线WS 和串行数据线SD。其中,发送单元的串行数据线固定为输出,接收单元的串行数据线固定为接收。发送单元和接收单元的时钟线和声道选择线均可配置为主机发送和从机接收。在LCD 模式下,串行数据线扩展为并行数据总线。I2S 模块发送和接收单元各有一块宽32 bit、深64 bit 的FIFO。此外,只有I2S0 支持接收/发送PDM 信号并且支持片上DAC/ADC 模块。

图1 右侧为I2S 模块的信号总线。Rx 和Tx 模块的信号命名规则为: I2SnA_B_C。其中”n” 为模块名,表示I2S0或I2S1;”A” 表示I2S 模块的数据总线信号的方向,”I” 表示输入,”O” 表示输出;”B” 表示信号功能;”C” 表示该信号的方向,”in” 表示该信号输入I2S 模块,”out” 表示该信号自I2S 模块输出。各信号总线的具体描述见表1。除I2Sn_CLK 信号外,其他信号均需要经过GPIO 交换矩阵和IO_MUX 映射到芯片的管脚。I2Sn_CLK 信号需要经过IO_MUX 映射到芯片管脚。

表1 I2S 信号总线描述

I2S 信号总线描述

主要特性

I2S 模式

  • 可配置高精度输出时钟;
  • 支持全双工和半双工收发数据;
  • 支持多种音频标准;
  • 内嵌A 律压缩/解压缩模块;
  • 可配置时钟;
  • 支持PDM 信号输入输出;
  • 收发数据模式可配置。

LCD 模式

  • 支持外接LCD;
  • 支持外接Camera;
  • 支持多种LCD 模式;
  • 支持连接片上DAC/ADC 模式。

I2S 中断

  • I2S 接口中断;
  • I2S DMA 接口中断。

应用示例

esp-idf中提供了完整的I2S示例:peripherals/i2s.

I2S配置的简短示例:

#include "driver/i2s.h"
#include "freertos/queue.h"

static const int i2s_num = 0; // i2s port number

static const i2s_config_t i2s_config = {
     .mode = I2S_MODE_MASTER | I2S_MODE_TX,
     .sample_rate = 44100,
     .bits_per_sample = 16,
     .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
     .communication_format = I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB,
     .intr_alloc_flags = 0, // default interrupt priority
     .dma_buf_count = 8,
     .dma_buf_len = 64,
     .use_apll = false
};

static const i2s_pin_config_t pin_config = {
    .bck_io_num = 26,
    .ws_io_num = 25,
    .data_out_num = 22,
    .data_in_num = I2S_PIN_NO_CHANGE
};

...

    i2s_driver_install(i2s_num, &i2s_config, 0, NULL);   //install and start i2s driver

    i2s_set_pin(i2s_num, &pin_config);

    i2s_set_sample_rates(i2s_num, 22050); //set sample rates

    i2s_driver_uninstall(i2s_num); //stop & destroy i2s driver

配置I2S以使用内部DAC进行模拟输出的简短示例:

#include "driver/i2s.h"
#include "freertos/queue.h"

static const int i2s_num = 0; // i2s port number

static const i2s_config_t i2s_config = {
     .mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN,
     .sample_rate = 44100,
     .bits_per_sample = 16, /* the DAC module will only take the 8bits from MSB */
     .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
     .communication_format = I2S_COMM_FORMAT_I2S_MSB,
     .intr_alloc_flags = 0, // default interrupt priority
     .dma_buf_count = 8,
     .dma_buf_len = 64,
     .use_apll = false
};

...

    i2s_driver_install(i2s_num, &i2s_config, 0, NULL);   //install and start i2s driver

    i2s_set_pin(i2s_num, NULL); //for internal DAC, this will enable both of the internal channels

    //You can call i2s_set_dac_mode to set built-in DAC output mode.
    //i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN);

    i2s_set_sample_rates(i2s_num, 22050); //set sample rates

    i2s_driver_uninstall(i2s_num); //stop & destroy i2s driver

API Reference

Header File

猜你喜欢

转载自blog.csdn.net/qq_27114397/article/details/81611917