Funpack5-3 - 基于 MAX32690EVKIT 的音频频谱分析与实时显示
该项目使用了MAX32690EVKIT,实现了实时音频频谱分析的设计,它的主要功能为:通过 I2S/PCM 和 DMA 持续获取音频,使用 FFT 计算频谱并提取主要频率,实时显示时域波形和频域频谱。
标签
嵌入式系统
Funpack活动
显示
ADC
开发板
接口
USB
ixbwer
更新2026-08-12
31


基于 MAX32690EVKIT 的音频频谱分析与实时显示

摘要

本项目完成了 MAX32690EVKIT 上的实时音频频谱分析链路。板载 MAX9867 通过 I2C2 完成工作模式配置,并以 48 kHz、双声道、24 bit 左对齐格式向 MAX32690 的 I2S 接口输出数字音频。Cortex-M4F 使用两块 512 字的乒乓 DMA 缓冲区连续接收数据,在主循环中完成左声道抽取、去直流、RMS 计算、Hann 加窗、256 点实数 FFT、幅度谱和主频插值;随后将 128 点波形或频谱封装为 141 B 显示帧,经 SEMA 邮箱交给片上 RISC-V 核。RISC-V 负责 128×128 ST7735 TFT 的差分刷新,SW2 可在时域和频域界面之间切换。设计刷新率分别为 46.875 fps 和 23.4375 fps,均高于题目要求的 10 fps。

1. 项目介绍

1.1 任务目标

任务要求利用 MAX32690EVKIT 的音频接口完成声音采集、频谱分析和屏幕显示。核心验收点包括:通过 I2C 初始化 MAX9867,通过 I2S/PCM 和 DMA 或中断持续获取音频,使用 FFT 计算频谱并提取主要频率,最后以不低于 10 fps 的速度显示时域波形和频域频谱。

2. 硬件平台介绍

2.1 MAX32690EVKIT

MAX32690EVKIT 是本项目的载体,板上集成 MAX32690、MAX9867 立体声音频编解码器、1.45 英寸 128×128 彩色 TFT、3.5 mm Line-In/Line-Out、USB 供电与 UART、SWD 接口以及通用按键。评估板资料说明,音频编解码器通过 I2C 和 I2S/PCM 与 MCU 相连;TFT 由于硬件引脚分配原因使用 GPIO 模拟 SPI 时序。

2.2 使用到的硬件

硬件

本项目中的作用

关键参数/连接

MAX32690

主控制器与双核计算平台

120 MHz Cortex-M4F;RISC-V RV32 协处理器;I2S、DMA、I2C、SEMA

MAX9867

模拟音频 ADC 与数字音频接口

I2C 地址 0x18;MCLK 12.288 MHz;ADC 支持 8–48 kHz

J5 Line-In

接入 PC/手机耳机输出或经过前置放大的麦克风

3.5 mm 立体声输入;工程分析左声道

CFAF128128B1 类 TFT

显示波形、频谱和主频

128×128;ST7735 控制器;GPIO 模拟 SPI

SW2

时域/频域显示模式切换

P4.0,按下为低;软件采用边沿检测

JP9 / JP10

将 I2C2C 路由到 MAX9867

均置于 2–3:JP9=SDA,JP10=SCL

CN1/CN2 与调试器

供电、下载、调试和串口日志

OpenOCD/CMSIS-DAP;UART 115200-8-N-1

接线要点: 音源输出接 J5,先把音量调低再逐步增加;JP9、JP10 必须切到 2–3,才能把 I2C2C 的 SDA/SCL 接到编解码器。由于 JP9/JP10 的另一档用于 UART2 CTS/RTS,调试串口只使用 TX/RX 即可。

3. 总体方案框图与设计思路



图 1:系统总体方案框图

3.1 数据链路

  1. MAX9867 将 J5 的模拟立体声输入转换为 48 kHz、24 bit 数字音频,并提供外部 SCK/WS 给 I2S 从机接口。
  2. I2S RX DMA 每次写入 512 个 32 位字,即 256 组左右声道采样,单块持续 5.333 ms。
  3. DMA 回调只完成缓冲区状态切换和下一次 DMA 启动;FFT 不在中断中执行。
  4. M4 主循环每 4 块生成一次时域帧,每 8 块执行一次 FFT;显示包通过 SEMA 邮箱非阻塞发送。
  5. RISC-V 核解析显示包,以差分点或垂直色带更新 TFT,避免整屏清除造成闪烁和低帧率。

