Grove录音模块工程化应用:从ISD1820P原理到抗干扰设计实战
1. 从“能录”到“录好”Grove录音模块的工程化思考在嵌入式项目里给设备加上“录音”功能听起来是个挺酷的点子。你可能想做个会说话的智能门铃、一个能记录环境声音的监测节点或者一个简单的语音留言机。市面上能实现录音的芯片和模块不少但当你真正上手时往往会发现从“电路能出声”到“录出来的声音清晰可用”中间隔着一道不小的鸿沟。噪音、失真、存储、触发逻辑……每一个环节都可能成为项目卡壳的痛点。Grove生态里的录音模块尤其是基于ISD1820P这类芯片的版本就是为解决这个“从零到一”的快速验证而生的。它把麦克风、功放、存储芯片以及最关键的录音/放音控制逻辑全部集成到了一块比拇指稍大的板子上通过标准的4针Grove接口与你的主控板比如Arduino、Seeeduino连接。你不需要去研究音频编解码算法不用头疼于模拟电路的前级放大和滤波设计甚至免去了寻找合适存储介质的麻烦。理论上接上电源和信号线调用几个简单的数字电平控制你的项目就拥有了“开口说话”的能力。然而我以多年的嵌入式开发经验告诉你如果你止步于官方示例代码的“Hello World”那么在实际项目中这个模块很可能给你带来的是“含混不清的抱怨”而非“清晰明确的指令”。它的便利性隐藏了音频质量、电源管理、控制时序等深层细节。这篇文章我们就抛开简单的接线演示深入Grove录音模块以ISD1820P方案为例的工程应用核心。我会带你理解它如何工作更重要的是分享如何通过一系列外围设计和软件策略让它从一块“能用的模块”变成项目中“可靠好用的语音单元”。无论你是想制作一个展览讲解器还是一个需要语音反馈的工业控制器这里的经验都能帮你避开我当年踩过的那些坑。2. 模块核心ISD1820P芯片的工作原理与能力边界要驾驭一个模块首先得理解它的心脏。Grove录音模块常见的核心是ISD1820P这是一款单芯片、免维护的语音录放电路。它的设计哲学是“简单直接”但这份简单背后有明确的规格限制理解这些限制是做出好设计的前提。2.1 存储机制模拟存储与固定时长ISD1820P最特别的一点在于其存储介质。它不像现代数字录音那样使用Flash或SD卡存储数字音频文件而是采用了一种叫做“多级模拟存储”的技术直接将模拟音频信号以电荷的形式存储在芯片内部的EEPROM存储单元阵列中。播放时再将电荷信号还原成模拟电压输出。这种技术带来了两个最直接的特征固定录音时长芯片的存储空间是物理固定的因此录音时长是一个硬性指标。常见的ISD1820P有8秒、10秒、20秒等不同版本具体看模块型号。这意味着你必须在项目规划阶段就确定好每段语音的最大长度超出的部分会被截断。例如如果你的模块是10秒版那么设计提示音就不能超过10秒。非文件系统录音数据不是以“.wav”或“.mp3”文件的形式存在。它更像一卷老式的磁带录音操作就是从当前“磁头”位置开始抹除旧内容并录制新内容放音则是从指定地址开始播放。你无法通过电脑直接读取出一个标准音频文件。2.2 管脚控制逻辑本质是一个状态机模块虽然通过Grove接口只引出四根线VCC, GND, D1, D2但其底层的ISD1820P芯片提供了丰富的控制管脚。模块设计者已经帮你做好了部分电路连接和逻辑映射。通常Grove接口的D1和D2会被连接到芯片的某个控制模式上。常见的映射有一键模式D1接REC录音键按下为高电平时开始录音松开停止D2接PLAYE边沿触发放音给一个高电平脉冲如从LOW拉高到HIGH再拉回LOW即播放整段录音。独立控制模式D1接RECD2接PLAYL电平触发放音当PLAYL保持高电平时持续播放直到变为低电平或播放完毕。注意具体映射方式取决于模块版本务必查阅你所购买模块的说明书或原理图。用错触发模式会导致控制失灵。芯片的工作完全由这些管脚的电平状态控制内部是一个清晰的状态机。例如在录音时REC管脚为高PLAYX管脚必须为低在放音时则相反。同时芯片提供了BUSY管脚通常通过模块上的LED指示在录音或放音期间输出高电平告知主控“我正在忙”。理解这个状态机至关重要。一个常见的错误是主控单片机在发出播放指令后立即试图进行下一次录音或播放而此时BUSY信号仍为高导致操作冲突产生刺耳的噪音或操作无效。正确的做法是在触发播放后持续检测BUSY管脚或观察模块LED直到其变为低电平再进行下一步操作。2.3 电气特性与音频指标这是影响音质的核心部分却最容易被忽略。供电电压ISD1820P典型工作电压为3V模块通过Grove接口通常接受3.3V或5V输入内部可能有稳压电路。但电源质量直接影响录音质量。如果使用开发板的5V引脚供电而该电源线上同时有电机、继电器等大电流设备工作引入的电源纹波会被麦克风放大电路拾取录下“嗡嗡”的交流声或“咔咔”的噪声。麦克风与音频输入模块板载驻极体麦克风MIC和一个音频输入接口AUX IN。麦克风灵敏度是固定的且通常没有自动增益控制AGC。这意味着在嘈杂环境中背景噪音会和你的声音一起被清晰地录进去而在安静环境中如果说话距离稍远录下的声音又会太小。AUX IN可以接入外部音源如手机但输入电平需要匹配过高会导致削顶失真声音破掉。输出与功放音频输出经过一个小型功放芯片如LM386驱动一个8Ω 0.5W的小喇叭。这个功放增益可能通过板载跳线或电阻可调。增益过高即使很小的背景噪音也会被放大得很大同时可能引发自激振荡啸叫。能力边界总结ISD1820P模块是一个低成本、易集成、时长固定、音质受外围电路影响大的解决方案。它适合用于对音质要求不高、语音内容固定且简短的场合如提示音、告警声、简短的语音标签。如果你需要高保真音乐播放、长时间录音或复杂的语音编辑管理则需要寻找数字音频编解码芯片外部存储的方案。3. 超越示例代码稳定可靠的软硬件集成设计官方示例代码通常只演示最基础的“录放”功能但真实项目需要稳定性和鲁棒性。下面我们从硬件和软件两方面拆解如何搭建一个更可靠的系统。3.1 硬件优化为声音创造一个“安静”的环境独立供电与滤波问题与数字电路共用电源特别是当主控MCU频繁切换IO、驱动外设时电源网络上会产生高频噪声。方案如果条件允许为录音模块提供独立的线性稳压电源如AMS1117-3.3。如果必须共用电源务必在模块的VCC和GND引脚之间就近焊接一个100μF的电解电容滤低频纹波并联一个0.1μF的陶瓷电容滤高频噪声。这是成本最低、效果最显著的音质提升方法。信号地与电源地分离问题大电流的负载如电机在地线上产生的压降会耦合进敏感的音频放大电路。方案在PCB布局或接线时尽量让音频模块的接地路径“干净”。理想情况下所有地线最终单点连接到电源地。在万用板上搭建系统时注意地线的走线避免形成环路。麦克风与环境噪声处理问题板载麦克风会拾取环境所有声音。方案物理隔离为模块设计一个外壳并在麦克风开孔处使用柔软的防震海绵或硅胶套减少结构振动传导的噪声。指向性如果可能使用外接的指向性麦克风通过AUX IN接入能有效抑制侧面和背后的环境噪声。输入电平匹配如果使用AUX IN先用电脑和音频编辑软件生成一段标准正弦波测试信号如1kHz, -20dB播放并录制观察录制后播放的声音是否失真。通过调整音源输出音量或模块上的输入分压电阻如果有找到不失真的最大输入电平。3.2 软件策略精准控制与状态管理软件层面我们的目标是实现“精准触发”和“避免冲突”。基于BUSY信号的互锁逻辑 这是确保操作顺序正确的关键。绝不能假设操作“瞬间完成”。// 假设 REC_PIN D1, PLAY_PIN D2, BUSY_PIN D3 (如果引出) const int REC_PIN 4; const int PLAY_PIN 5; const int BUSY_PIN 6; // 或通过模块LED状态间接判断 void playAudio() { // 1. 检查是否正忙 if(digitalRead(BUSY_PIN) HIGH) { Serial.println(Module busy, wait...); return; // 或加入等待队列 } // 2. 确保录音引脚为低状态机要求 digitalWrite(REC_PIN, LOW); delay(10); // 小延时确保电平稳定 // 3. 发送播放脉冲假设为边沿触发PE digitalWrite(PLAY_PIN, HIGH); delay(50); // 脉冲宽度通常10ms以上即可参考芯片手册 digitalWrite(PLAY_PIN, LOW); // 4. 等待播放完成 while(digitalRead(BUSY_PIN) HIGH) { // 可以在这里添加超时检测避免死循环 delay(10); } Serial.println(Play finished.); } void recordAudio(int durationMs) { if(digitalRead(BUSY_PIN) HIGH) return; digitalWrite(PLAY_PIN, LOW); // 确保播放引脚为低 delay(10); digitalWrite(REC_PIN, HIGH); delay(durationMs); // 阻塞式录音简单示例 digitalWrite(REC_PIN, LOW); while(digitalRead(BUSY_PIN) HIGH); // 等待录音处理完成 }非阻塞式状态管理 上述recordAudio函数中的delay(durationMs)会阻塞整个程序。对于需要同时响应其他事件如按键、传感器的系统这不可接受。更好的方法是使用状态机非阻塞定时。enum AudioState { IDLE, RECORDING, PLAYING }; AudioState currentState IDLE; unsigned long recordStartTime 0; const unsigned long RECORD_DURATION 5000; // 录制5秒 void loop() { switch(currentState) { case IDLE: if(triggerRecordCondition) { startRecording(); currentState RECORDING; recordStartTime millis(); } if(triggerPlayCondition) { startPlaying(); currentState PLAYING; } break; case RECORDING: if(millis() - recordStartTime RECORD_DURATION) { stopRecording(); currentState IDLE; } // 此处可以处理其他任务如读取传感器 readSensor(); break; case PLAYING: if(digitalRead(BUSY_PIN) LOW) { // 播放结束 currentState IDLE; } break; } // 主循环其他任务... }分段录音与播放管理 ISD1820P支持通过地址线进行分段但大多数Grove模块未引出这些地址线因此通常整片存储区域作为一个片段使用。如果你的模块支持分段查看是否有A0-A7的跳线你可以规划不同的地址段存储不同的语音如“欢迎光临”存一段“谢谢惠顾”存另一段通过控制地址线引脚的电平组合来选择播放哪一段。这需要更复杂的电路和软件控制但实现了语音内容的可管理性。4. 典型应用场景与实战调试技巧理解了原理和优化方法后我们来看几个具体场景并分享调试中的关键技巧。4.1 场景一博物馆自助讲解器需求游客走到展品前按下按钮播放一段预先录制的讲解约1分钟。要求音质清晰触发可靠。挑战环境相对安静但可能有回声讲解时间长远超单模块时长。方案硬件使用多个录音模块如6个10秒模块串联使用。每个模块录制10秒内容。主控如Seeeduino XIAO管理一个模块阵列。控制逻辑按下按钮后主控按顺序触发第一个模块播放在其BUSY信号变低后立即触发第二个模块如此接力实现无缝或略有间隔的连续播放。这要求主控有足够的IO口来控制每个模块的PLAY和BUSY。音质优化为整个阵列设计一个共用的、滤波良好的3.3V线性稳压电源。将所有模块的喇叭并联注意阻抗匹配可能需要计算或者使用一个外部功放驱动一个更大的喇叭。调试技巧同步问题模块间切换的间隔可能导致语音中断。可以在每段录音的结尾和开头预留0.5秒的静音软件上在检测到前一个模块BUSY变低后延迟100ms再触发下一个模块让功放和喇叭的余振平息。音量一致性分别录制每个模块时使用相同的音源、相同的音量、相同的录音距离并用声压计或手机分贝计APP辅助校准确保各段播放音量一致。4.2 场景二工业设备状态语音提示需求设备启动、运行、报警时播放不同的简短提示音“设备就绪”、“运行中”、“温度过高”。挑战工业环境电磁干扰强噪音大要求高可靠性不能误触发。方案硬件使用单模块分段功能如果模块支持。将不同的提示音录在芯片的不同地址段。通过主控的多个IO口控制地址线选段。这样成本最低控制也相对简单。抗干扰设计电源隔离为录音模块使用独立的DC-DC隔离电源模块彻底切断来自主设备电源的干扰路径。信号隔离主控与录音模块之间的控制信号REC,PLAY,BUSY使用光耦如PC817进行隔离。即使主控侧地线有大幅波动也不会影响到音频侧。屏蔽与接地将录音模块置于金属屏蔽盒内屏蔽盒良好接地接机柜大地。软件防抖对触发播放的输入信号如来自PLC的干接点进行软件防抖处理避免因接触抖动导致语音重复播放。4.3 通用调试技巧与故障排查无论什么场景以下调试流程都很有帮助电源是第一嫌疑人任何莫名其妙的噪音、音量小、失真问题首先用示波器查看模块供电引脚VCC和GND之间的波形。如果看到明显的毛刺或纹波大于50mVpp加强滤波电容或改用线性稳压电源。信号注入法定位噪声源断开麦克风将AUX IN对地短接录音然后播放。如果此时噪音消失说明噪音来自麦克风及前级放大电路可能是环境噪声或电源噪声耦合。如果短接后仍有噪音则噪音可能来自功放部分或电源。尝试降低功放增益如果可调或检查功放芯片的电源和接地。控制时序验证使用逻辑分析仪或示波器同时抓取REC、PLAY、BUSY三个引脚的电平变化。对照ISD1820P数据手册的时序图检查你的控制信号是否满足t建立时间、t保持时间等要求。不满足时序可能导致操作失败或芯片进入不可预测状态。录音电平校准进行试录音用正常说话音量在典型距离如30cm讲话。播放录音主观评价。如果声音小且清澈可以提高音源音量或靠近麦克风。如果声音大但破音失真则降低音源音量或远离麦克风。最佳实践找到刚好不出现破音的最大音量然后在此基础上降低3-6dB进行正式录音这样可以预留一定的“动态余量”避免突然的大音量冲击导致失真。5. 进阶考量当Grove模块不再满足需求时Grove录音模块是快速原型的神器但当你的项目需要更长的录音时间、更好的音质、更复杂的语音管理如存储多段、按文件名播放、或需要通过网络传输音频数据时你就需要考虑更专业的方案了。数字音频方案核心采用数字音频编解码芯片如VS1053B可录放MP3/WMA等格式、ISD1760数字存储但接口更现代或STM32等MCU自带的I2S接口音频编解码器。存储搭配SPI Flash、SD/TF卡存储容量从几兆字节到数十GB录音时长从几分钟到数百小时。优点音质好采样率、位深可调存储管理灵活文件系统功能强大可压缩、可解码多种格式。缺点电路和软件复杂度指数级上升需要处理文件系统、编解码数据流、可能还需要嵌入式操作系统。语音合成方案如果你不需要录制真人语音而是播放固定的文本内容那么语音合成TTS模块是更好的选择。如SYN6288、XFS5152等芯片可以通过UART接收文本直接合成语音播放。内容可动态生成无需预先录制存储空间用于字库而非音频数据。无线音频流对于需要实时传输音频的应用如无线麦克风、婴儿监控可以考虑蓝牙音频模块如BK8000L或Wi-Fi音频模块。它们直接将模拟音频信号数字化并通过无线协议传输完全绕开了本地存储和播放的难题。迁移建议如果你的项目始于Grove模块的原型验证并且验证了语音功能的必要性和基本逻辑但在音质、时长或管理上遇到瓶颈那么下一步就应该根据新的需求清单最长录音时间、音质指标、控制接口、成本预算去寻找对应的数字音频芯片或模块。此时你在调试Grove模块过程中积累的关于电源、噪声、控制时序的经验将同样适用于更复杂的系统。围绕Grove录音模块的开发远不止接上线、写两行代码那么简单。它涉及模拟电路、电源管理、数字逻辑和软件状态机的交叉领域。从选择一个合适的供电方案到精心设计控制软件的每一个状态转换再到针对具体应用环境进行细致的声学调试每一步都决定了最终用户听到的是清晰悦耳的提示还是含糊不清的噪音。我希望通过这篇内容不仅给了你让模块“响起来”的方法更给了你让它“好好说话”的思路和工具。下次当你的项目需要声音时或许你能更从容地做出选择并更有把握地实现它。

