嘉楠科技
直播中

恩可口

9年用户 843经验值
私信 关注
[问答]

请问K210如何配置I2S读取MIC阵列数据?


K210的I2S,有3个设备,4个通道,如何配置同时可以读取麦克风阵列中多个麦克风的数据?
i2s_rx_channel_config ( I2S_DEVICE_0 , I2S_CHANNEL_0 , RESOLUtiON_16_BIT , SCLK_CYCLES_32 , TRIGGER_LEVEL_4 , STANDARD_MODE );
i2s_rx_channel_config ( I2S_DEVICE_0 , I2S_CHANNEL_1 , RESOLUTION_16_BIT , SCLK_CYCLES_32 , TRIGGER_LEVEL_4 , STANDARD_MODE );
i2s_rx_channel_config ( I2S_DEVICE_0 , I2S_CHANNEL_2 , RESOLUTION_16_BIT , SCLK_CYCLES_32 , TRIGGER_LEVEL_4 , STANDARD_MODE );
i2s_rx_channel_config ( I2S_DEVICE_0 , I2S_CHANNEL_3 , RESOLUTION_16_BIT , SCLK_CYCLES_32 , TRIGGER_LEVEL_4 , STANDARD_MODE );
软硬件版本信息
K210. sipeed.
尝试解决过程
i2s_recv_data_dma ( I2S_DEVICE_0 , rx_buf , 8, DMAC_CHANNEL0 )
i2s_recv_data_dma ( I2S_DEVICE_0 , rx_buf , 8, DMAC_CHANNEL1 )
i2s_recv_data_dma ( I2S_DEVICE_0 , rx_buf , 8, DMAC_CHANNEL2 )
i2s_recv_data_dma ( I2S_DEVICE_0 , rx_buf , 8, DMAC_CHANNEL3 )
补充材料
        你好,请使用Sipeed的MIC Array代码进行开发。
        谢谢你的回答。MIC array 不能提供各个MIC的原始数据,MIC 阵列有7个MIC,所有的MIC的WS,CLK是共用的,只有数据线不同,使用多路I2S同时读取各个MIC的数据,需要配置4个数据线,WS,CLK,
fpioa_set_function(args[ARG_i2s_d0].u_int, FUNC_I2S0_IN_D0);
fpioa_set_function(args[ARG_i2s_d1].u_int, FUNC_I2S0_IN_D1);
fpioa_set_function(args[ARG_i2s_d2].u_int, FUNC_I2S0_IN_D2);
fpioa_set_function(args[ARG_i2s_d3].u_int, FUNC_I2S0_IN_D3);
fpioa_set_function(args[ARG_i2s_ws].u_int, FUNC_I2S0_WS);
fpioa_set_function(args[ARG_i2s_sclk].u_int, FUNC_I2S0_SCLK);
//TODO: optimize Soft SPI
fpioa_set_function(args[ARG_sk9822_dat].u_int, FUNC_GPIOHS0 + SK9822_DAT_GPIONUM);
fpioa_set_function(args[ARG_sk9822_clk].u_int, FUNC_GPIOHS0 + SK9822_CLK_GPIONUM);
MaxiPy中没有这些接口,需要通过CSDK API自己开发,具体的I2S的配置,需要C相关驱动接口细粒度地进行I2S接口配置和相关DMA配置等才能读取这些数据,请问下这个要怎么配置?
        K210的参考手册,哪儿可以下载?
        我也碰到这个问题,打算做声源定位,如何获得原始数据分析。
        

回帖(1)

贾小龙

2025-8-7 18:28:50

要配置K210的I2S接口同时读取麦克风阵列的多个麦克风数据,需遵循以下步骤。这里以I2S_DEVICE_0的4个通道为例(最多支持4个麦克风):


1. 配置GPIO引脚映射


首先,将物理引脚映射到I2S功能(假设使用I2S0):


#include "fpioa.h"

// 配置MIC阵列引脚(示例引脚,根据实际硬件调整)
fpioa_set_function(15, FUNC_I2S0_IN_D0);  // 通道0数据输入
fpioa_set_function(14, FUNC_I2S0_IN_D1);  // 通道1数据输入
fpioa_set_function(13, FUNC_I2S0_IN_D2);  // 通道2数据输入
fpioa_set_function(12, FUNC_I2S0_IN_D3);  // 通道3数据输入
fpioa_set_function(11, FUNC_I2S0_WS);     // 左右时钟(LRCLK)
fpioa_set_function(10, FUNC_I2S0_SCLK);   // 串行时钟(SCLK)

2. 初始化I2S设备


初始化I2S_DEVICE_0为接收模式,并配置所有4个通道:


#include "i2s.h"

// 初始化I2S设备0为接收器
i2s_init(I2S_DEVICE_0, I2S_RECEIVER, 0x00);

// 配置4个通道
i2s_rx_channel_config(I2S_DEVICE_0, I2S_CHANNEL_0,
                     RESOLUTION_16_BIT, SCLK_CYCLES_32,
                     TRIGGER_LEVEL_4, STANDARD_MODE);

i2s_rx_channel_config(I2S_DEVICE_0, I2S_CHANNEL_1,
                     RESOLUTION_16_BIT, SCLK_CYCLES_32,
                     TRIGGER_LEVEL_4, STANDARD_MODE);

i2s_rx_channel_config(I2S_DEVICE_0, I2S_CHANNEL_2,
                     RESOLUTION_16_BIT, SCLK_CYCLES_32,
                     TRIGGER_LEVEL_4, STANDARD_MODE);

i2s_rx_channel_config(I2S_DEVICE_0, I2S_CHANNEL_3,
                     RESOLUTION_16_BIT, SCLK_CYCLES_32,
                     TRIGGER_LEVEL_4, STANDARD_MODE);

// 设置采样率(例如16kHz)
i2s_set_sample_rate(I2S_DEVICE_0, 16000);

3. 设置DMA缓冲区


为每个通道分配独立的DMA缓冲区:


#define BUFFER_SIZE 1024  // 每通道缓冲区大小(单位:样本数)

// 分配缓冲区(每个样本16位)
int16_t *rx_buf[4];
for (int ch = 0; ch < 4; ch++) {
    rx_buf[ch] = (int16_t*)malloc(BUFFER_SIZE * sizeof(int16_t));
    i2s_set_rx_dma(I2S_DEVICE_0, ch, (void*)rx_buf[ch], BUFFER_SIZE, NULL, 0);
}

4. 启动I2S接收


i2s_rx_start(I2S_DEVICE_0);

5. 数据处理


从缓冲区读取多通道数据(示例为通道0-3):


// 等待数据填满(或使用中断)
while (!i2s_rx_dma_done(I2S_DEVICE_0, I2S_CHANNEL_0));

for (int i = 0; i < BUFFER_SIZE; i++) {
    int16_t mic0 = rx_buf[0][i];  // 麦克风0数据
    int16_t mic1 = rx_buf[1][i];  // 麦克风1数据
    int16_t mic2 = rx_buf[2][i];  // 麦克风2数据
    int16_t mic3 = rx_buf[3][i];  // 麦克风3数据

    // 在此处理多通道数据(如波束成形、降噪等)
}

// 重置DMA指针
i2s_clear_rx_dma(I2S_DEVICE_0, I2S_CHANNEL_0);
// (其他通道类似)

关键配置说明




  1. 通道数量

    每个I2S设备(共3个)支持最多4通道。如需超过4个麦克风,需使用第二个设备(如I2S_DEVICE_1)。




  2. SCLK周期

    SCLK_CYCLES_32表示每通道数据为32位。实际音频数据通常为16位,此时高16位为有效数据(低16位可能填充0)。读取后需右移16位:


    int16_t sample = (int16_t)(rx_buf[ch][i] >> 16);  // 提取有效音频



  3. 采样同步

    所有通道共享相同的SCLK和LRCLK,因此数据是同步采样的,适用于麦克风阵列处理。




  4. 数据格式:  



    • STANDARD_MODE:I2S标准模式(数据在LRCLK跳变后延迟1个时钟)。

    • 若麦克风使用PCM模式,改用RIGHT_JUSTIFYING_MODE




  5. 缓冲区管理

    使用DMA中断可避免轮询:


    i2s_set_irq(I2S_DEVICE_0, I2S_RX_INT, on_i2s_rx_done, NULL);



处理更多麦克风


若麦克风数量 > 4,需组合多个I2S设备:


// 第二个设备(I2S_DEVICE_1)
fpioa_set_function(X, FUNC_I2S1_IN_D0);  // 通道4
fpioa_set_function(Y, FUNC_I2S1_WS);
fpioa_set_function(Z, FUNC_I2S1_SCLK);

i2s_init(I2S_DEVICE_1, I2S_RECEIVER, 0x00);
i2s_rx_channel_config(I2S_DEVICE_1, I2S_CHANNEL_0, ...);
// 设置DMA缓冲区并启动

通过此配置,K210可同步读取最多12个麦克风(3设备×4通道),适用于大型麦克风阵列应用。实际接线时需确保所有设备共享时钟信号以保持同步。

举报

更多回帖

发帖
×
20
完善资料,
赚取积分