3.2 关键设计参数

参数

取值

设计意义

采样率

48 kHz

覆盖 0–24 kHz;MAX9867 支持;与 12.288 MHz MCLK 匹配

DMA 帧

256 stereo samples

5.333 ms/帧;兼顾实时性和 FFT 点数

DMA 缓冲

2 × 512 × 32 bit

总计 4096 B;采集与处理交替进行

FFT

256 点 real FFT

128 个正频率点;分辨率 187.5 Hz/bin

幅度显示

相对峰值 0 至 −60 dB

弱分量仍可见,避免线性谱被主峰压扁

跨核帧

141 B / 256 B mailbox

带 magic/version/sequence,静态断言保证尺寸

显示调度

4 块 / 8 块

时域 46.875 fps;频域 23.4375 fps


图 2:DMA 块与显示/FFT 调度关系

4. 调试软件与工程组织

4.1 开发与调试工具

软件/组件

用途

本工程使用方式

MSDK

芯片启动、外设驱动、板级支持与构建系统

TARGET=MAX32690BOARD=EvKit_V1

GNU Arm Embedded 10.3

编译 Cortex-M4F 应用

hard-float,-O2,生成 i2s_dma_app.elf

xPack RISC-V GCC 12.2

编译 RV32 显示固件

生成 riscv.bin 并嵌入 M4 镜像

CMSIS-DSP 1.16.2

实数 FFT 与数学运算

arm_rfft_fast_init_f32 / arm_rfft_fast_f32

GNU Make + MSYS2

按阶段编译与清理

STAGE=capture/dsp/lcd/appRUN_TESTS=1

OpenOCD / CMSIS-DAP

下载、复位和断点调试

make flash.openocd;多探针可指定 ADAPTER_SN

串口终端

查看状态、主频、RMS、overrun 和显示统计

UART2,115200-8-N-1

Unity + Host GCC

纯软件单元测试

23 项测试,0 失败

4.2 四阶段调试法

工程将复杂链路拆成四个可单独构建的阶段,从输入到输出逐级隔离问题:

阶段

验证范围

主要观察量

capture

MAX9867 + I2S RX + DMA

completed、overruns、dma_error、running/paused

dsp

采集 + 左声道 + FFT

peak_hz、RMS、静音判定、1.5/3/6/12 kHz

lcd

双核邮箱 + TFT 渲染

合成波形/频谱、SW2 切换、残影与卡顿

app

完整音频到显示链路

频率随输入变化、display sent/dropped/rendered

关键调试命令如下:

make STAGE=capture clean && make STAGE=capture flash.openocd
make STAGE=dsp clean && make STAGE=dsp flash.openocd
make STAGE=lcd clean && make STAGE=lcd flash.openocd
make STAGE=app clean && make STAGE=app flash.openocd
make RUN_TESTS=1 clean && make RUN_TESTS=1 flash.openocd

5. 软件流程图及关键代码


图 3:完整软件流程图

5.1 MAX9867 与 I2S 初始化

初始化时先将 I2C2 设置为 100 kHz,再调用板级 MAX9867 驱动完成基础配置。工程随后写入 48 kHz 的 NI 参数并回读校验,启用录音路径,设置 ADC 电平为 −12 dB、Line-In 增益为 +10 dB。I2S 采用 24 bit 有效数据、32 bit 字槽、左对齐、MSB 优先、双声道,SCK 与 WS 由 MAX9867 提供。

MXC_I2C_Init(MXC_I2C2, 1, 0);
MXC_I2C_SetFrequency(MXC_I2C2, 100000U);
max9867_init(MXC_I2C2, 12288000U, 1);
codec_set_48khz();
max9867_enable_record(1);
max9867_adc_level(-12, -12);
max9867_linein_gain(10, 10);

request.sampleSize = MXC_I2S_SAMPLESIZE_TWENTYFOUR;
request.adjust = MXC_I2S_ADJUST_LEFT;
request.channelMode = MXC_I2S_EXTERNAL_SCK_EXTERNAL_WS;
request.stereoMode = MXC_I2S_STEREO;

5.2 DMA 乒乓缓冲与中断最小化

缓冲区具有 FREECAPTURINGREADYPROCESSING 四种状态。DMA 完成后,中断回调把当前槽置为 READY,并立即寻找 FREE 槽启动下一次接收;主循环只获取最早完成的 READY 帧。若两个槽均被占用,采集暂时暂停并记录 overrun,待 PROCESSING 槽释放后自动恢复。

static void dma_callback(int channel, int result)
{
uint8_t next_slot = AUDIO_BUFFER_SLOT_NONE;
uint8_t completed_slot = dma_slot;

MXC_DMA_ReleaseChannel(dma_channel);
running = 0;
if (result != E_NO_ERROR) {
dma_error = result;
return;
}

audio_buffer_pool_complete(&pool, completed_slot, &next_slot);
if (next_slot != AUDIO_BUFFER_SLOT_NONE) {
dma_error = start_dma(next_slot);
}
}

5.3 FFT 处理链路

每个 DMA 帧包含左右声道交织的 32 位字。算法选择偶数索引的左声道,将有符号样本归一化到约 [−1, 1),求均值并去除直流。RMS 在未加窗的中心化信号上计算;FFT 输入乘以预计算的 Hann 窗,从而降低非整周期信号造成的谱泄漏。

for (i = 0; i < 256; i++) {
int32_t sample = (int32_t)i2s_words[2U * i];
fft_input[i] = (float)sample / 2147483648.0f;
mean += fft_input[i];
}

for (i = 0; i < 256; i++) {
float centered = fft_input[i] - mean / 256.0f;
energy += centered * centered;
fft_input[i] = centered * hann_window[i];
}

arm_rfft_fast_f32(&rfft, fft_input, fft_output, 0);

幅度谱使用 4/N 的比例修正,同时补偿单边谱和 Hann 窗约 0.5 的相干增益。峰值搜索忽略 DC 和 50 Hz 以下频率;对最大 bin 及左右相邻 bin 的功率做抛物线插值,估计偏移限制在 ±0.5 bin,从而在 187.5 Hz 的原始分辨率基础上改善单音频率读数。

5.4 显示帧与双核渲染

时域模式从 256 个左声道采样中隔点提取 128 点并自动缩放;频域模式将 128 个正频率点转换为相对最大值的 −60 至 0 dB。显示包由 magic、version、sequence、frame_count、peak_hz、level 和 128 B plot 组成,总长 141 B,能够装入 256 B SEMA 邮箱。

if (mode == DISPLAY_MODE_TIME && ++waveform_blocks >= 4) {
action.send_display = 1;
action.extract_waveform = !action.run_fft;
}

if (++fft_blocks >= 8) {
action.run_fft = 1;
if (mode == DISPLAY_MODE_FREQUENCY) {
action.send_display = 1;
}
}

display_packet_build(&packet, sequence++, processed, mode, &analysis);
display_bridge_try_send(&packet); /* mailbox full: drop only this frame */

RISC-V 不做整屏重绘:时域只擦除旧点、写入新点;频域只更新柱高变化的垂直区间,并设置 2 像素滞回、1024 单位的单帧工作预算。频谱标题约每 96 帧更新一次,使峰值文字刷新不会持续占用 GPIO 模拟 SPI 带宽。

6. 功能展示与验证

6.1 屏幕显示效果

图 4:TIME/FREQ 界面

上图左侧为时域模式:黑色背景、顶部 TIME 标题和青色波形;右侧为频域模式:顶部显示插值后的主频,图区以绿色填充 128 列频谱。按下并释放 SW2 可在两种模式间切换,软件采用边沿检测,因此持续按住不会重复切换。

7. 项目难题及解决方法

7.1 I2C 路由与串口复用冲突

难点: JP9/JP10 默认可把 P1.7/P1.8 接到 UART2 CTS/RTS,而 MAX9867 需要同一组引脚作为 I2C2C SDA/SCL。若跳帽位置错误,I2C 事务会超时,但串口 TX/RX 仍可能正常,容易误判为编解码器驱动问题。

解决: 将 JP9、JP10 都置于 2–3,并在初始化后回读 0x06/0x07 时钟寄存器,确认总线和配置均有效。

7.2 24 bit I2S 数据的符号与声道定位

难点: DMA 以 32 位字搬运 24 bit 左对齐数据,且左右声道交织。如果直接按 int16_t 读取或声道步长错误,波形会削顶、频谱出现镜像或主频错误。

解决: 先把 32 位字强制转换为 int32_t 保留符号,再按 i2s_words[2*i] 取左声道;波形显示使用 sample >> 16,FFT 使用除以 2³¹ 的浮点归一化。

