想了想还是看看这两基础哥们。1 麦克风1.1 总览大概有以下这些。类型换能原理输出信号灵敏度SNR体积成本典型应用MEMS 数字麦PDM硅微振膜电容 片内 ΣΔ 调制PDM 1bit 串行中等60~70dB极小3×4mm 级低TWS 耳机、手机、语音阵列、远场唤醒MEMS 数字麦I2S/TDM硅振膜 片内 ADC 抽取多 bit PCM中等60~70dB小中高高端多麦阵列、车载MEMS 模拟麦硅振膜电容 片内前置放大模拟电压中高60~65dB极小低需要外部 Codec 的低成本方案ECM 驻极体麦驻极体薄膜电容 JFET模拟电压高55~65dB中6mm 圆柱极低玩具、低端音箱、DIY动圈麦线圈切割磁感线模拟电压无源低70~80dB大中高舞台演出、户外 K 歌大振膜电容麦电容振膜 48V 幻象供电模拟电压极高80~100dB大高录音棚、专业配音MEMS 超声麦MEMS 压电 / 电容超声阵列数字 / 模拟——小中高手势识别、测距、探伤1.2 MEMS原理本质是微型电容结构硅片光刻出极薄振膜 固定背板声波推动振膜电容变化芯片内部集成前置放大、Σ-Δ 调制器直接输出 PDM最常见少数型号输出 I2S / 模拟电压。✅ 优点尺寸极小可以做到 1.6×1.0mm 级别、支持 SMT 回流焊、批次一致性很好SNR 离散小做多麦波束成形很关键、功耗低、抗震数字 PDM 版本走数字信号不怕主板射频干扰WiFi / 蓝牙干扰是模拟麦的大坑✅ 接口PDM 是最主流两根线CLKDATA一个时钟1bit 密度调制MCU/DSP 内部做抽取滤波转 PCMI2S 麦直接输出 PCM接口更重、成本更高模拟 MEMS 输出模拟电压后级要 PGAADC和老 ECM 链路一致✅ 典型指标SNR 60~70dB声学过载点 120~135dB SPL分上进声 / 下进声PCB 开孔有全向为主也有差分双振膜 MEMS内置降噪✅ 用法单麦基础拾音2 麦 / 4 麦阵列做波束成形 BF、AEC 回声消除、语音降噪、声源定位、远场语音唤醒小爱 / 天猫TWS 耳机里通常 2~3 颗 MEMS一颗主拾音、一颗环境参考做通话降噪 / AOC 堵耳消除1.3 ECM 驻极体电容麦老一代电容麦原理也是电容薄膜预先注入永久电荷驻极体搭配内置 JFET 阻抗变换输出模拟信号没有内置 ADC一定是模拟输出必须外部 PGAADC 才能转 PCM。✅ 优点成本极低、电路简单❌ 短板体积偏大、不能过高温回流焊、一致性差同批次 SNR 偏差 3~5dB做多麦阵列很难对齐相位、模拟走线极易引入干扰现在新手机 TWS 基本淘汰只在低价音箱、玩具、简易 DIY 里还在用。1.4 动圈麦克风电磁感应振膜带动线圈在磁铁缝隙里运动切割磁感线产生电压无源不需要供电。✅ 优势耐大声压、结实、抗造、低频扎实❌ 短板灵敏度偏低、高频上限一般、体积大不适合小型穿戴设备几乎不用在嵌入式语音采集。1.5 采集例子ECM用的GY-MAX4466 模块咪头是 ECM 驻极体电容麦。输出OUT 引脚是模拟音频信号必须接到 MCU/ADC采样之后才能得到 PCM没有 PDM、没有数字输出。ECM 运放MAX4466 方案老模拟路线。优点结构简单、便宜缺点模拟走线极易引入电源噪声、射频干扰想要 PCM依赖主控 ADC。STM32F4 的内置 ADC 就可以直接接这个 OUT 脚来采集。PDM MEMS把 ΣΔ 做进麦里面直接输出数字 1bit 流抗干扰强适合多麦阵列。模块内部有没有 ΣΔ原始输出得到 PCM 的方式GY-MAX4466❌ 无模拟电压外部 ADC 采样INMP441 PDM 麦✅ 片内 ΣΔPDM 1bit 流软件抽取滤波所以在使用MAX4466需要接到ADC的引脚。我这边是用的树莓派Pico2来完成实验使用的GP16ADC0口。实现思路是麦克风使用 MAX4466 模拟放大模块模拟输出接到 Pico 2 的 GP26也就是 ADC0。固件以 20 kHz 采样每 512 个样本组成一帧通过 USB CDC 串口发给电脑。每帧包含 ZAUD 帧头、样本数、帧序号和 512 个 16 位样本。电脑端可以据此同步数据并统计丢帧。这里树莓派Pico的ADC原始能力是12bit SAR ADC也就是12位精度。在2048的时候表示电压在中间也就是几乎没声音在0或者4095的时候都是声音最大的时候。之后在处理的时候扩展到16位。转换到PCM算法如下raw 0 ~ 4095mid 2048pcm16 (raw - 2048) 4;整体代码如下Pico2和上位机的通信协议字节位置长度内容0–34 字节固定标识ZAUDASCII4–52 字节本包样本数512小端序6–72 字节帧序号小端序无符号循环计数8 起1024 字节512 个 16 位小端序样本采样率是 20 kHz、单声道。每包代表 512 / 20000 25.6 ms 音频。核心代码main.c/* * Pico 2 audio capture: MAX4466 analog output on GP26 / ADC channel 0. * Streams 512-sample, 16-bit little-endian frames over USB CDC ACM. */ #include sample_usbd.h #include hardware/adc.h #include hardware/dma.h #include errno.h #include stdint.h #include string.h #include zephyr/device.h #include zephyr/drivers/adc.h #include zephyr/drivers/uart.h #include zephyr/kernel.h #include zephyr/usb/usbd.h #include zephyr/sys/byteorder.h #define SAMPLE_RATE_HZ 20000U #define ADC_CLOCK_HZ 48000000U #define ADC_DMA_CHANNEL 0U #define FRAME_SAMPLES 512U #define FRAME_HEADER_BYTES 8U #define FRAME_BYTES (FRAME_HEADER_BYTES FRAME_SAMPLES * sizeof(uint16_t)) BUILD_ASSERT(SAMPLE_RATE_HZ 20000U, Update ADC clock divider if sample rate changes); static const struct adc_dt_spec adc_spec ADC_DT_SPEC_GET(DT_NODELABEL(audio_user)); static const struct device *const cdc_dev DEVICE_DT_GET_ONE(zephyr_cdc_acm_uart); static struct usbd_context *usb_ctx; static struct k_sem tx_done; static uint8_t tx_frame[FRAME_BYTES]; static volatile size_t tx_offset; static void usb_message_cb(struct usbd_context *ctx, const struct usbd_msg *msg) { if (!usbd_can_detect_vbus(ctx)) { return; } if (msg-type USBD_MSG_VBUS_READY) { (void)usbd_enable(ctx); } else if (msg-type USBD_MSG_VBUS_REMOVED) { (void)usbd_disable(ctx); } } static int usb_device_start(void) { usb_ctx sample_usbd_init_device(usb_message_cb); if (usb_ctx NULL) { return -ENODEV; } if (!usbd_can_detect_vbus(usb_ctx)) { return usbd_enable(usb_ctx); } return 0; } static void cdc_tx_isr(const struct device *dev, void *user_data) { ARG_UNUSED(user_data); if (!uart_irq_update(dev)) { return; } while (uart_irq_tx_ready(dev)) { if (tx_offset sizeof(tx_frame)) { uart_irq_tx_disable(dev); k_sem_give(tx_done); return; } int written uart_fifo_fill(dev, tx_frame tx_offset, sizeof(tx_frame) - tx_offset); if (written 0) { return; } tx_offset (size_t)written; } } static int adc_channel_start(void) { struct adc_channel_cfg channel_cfg { .gain ADC_GAIN_1, .reference ADC_REF_INTERNAL, .acquisition_time ADC_ACQ_TIME_DEFAULT, .channel_id adc_spec.channel_id, }; return adc_channel_setup(adc_spec.dev, channel_cfg); } static void audio_stream_thread(void *arg1, void *arg2, void *arg3) { ARG_UNUSED(arg1); ARG_UNUSED(arg2); ARG_UNUSED(arg3); uint16_t samples[FRAME_SAMPLES]; uint16_t frame_number 0; dma_channel_config_t dma_cfg dma_channel_get_default_config(ADC_DMA_CHANNEL); channel_config_set_transfer_data_size(dma_cfg, DMA_SIZE_16); channel_config_set_read_increment(dma_cfg, false); channel_config_set_write_increment(dma_cfg, true); channel_config_set_dreq(dma_cfg, DREQ_ADC); /* Pace conversions in hardware and move each result with DMA. */ adc_run(false); /* Zephyrs ADC driver enabled the FIFO IRQ; DMA owns FIFO reads from here. */ adc_irq_set_enabled(false); adc_fifo_setup(true, true, 1, false, false); adc_set_clkdiv(((float)ADC_CLOCK_HZ / SAMPLE_RATE_HZ) - 1.0f); k_sem_init(tx_done, 0, 1); while (1) { /* Clear a possible trailing sample before starting the next exact block. */ adc_run(false); adc_fifo_drain(); dma_channel_configure(ADC_DMA_CHANNEL, dma_cfg, samples, adc_hw-fifo, FRAME_SAMPLES, false); dma_start_channel_mask(BIT(ADC_DMA_CHANNEL)); adc_run(true); dma_channel_wait_for_finish_blocking(ADC_DMA_CHANNEL); adc_run(false); uint32_t dtr 0; if (uart_line_ctrl_get(cdc_dev, UART_LINE_CTRL_DTR, dtr) ! 0 || !dtr) { continue; } memcpy(tx_frame, ZAUD, 4); sys_put_le16(FRAME_SAMPLES, tx_frame 4); sys_put_le16(frame_number, tx_frame 6); for (size_t i 0; i FRAME_SAMPLES; i) { sys_put_le16(samples[i], tx_frame FRAME_HEADER_BYTES i * 2U); } tx_offset 0; uart_irq_tx_enable(cdc_dev); k_sem_take(tx_done, K_FOREVER); } } K_THREAD_STACK_DEFINE(audio_thread_stack, 3072); static struct k_thread audio_thread; int main(void) { if (!device_is_ready(cdc_dev)) { return 0; } if (usb_device_start() ! 0) { return 0; } if (uart_irq_callback_user_data_set(cdc_dev, cdc_tx_isr, NULL) ! 0) { return 0; } if (!device_is_ready(adc_spec.dev) || adc_channel_start() ! 0) { return 0; } k_thread_create(audio_thread, audio_thread_stack, K_THREAD_STACK_SIZEOF(audio_thread_stack), audio_stream_thread, NULL, NULL, NULL, 5, 0, K_NO_WAIT); return 0; }用到的API来自Zephyr 提供uart_line_ctrl_get()查询 CDC 串口的 DTR 状态k_sem_init()/k_sem_take()控制发送同步ARG_UNUSED()是 Zephyr 宏。Pico SDK 提供adc_run()、adc_irq_set_enabled()、adc_fifo_setup()、adc_fifo_drain()、adc_set_clkdiv()操作 RP2350 的 ADCdma_channel_*()、dma_start_channel_mask()配置和控制 DMA。硬件寄存器adc_hw-fifo是 ADC FIFO 寄存器地址。上位机电脑端上位机使用 Python 和 Tkinter 编写可以选择串口、显示实时波形和电平并将采集数据保存为 WAV。当前录音格式为单声道、20 kHz、16 位 PCM。确实可以转换成PCM当时也确实噪音很大。调了几次gain也没有太明显的效果。后面再试试软件优化吧。2 喇叭2.1 总览类型换能原理驱动信号特点频响体积成本典型应用动圈扬声器电动式最通用音圈在磁场里电流驱动音圈带动振膜振动发声模拟交流音频功率信号技术成熟、推力足、失真可控需要功放驱动全频友好低频好跨度很大微型大低音单元低中蓝牙音箱、TWS 耳机单元、电视、汽车喇叭、开发板蜂鸣喇叭压电扬声器压电陶瓷压电材料加电压后形变带动振膜振动模拟交流可高压驱动结构简单、无磁、不怕电磁干扰低频差、偏尖高频为主低频弱很小极低蜂鸣器、便携提示音、穿戴设备提示、简易报警器很少用来放语音音乐静电扬声器ESL高压电场驱动超薄导电振膜极板静电吸力推拉振膜高压音频信号几十上千 V 偏置解析极高、瞬态好需要高压驱动、怕潮湿、低频弱中高频极其顺滑低频难做大薄、大面积很高HiFi 高端音箱消费电子几乎不用平板扬声器平面振膜 / 气动式 AMTAMT褶皱铝膜在磁场里平面振膜整块薄膜驱动模拟功率音频扩散好、高频细腻低频效率偏低中高频优秀偏薄、面积大中高高端头戴耳机、高端 HiFi 音箱、车载顶棚扬声器MEMS 扬声器硅喇叭硅工艺微型振膜静电 / 压电驱动晶圆级封装数字 / 模拟很多自带驱动极小、适合 SMT 贴片、一致性好声压上限有限低频弱中高频为主芯片级极小中正在降价智能眼镜、TWS 副单元、助听器、AR 设备骨传导扬声器骨传导振子振动块机械振动通过颅骨传声不靠空气声波模拟功率信号开放听感、不漏音相对更好有震感、低频弱中低频偏弱中等中高骨传导耳机、安全帽通讯设备气传导扬声器开放式喇叭单元本质还是动圈结构专门优化远场开放辐射模拟功率音频开放声场不堵耳容易漏音全频低频一般中等中开放式耳机、挂耳耳机因为喇叭需要前后震动发声所以给的电流是交流电。不过DAC/CODEC 直接输出的信号电压小、电流能力极弱推不动喇叭输出电流只有mA 甚至 μA 级带载能力非常弱。一般来说喇叭想要正常响、达到额定响度需要几百 mA 级的电流DAC 引脚完全给不出这么大电流。所以需要一个功放来放大电流。功放功放类型简介适配喇叭特点AB 类功放线性模拟放大动圈为主音质好、噪声低、发热大、效率低老方案D 类功放数字功放 / PWM 功放PWM 调制开关放大动圈、压电、MEMS效率高、发热小现在消费音频主流WM8960 内部就是 D 类H 类 / G 类自适应电源轨 D 类改进动圈兼顾效率和大动态高端音箱不过有些有线耳机耳机32Ω、16Ω功率只需要毫瓦级CODEC内置的耳机驱动缓冲电流刚好够用此时就不需要额外外接功放芯片。2.2 Speaker这个是目前某宝上随处可见的一个喇叭功率8W阻抗3Ω。选择功放如下组合后果功放支持≥8Ω功放 8Ω 功率 ≥喇叭功率✅ 理想余量充足功放支持≥8Ω功放 8Ω 功率 喇叭功率⚠️ 能用音量上限不足大声容易失真喇叭阻抗功放允许最小阻抗比如功放最小 4Ω接 2Ω 喇叭❌ 危险过流、烧功放喇叭输入的就是经过放大的交流电。因为是交流电方向一直变化所以接反了影响也不会太大。2.3 播放例子这里给一个MAX98357进行播放的例子。MAX98357 是一款集成 DAC 与 D 类功率放大的音频芯片直接接收 I2S 格式的 PCM 数字音频信号内部完成数模转换后通过 BTL 桥接方式输出差分交流功率信号可直接驱动扬声器无需额外模拟功放它无需 MCLK 主时钟外围电路简洁支持增益配置与单声道混合5V 供电下 8Ω 负载最大输出约 1.8W适合 STM32、ESP32 等嵌入式设备做语音播报、音频播放缺点是功率有限推 3W 8Ω 喇叭无法达到满功率大音量下容易出现削波失真。详细的内容之前写过这里就不再做实验了直接看就行了。总线学习5--I2S_max98357数据手册-CSDN博客
企业数字化 ERP 产品动态
相关推荐
学生常用降 AI 率工具全解析:从检测原理到实操降重,一篇讲清 一、为什么“降 AI 率”成了学生的新刚需
过去几年,学生最怕的是“查重率超标”;而现在,越来越多同学发现,论文提交后系统给出的不只是重复率,还有一项“AI 生成疑似度”。不少高校在毕业论文、课程论文、开题报告中陆… · 2026/11/3 3:32:37
【Docker】镜像相关指令 目录 1、镜像介绍
2、镜像相关指令
2.1 docker pull 指令
2.2 docker push 指令
2.3 docker search 指令
2.4 docker logout 指令
2.5 docker images 指令
2.6 docker image inspect 指令
2.7 docker tag 指令
2.8 docker rmi 指令
2.9 docker save 指令
2.10 docke… · 2026/11/3 0:36:10
推荐一款配音APP之前,我先替你把该踩的坑踩了一遍 做影视解说和小说推文这一年多,配音这件事把我折腾得够呛。一开始图省事用剪映,后来听说讯飞稳、MiniMax情绪好,挨个试了一圈,钱没少花,时间也搭进去不少。到现在手机里还留着好几款,没哪一款能一劳永逸——… · 2026/11/3 14:43:21
EasyU优启通PE维护盘实战指南:制作、启动与核心操作全解析 1. 为什么一个PE维护盘值得单独拿出来聊装系统、修引导、救数据、清病毒,这些活儿但凡干过几次的人都知道,真正决定效率的往往不是你手速多快,而是手边那套PE环境靠不靠谱。EasyU(圈内习惯叫优启通)就是在这个场景下被… · 2026/11/5 16:49:35
Rust原来很简单二:所有权系统 Part 2 核心篇 —— 所有权系统
本篇覆盖 第 6 ~ 10 章:所有权、借用与引用、生命周期、字符串与切片、内存模型。 ⚠️ 这是全书最重要的一篇。 把它吃透,Rust 从此“很简单”;跳过它,你会处处碰壁。请慢下来,动手敲每一段代码。 第 6 章 所有权:Rust 的第一性原理
6… · 2026/11/5 16:26:08
基于Hadoop+Spark的民宿智能推荐系统设计与实现 1. 项目概述:大数据时代的民宿智能推荐这个毕业设计项目融合了当前大数据领域最主流的技术栈,构建了一个完整的民宿推荐系统解决方案。作为一名长期从事大数据系统开发的工程师,我认为这个选题非常贴合实际应用场景——随着旅游业的复苏和共享… · 2026/11/5 14:59:25
ADS122U04IPWR+STM32F427ZI工业级温度测量信号链设计 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 14:10:41
UART接口24位ADC搭配RS485,解决远距离温度监控难题 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 14:10:41
UART接口24位ADC搭配PIC18F46K22的RTD与热电偶测温实践 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 14:10:41
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:27:59
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:28:03
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:28:07
多智能体协作系统架构设计与实践优化 1. 多智能体协作系统的时代背景2017年Transformer架构的诞生彻底改变了人工智能的发展轨迹。当行业还沉浸在单一大模型带来的性能突破时,Anthropic的研究团队已经将目光投向了更前沿的领域——如何让多个智能体通过协作产生超越单体能力的系统智能。这就像交响乐团中… · 2026/11/5 0:00:39
大模型系统性入门实战指南:从原理到部署微调的全链路路线 提到大模型的系统性入门,我先说个结论:这事真不难,难的是资料太散、路线太多,今天这个框架明天那个工具,新人很容易在“收藏夹吃灰”和“教程看到一半放弃”之间反复横跳。市面上关于大模型的内容少说有几十万篇&#… · 2026/11/5 0:00:39
鸿蒙文件系统沙箱机制解析与开发实践 1. 鸿蒙文件系统沙箱机制深度解析作为一名从Android转向鸿蒙开发的工程师,我深刻体会到文件系统访问是迁移过程中最先遇到的"拦路虎"。在Android上运行良好的文件读写代码,在鸿蒙真机环境却频频出现文件写入后神秘消失或直接抛出权限拒绝错误的… · 2026/11/5 0:00:39
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:27:59
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:28:03
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:28:07