You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tang Nano 9K FPGA通过I2S采集INMP441音频无响应问题求助

双INMP441 I2S采集无声音响应排查(Tang Nano 9K)

项目背景

  • 基于Tang Nano 9K FPGA + Gowin EDA开发,通过共享I2S总线读取两个INMP441 MEMS麦克风
  • 麦克风区分方式:一个LR引脚接VCC,另一个接GND,以此划分左右声道

时钟配置

使用Nano 9K的27MHz系统时钟生成I2S所需时钟:

  • I2S位时钟(sck):通过分频公式 27/(5*2) 生成约2.7MHz的位时钟。选择该方案是因为Gowin RPLL IP核无法生成48kHz音频所需的3.072MHz频率,而项目仅需约20kHz音频带宽,略低频率可接受。
  • 字选择信号(ws):计算逻辑为 2.7MHz / 66,对应每帧结构:1个dummy bit + 32位左声道 + 1个dummy bit + 32位右声道,最终得到约40.909Hz的ws信号。

问题现象

读取麦克风的采样值看似有效,但LED矩阵(设计为声音越大亮度越高)对拍手等声音无响应,无法通过装置直观确认数据是否随声音变化。

示波器截图

  • T1:I2S信号时序捕获截图1
  • T2:I2S信号时序捕获截图2

核心代码

module main (
    input clk,       // 27 MHz System-Clock
    input rst,       // Reset Button (active-high)
    input sd,        // I2S SD
    output reg sck,  // I2S BCLK (~2.7 MHz)
    output reg ws,   // I2S WS (Word-Select, 32-bit slots)
    output reg tx    // UART TX
);

// -------------------------------------------------
// SCK & WS Generator
// -------------------------------------------------
reg [3:0] frame_counter = 0;
always @(posedge clk or negedge rst) begin
    if(!rst) begin
        frame_counter <= 0; 
        sck <= 0;
    end else begin
        if(frame_counter == 4) begin 
            frame_counter <= 0; 
            sck <= ~sck; 
        end else frame_counter <= frame_counter + 1;
    end
end

reg [5:0] ws_counter = 0;
always @(posedge sck or negedge rst) begin
    if(!rst) begin ws_counter <= 0; ws <= 0; end
    else begin
        if(ws_counter == 32) begin 
            ws_counter <= 0; 
            ws <= ~ws; 
        end else ws_counter <= ws_counter + 1;
    end
end

// -------------------------------------------------
// I2S Capture -> FIFO
// -------------------------------------------------
reg signed [31:0] word = 0;
reg [5:0] bit_counter = 0;
reg ws_p = 0;
reg write_l_pulse = 0;
reg write_r_pulse = 0;
reg signed [15:0] data_input_l =0;
reg signed [15:0] data_input_r =0;
reg write_enable_l = 0;
reg write_enable_r = 0;

always @(posedge sck or negedge rst) begin
    if(!rst) begin
        word <= 0; bit_counter <= 0; ws_p <= 0;
        data_input_l <= 0; data_input_r <= 0;
        write_enable_l <= 0; write_enable_r <= 0;
    end else begin
        ws_p <= ws;

        // WS-Change -> Dummy-Bit -> Counter reset
        if(ws != ws_p) bit_counter <= 0;
        else if(bit_counter < 32) bit_counter <= bit_counter + 1;

        // Bits sammeln
        if(bit_counter >= 1 && bit_counter <= 32)
            word <= {word[30:0], sd};

        // Word fertig -> Write Pulse
        write_l_pulse <= 0; write_r_pulse <= 0;
        if(bit_counter == 32) begin
            if(ws_p == 0) begin
                data_input_l <= word[31:16];
                write_l_pulse <= 1;
                word <= 0;
            end else begin
                data_input_r <= word[31:16];
                write_r_pulse <= 1;
                word <= 0;
            end
        end

        // set Write Enable (1 tact)
        write_enable_l <= write_l_pulse;
        write_enable_r <= write_r_pulse;
    end
end

// -------------------------------------------------
// FIFO instantiation
// -------------------------------------------------
wire signed [15:0] q_l, q_r;
wire empty_l, full_l, empty_r, full_r;
fifo_top fifo_l(
    .Data(data_input_l),
    .Reset(!rst),
    .WrClk(sck),
    .RdClk(clk),
    .WrEn(write_enable_l),
    .RdEn(1'b0),   // reading logic omitted for simplicity
    .Q(q_l),
    .Empty(empty_l),
    .Full(full_l)
);

fifo_top fifo_r(
    .Data(data_input_r),
    .Reset(!rst),
    .WrClk(sck),
    .RdClk(clk),
    .WrEn(write_enable_r),
    .RdEn(1'b0),
    .Q(q_r),
    .Empty(empty_r),
    .Full(full_r)
);

endmodule

请求帮助

恳请有FPGA与I2S经验的人士帮忙排查:

  • 当前I2S时序/WS信号处理逻辑是否正确?
  • 麦克风未对声音做出预期响应的可能原因是什么?

内容的提问来源于stack exchange,提问作者enero

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.11 20:13:11