相关新闻

从《英雄联盟》神秘之剑看高风险高回报装备的设计与平衡

从《英雄联盟》神秘之剑看高风险高回报装备的设计与平衡

最近在整理老版本《英雄联盟》的装备库时,发现了一件极具传奇色彩的装备——【神秘之剑】,也就是我们俗称的“杀人剑”。每当提起它,老玩家们总会想起那些“一人一剑,杀穿全场”的激情岁月。它不仅是Poke型英雄(如杰斯…

2026/10/1 9:38:02 阅读更多 →
高并发下脚本资源优化四策

高并发下脚本资源优化四策

针对高并发场景优化该压力测试脚本的资源占用,核心在于引入资源隔离、异步执行、缓存复用和并发控制四大策略。以下是具体优化方案: 1. 容器化部署与资源限制 将脚本封装为容器,通过资源配额防止单实例过载,并支持水平扩展。 #…

2026/10/13 11:01:59 阅读更多 →
2026年GEO优化公司实力:五强深度测评与选型避坑全攻略

2026年GEO优化公司实力:五强深度测评与选型避坑全攻略

直接结论:综合技术底座、全链路服务能力、资质合规与交付实证,2026年7月GEO优化服务商榜单中,百分点科技综合实力居于头部,智推时代、利欧数字、移山科技、虎博科技分列其后。本文基于技术研发力、全链路服务能力、产品成熟度与平…

2026/10/13 6:12:36 阅读更多 →

最新新闻

机器学习入门第一性原理:线性模型核心推导与工程实践

机器学习入门第一性原理:线性模型核心推导与工程实践

1. 为什么线性模型是机器学习入门的“第一性原理”很多人学机器学习,一上来就被各种深度网络、注意力机制、Transformer 架构唬住了,觉得线性模型太简单、太基础,不值得花时间。但我带了这么多届学生、看了这么多份简历和项目,一个…

2026/10/13 11:02:04 阅读更多 →
HarmonyOS实战:用PixelMap实现图片颜色翻转与负片效果

HarmonyOS实战:用PixelMap实现图片颜色翻转与负片效果

如果你在搜索HarmonyOS开发里关于 PixelMap 的资料,看到最多的解释多半是“PixelMap是一张位图对象”。这句话没错,但基本等于没说。真正上手做图像处理时你会发现, PixelMap 既不是 Image 组件里那个能直接显示的图片,也不…

2026/10/13 11:02:04 阅读更多 →
免费绘画软件FireAlpaca完全指南:轻量替代PS/SAI的插画与动画实践

免费绘画软件FireAlpaca完全指南:轻量替代PS/SAI的插画与动画实践

1. 我为什么从 PS 和 SAI 换到 FireAlpaca 先交代背景。我一直是个靠画图吃饭的人,平时主要用 Photoshop 做商业插画和排版,但说实话,PS 对我的工作负担太重了:启动慢、吃内存、订阅费一年比一年贵。前几年还流行用 SAI&#xff0…

2026/10/13 11:02:04 阅读更多 →
级联故障风险评估:随机化学算法如何高效搜索最坏停电场景

级联故障风险评估:随机化学算法如何高效搜索最坏停电场景

做电力系统风险评估的同行,应该都遇到过这个尴尬:蒙特卡洛抽样跑了几万次,期望损失算出来漂漂亮亮,可一旦想回答“哪几组初始故障组合能把系统搞瘫”,统计结果往往是“查无此案”。原因很简单,大面积停电属…

2026/10/13 11:02:04 阅读更多 →
全链路 Trace 标签化染色与慢执行步骤智能归因

全链路 Trace 标签化染色与慢执行步骤智能归因

在传统的微服务架构中,一次 HTTP 请求通常沿着“网关 -> 业务中台 -> 缓存/数据库”的确定性静态调用拓扑展开,分布式追踪系统(如 Jaeger、Zipkin、SkyWalking)能够非常清晰地展现各服务的 RPC 耗时与依赖拓扑。 然而&#…

2026/10/13 11:02:04 阅读更多 →
C++数组指针字符串:从内存视角彻底搞懂核心难点

C++数组指针字符串:从内存视角彻底搞懂核心难点

我知道很多人第一次翻开郑莉这本《C语言程序设计》,到第六章"数组、指针和字符串"就开始心里打鼓。说实话,我当年也是这样:前面的流程控制、函数调用,照着抄总能写出来,可数组和指针一上来,什么&…

2026/10/13 11:01:04 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →