I would like to ask how to make the AMB82-MINI successfully drive the INMP441 microphone module to obtain audio data?
I want to use the AMB82-MINI to drive the Inmp441 microphone module under the Arduino framework. I have tried my best with the hal_i2s.h, rtl8735b_audio.h, rtl8735b_i2s.h, rtl8735b_i2s_type.h, rtl8735b_pinmux.h files in the system, but I still cannot drive it.
I connected a 10μF electrolytic capacitor and a 0.1μF ceramic capacitor in parallel directly between the VCC and GND of the INMP441 module. However, no matter how I test it, I am unable to successfully obtain data from the INMP441 module. When powering on, regardless of whether there is sound or not, the voltage between VCC and SD of the INMP441 is 3V, the voltage between VCC and SCK is 0V, and the voltage between VCC and WS is 0V.
Here is my code & serial monitor log:
—————————————————————————————–—————————————————————–
/********************************************************************************
* AMB82-MINI(RTL8735B) 驱动INMP441 + Arduino串口绘图器波形显示
* 纯寄存器操作 | I2S1主接收 | 标准I2S 16bit/16kHz | 串口绘图器纯数值输出
* 硬件接线:AMB82-MINI GPIOD14(SCK)/D17(WS)/D18(RX) → INMP441 SCK/WS/SD
* 串口配置:115200波特率 → 打开Arduino串口绘图器,直接显示声音波形
********************************************************************************/
#include “Arduino.h”
// 包含I2S相关头文件
#ifdef __cplusplus
extern “C” {
#endif
#include “hal_i2s.h”
#include “rtl8735b_pinmux.h”
#ifdef __cplusplus
}
#endif
// 定义I2S缓冲区参数
#define I2S_PAGE_SIZE 256
#define I2S_PAGE_COUNT 4
// I2S适配器
hal_i2s_adapter_t g_i2s_adapter;
// DMA缓冲区
uint8_t i2s_rx_buffer[I2S_PAGE_SIZE * I2S_PAGE_COUNT];
uint8_t i2s_tx_buffer[I2S_PAGE_SIZE * I2S_PAGE_COUNT]; // 即使不用发送,也需要初始化
// 音频数据计数
volatile uint32_t audio_data_count = 0;
// 录音状态
volatile bool is_recording = false;
// 初始化I2S接口
bool initI2S() {
Serial.println("1. 开始初始化I2S适配器...");
// 初始化I2S适配器
memset(&g_i2s_adapter, 0, sizeof(hal_i2s_adapter_t));
// 设置设备号 - 使用I2S1,因为INMP441连接的是I2S1引脚
g_i2s_adapter.dev_num = I2s1_Sel;
// 设置缓冲区指针
g_i2s_adapter.init_dat.i2s_tx_data = i2s_tx_buffer;
g_i2s_adapter.init_dat.i2s_rx_data = i2s_rx_buffer;
// 设置数据字节计数
g_i2s_adapter.init_dat.i2s_data_byte_cnt = I2S_PAGE_SIZE \* I2S_PAGE_COUNT;
// 初始化I2S
HAL_Status status = hal_rtl_i2s_init(&g_i2s_adapter);
if (status != HAL_OK) {
Serial.println("I2S init failed");
return false;
}
Serial.println("2. I2S适配器初始化完成");
// 启用I2S时钟
Serial.println("3. 启用I2S时钟...");
hal_rtl_i2s_en_clk_ctrl(I2s1_Sel, TRUE);
Serial.println("4. I2S时钟启用完成");
// I2S配置 - 针对INMP441的参数
Serial.println("5. 开始配置I2S参数...");
hal_i2s_def_setting_t i2s_setting;
memset(&i2s_setting, 0, sizeof(hal_i2s_def_setting_t));
i2s_setting.i2s_word_len = I2S_WL_24; // INMP441使用24位数据
i2s_setting.i2s_ch_num = I2S_CH_STEREO; // 立体声模式,因为INMP441输出左右声道
i2s_setting.i2s_rate = I2S_SR_16KHZ; // 16kHz采样率
i2s_setting.i2s_trx_act = I2S_ONLY_RX; // 仅接收模式
i2s_setting.i2s_page_num = I2S_4PAGE; // 4个页面
i2s_setting.i2s_page_size = I2S_PAGE_SIZE; // 页面大小
i2s_setting.i2s_byte_swap = I2S_LITTLE_INDIAN; // 字节交换
i2s_setting.i2s_master = I2S_MASTER_MODE; // 主模式
i2s_setting.i2s_format = I2S_FORMAT_I2S; // 标准I2S格式
// 设置I2S参数
hal_rtl_i2s_set_parameter(&g_i2s_adapter, &i2s_setting);
Serial.println("6. I2S参数配置完成");
// 配置DMA缓冲区
Serial.println("7. 配置DMA缓冲区...");
hal_rtl_i2s_set_dma_buf(&g_i2s_adapter, I2S_PAGE_SIZE, I2S_4PAGE);
Serial.println("8. DMA缓冲区配置完成");
// 启用字节交换(处理大端数据)
Serial.println("9. 启用字节交换...");
hal_rtl_i2s_set_byte_swap(&g_i2s_adapter, true);
Serial.println("10. 字节交换启用完成");
// 配置中断掩码
hal_rtl_i2s_intr_ctrl(&g_i2s_adapter, 0, I2S_RX_INT_PAGE0_OK | I2S_RX_INT_PAGE1_OK | I2S_RX_INT_PAGE2_OK | I2S_RX_INT_PAGE3_OK);
// 清除所有中断标志
hal_rtl_i2s_clr_all_intr(&g_i2s_adapter);
// 清除所有页面所有权位
hal_rtl_i2s_clear_all_own_bit(&g_i2s_adapter);
Serial.println("I2S init success");
return true;
}
// 开始录音
void startRecording() {
if (!is_recording) {
// 启用I2S功能
hal_rtl_i2s_func_ctrl(&g_i2s_adapter, TRUE);
is_recording = true;
audio_data_count = 0;
Serial.println("Recording started");
} else {
Serial.println("Already recording");
}
}
// 停止录音
void stopRecording() {
if (is_recording) {
// 禁用I2S功能
hal_rtl_i2s_func_ctrl(&g_i2s_adapter, FALSE);
is_recording = false;
Serial.println("Recording stopped");
Serial.print("Total data recorded: ");
Serial.print(audio_data_count);
Serial.println(" bytes");
} else {
Serial.println("Not recording");
}
}
// 读取单个INMP441采样数据
uint32_t readI2SData() {
// 最简单的方式:直接从DMA缓冲区读取原始24位数据
static uint32_t buffer_index = 0;
// 检查缓冲区是否有数据
if (buffer_index >= I2S_PAGE_SIZE \* I2S_PAGE_COUNT) {
buffer_index = 0;
}
// 直接从DMA缓冲区读取左声道数据(每3字节一个样本)
uint32_t raw_value = (i2s_rx_buffer\[buffer_index\] << 16) | (i2s_rx_buffer\[buffer_index+1\] << 8) | i2s_rx_buffer\[buffer_index+2\];
buffer_index += 3; // 24位数据占3个字节
return raw_value;
}
// Arduino初始化
void setup() {
// 初始化串口(115200波特率,适配绘图器)
Serial.begin(115200);
// 等待串口连接
delay(1000);
Serial.println(“=== AMB82-MINI INMP441 Test ===”);
Serial.println(“Initializing INMP441…”);
// 初始化I2S
if (!initI2S()) {
Serial.println("Failed to initialize I2S");
while (1);
}
// 开始录音
startRecording();
Serial.println(“Start recording…”);
Serial.println(“Opening Arduino Serial Plotter to see waveform…”);
}
// 主循环:实时采样+串口绘图器纯数值输出
void loop() {
// 读取实时音频数据
uint32_t sample = readI2SData();
// 直接输出原始24位数据值+换行(不做任何转换)
Serial.println(sample);
// 无冗余延时,保证波形实时性
}
—————————————————————————————–—————————————————————–
After flashing the firmware, whether or not a sound is emitted, the serial plotter always displays a straight line. The serial monitor log is as follows:
$8735b>=== AMB82-MINI INMP441 Test ===
Initializing INMP441…
- Starting to initialise I2S adapter…
- I2S adapter initialisation completed
- Enabling I2S clock…
- I2S clock enabled
- Starting to configure I2S parameters…
- I2S parameter configuration completed
- Configuring DMA buffer…
- DMA buffer configuration completed
- Enabling byte swapping…
- Byte swapping enabled
I2S init success
Recording started
Start recording…
Opening Arduino Serial Plotter to see waveform…
0
0
0
0
0
0
0
.
.
.
.
continue display 0…