7.3 DMA 与主循环的竞态

难点: 若 DMA 在主循环处理期间覆盖同一缓冲区,FFT 会读到撕裂数据;若回调中直接运行 FFT,又会拉长中断并导致下一帧丢失。

解决: 显式维护四态缓冲区所有权,中断只推进状态机,获取/释放临界区短暂关中断;两个槽都忙时暂停而不是覆盖,并通过 overrun 计数暴露性能问题。

7.4 频谱泄漏、噪声误报与频率分辨率

难点: 256 点、48 kHz 的原始 bin 间隔为 187.5 Hz,非整周期单音会泄漏到相邻频点;Line-In 底噪还可能被识别为主峰。

解决: 去除帧均值、使用 Hann 窗、设置 RMS 与 peak_power 双门限、忽略 50 Hz 以下频点,并用三点抛物线插值改善单峰读数。

7.5 GPIO 模拟 SPI 的刷新瓶颈

难点: 评估板 TFT 没有接到硬件 SPI,整屏 128×128 像素以 GPIO bit-bang 刷新会占用大量 CPU,容易低于 10 fps。

解决: 把显示从 M4 分离到 RISC-V;时域仅更新改变的像素,频域仅更新柱高差值;加入 2 像素滞回、单帧工作预算和跨帧扫描起点,并降低频率标题更新速率。这样显示负载被限制,音频 DMA 和 FFT 不被阻塞。

7.6 双核镜像的一致性

难点: M4 启动时嵌入 riscv.bin,如果两个核心使用不同输出目录或旧文件未重建,M4 可能悄悄装载过期的 RISC-V 固件。

解决: project.mk 强制 M4 与 RISC-V 使用工程本地 build/buildrv,并让 lcd/app 阶段递归构建 RISC-V 镜像后再链接 M4 应用。

8. 心得体会

本项目最重要的收获,是认识到“FFT 算法能运行”只占实时音频系统的一小部分。真正决定体验的,是采集时钟、DMA 所有权、中断长度、跨核通信、显示带宽和错误退化策略能否形成稳定闭环。采用四阶段调试后,每个阶段都有单独的输入、输出和验收指标,比一次性联调整条链路更容易定位问题。

在信号处理方面,Hann 窗、直流移除、噪声门限和峰值插值虽然代码量不大,却显著改善了频谱的可读性。在系统设计方面,将 TFT 渲染交给 RISC-V,并让显示邮箱满时只丢当前帧,使音频采集保持最高优先级;这种“数据采集不可阻塞、显示允许降级”的取舍同样适用于示波器、振动监测和其他边缘信号分析项目。

最后,项目也提醒我必须区分理论指标、软件测试和实物测量。46.875 fps 与 23.4375 fps 是由调度参数推导出的设计值;23/23 是可复现的软件测试结果;而现场 60 秒的丢帧率、overrun 和屏幕照片应由实物实验给出。清楚标注证据来源,能让项目报告更可信,也便于后续复现和改进。

9. 总结与可扩展方向

工程已经实现从 MAX9867 音频输入、I2S DMA 连续采集、CMSIS-DSP FFT、主频与幅度提取,到双核彩屏显示的完整闭环。当前使用 48 kHz/256 点配置,在保持低延迟的同时提供 187.5 Hz 原始分辨率,并通过插值改善单音读数;双模式刷新率均超过任务要求。

后续可从以下方向扩展:

  • 将采样率切换为 16 kHz,并采用 512 或 1024 点 FFT,以提高语音频段的频率分辨率。
  • 加入指数平滑、峰值保持和对数频率刻度,进一步提升显示稳定性和视觉可读性。
  • 实现麦克风偏置/前置放大方案,或使用 MAX9867 的差分麦克风输入,形成真正的声学采集终端。
  • 把 UART 统计保存为 CSV,自动计算 60 秒丢帧率、overrun 和主频误差,形成可重复的硬件验收报告。
  • 增加频带能量、基频跟踪或音符识别,在现有 FFT 管线之上扩展声音分析功能。

参考资料

  1. 硬禾学堂 FunPack 5-3 活动页面
  2. Analog Devices, MAX32690 Evaluation Kit Data Sheet
  3. Analog Devices, MAX32690 Datasheet and Product Information
  4. Analog Devices, MAX9867 Ultra-Low Power Stereo Audio Codec
  5. Analog Devices MSDK


附件下载
sourcecode.zip
团队介绍
个人
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号