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
相关产品推荐
相关产品推荐

