🧩 接线说明
ESP32-S3 与 INMP441(麦克风)接法:
| INMP441 引脚 | 功能 | ESP32-S3 引脚(例) | 
|---|---|---|
| VCC | 电源 | 3.3V | 
| GND | 地 | GND | 
| WS (LRCL) | 采样对齐位 | GPIO 42 | 
| SCK (BCLK) | 时钟信号 | GPIO 41 | 
| SD | 数据输出 | GPIO 40 | 
注意:INMP441 是“只输出”的器件。
ESP32-S3 与 MAX98357A(功放)接法:
MAX98357A 一般有 7 个引脚,但实际只需连接这几个:
| MAX98357A 引脚 | 功能 | ESP32-S3 引脚(例) | 
|---|---|---|
| VIN | 电源输入 | 5V(或外接 5V) | 
| GND | 地 | GND(共地) | 
| LRC (WS) | 对齐信号 | GPIO 42 | 
| BCLK | 位时钟 | GPIO 41 | 
| DIN | 数据输入 | GPIO 39 | 
| SD | 静音(可不接,接GND不静音) | 可接 GND | 
| GAIN / CSEL | 增益设置 | 可接 GND 或浮空 | 
🔁 音频通道说明
ESP32-S3 有两个 I²S 控制器,你可以使用:
- I²S0 接收麦克风音频数据(RX)
- I²S1 发送音频给 MAX98357A(TX)
也可以使用 I²S 的全双工模式(某些库支持),用同一组引脚同时做收发。
#include <Arduino.h>
#include <driver/i2s.h>
#define I2S_MIC_PORT I2S_NUM_0
#define I2S_SPK_PORT I2S_NUM_1
#define SAMPLE_RATE     16000
#define I2S_BCLK        41
#define I2S_WS          42
#define I2S_MIC_SD      40
#define I2S_SPK_DIN     39
void setupI2SMic() {
  const i2s_config_t mic_config = {
    .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
    .sample_rate = SAMPLE_RATE,
    .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
    .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
    .communication_format = I2S_COMM_FORMAT_I2S,
    .intr_alloc_flags = 0,
    .dma_buf_count = 4,
    .dma_buf_len = 1024,
    .use_apll = false,
    .tx_desc_auto_clear = false,
    .fixed_mclk = 0
  };
  const i2s_pin_config_t mic_pin_config = {
    .bck_io_num = I2S_BCLK,
    .ws_io_num = I2S_WS,
    .data_out_num = I2S_PIN_NO_CHANGE,
    .data_in_num = I2S_MIC_SD
  };
  i2s_driver_install(I2S_MIC_PORT, &mic_config, 0, NULL);
  i2s_set_pin(I2S_MIC_PORT, &mic_pin_config);
}
void setupI2SSpeaker() {
  const i2s_config_t spk_config = {
    .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX),
    .sample_rate = SAMPLE_RATE,
    .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
    .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
    .communication_format = I2S_COMM_FORMAT_I2S,
    .intr_alloc_flags = 0,
    .dma_buf_count = 4,
    .dma_buf_len = 1024,
    .use_apll = false,
    .tx_desc_auto_clear = true,
    .fixed_mclk = 0
  };
  const i2s_pin_config_t spk_pin_config = {
    .bck_io_num = I2S_BCLK,
    .ws_io_num = I2S_WS,
    .data_out_num = I2S_SPK_DIN,
    .data_in_num = I2S_PIN_NO_CHANGE
  };
  i2s_driver_install(I2S_SPK_PORT, &spk_config, 0, NULL);
  i2s_set_pin(I2S_SPK_PORT, &spk_pin_config);
}
void setup() {
  pinMode(10, OUTPUT);
  digitalWrite(10, HIGH);
  // pinMode(40, OUTPUT);
  // digitalWrite(40, HIGH);
  Serial.begin(115200);
  setupI2SMic();
  setupI2SSpeaker();
  Serial.println("ok");
}
void loop() {
  int16_t buffer[256];
  size_t bytesRead, bytesWritten;
  i2s_read(I2S_MIC_PORT, (void *)buffer, sizeof(buffer), &bytesRead, portMAX_DELAY);
  for (int i = 0; i < bytesRead / 2; i++) {
    buffer[i] = (int16_t)(buffer[i] * 1.8);
  }
  i2s_write(I2S_SPK_PORT, (const void *)buffer, bytesRead, &bytesWritten, portMAX_DELAY);
}