基于STM32的机场智能驱鸟系统:复合检测与分级驱离方案设计

简介:面向嵌入式开发者和STM32初学者的机场驱鸟装置完整工程资源,基于STM32F103的ARM Cortex-M3内核,利用舵机与超声波模块实现鸟类检测与自动驱离,可应用于机场净空区、果园、农田等场景。压缩包共159个文件,以C源文件、头文件、STM32CubeMX工程配置及Keil工程文件为主,含启动文件、分散加载文件、依赖文件及编译生成的hex/axf/map等中间文件,整体仅5.12MB,便于快速下载和二次开发。工程覆盖GPIO与PWM舵机角度控制、超声波测距驱动、中断快速响应、电源管理等关键模块,并涉及FreeRTOS任务调度、UART/SPI/I2C通信扩展,帮助读者掌握STM32外设编程与嵌入式系统开发流程。已有272人学习,适合用STM32完成智能驱鸟或类似测距、伺服控制项目的学习者参考。

1. 需求切入:机场驱鸟为什么需要STM32方案

机场驱鸟是鸟击防范里最日常又最头疼的一件事。鸟击对航班安全的威胁不用多说,问题在于传统驱鸟方式——人工巡逻、煤气炮、猎枪驱散,成本高且覆盖不连续。煤气炮声音大但只能在固定点位,鸟群很容易形成习惯性适应,几次之后效果明显下降。更麻烦的是,机场围界范围大,人工驱鸟的盲区永远存在。一套能自动检测鸟类活动、自动分级驱离、还能远程看的装置,就是这个场景下最实际的解法。

用STM32F103来做这套装置的核心控制器,是一个很稳妥的选型。F103的主频72MHz,GPIO、定时器、ADC、UART这些资源刚好覆盖传感器接入、功放控制、通信上报的全部需求,功耗低、外设丰富,而且资料多、调试方便。对于毕设、课程设计,或者机场围界、农场果园的初步自动化驱离,这套硬件平台的成本和技术风险都足够低。这套方案要解决的,就是“怎么让驱鸟从人工巡逻变成自动感知、自动决策、自动执行、远程可管”的问题。

2. 总体设计:硬件选型与四层架构的职责划分

2.1 硬件选型:STM32F103的资源怎么分配

先看硬件资源能不能扛住需求。STM32F103C8T6这颗芯片,72MHz主频,64KB Flash、20KB RAM,片上外设包含多个定时器、两个SPI、两个I2C、三个UART、一个ADC。对于驱鸟装置这种场景,传感器的数据量不大,驱离执行器大多是开关量控制和PWM驱动,通信走串口透传,所以资源是够用的,不需要上F407这种高性能芯片。

实际项目中通常按功能模块来分配引脚资源。鸟类检测侧,一个微波雷达模块输出电平信号接GPIO,一个红外热释电模块同样接GPIO,如果这两路信号需要模拟量连续采集,也可以用ADC输入。驱离执行侧,语音驱离需要PWM输出控制音频功放的音量或者音调,超声波换能器需要专用的PWM频率输出,强光灯和煤气炮的点火信号用继电器控制。通信侧,4G模组或者LoRa模组占两路UART,一路用于AT指令配置,一路用于数据上报。整个系统的外设占用情况,一张表就能看得很清楚。

外设用途连接对象
GPIO传感器信号输入、继电器控制微波雷达、红外热释电、继电器
定时器TIM1/TIM2超声波PWM产生、系统调度时钟超声波换能器、定时中断
ADC电池电压监测电压采样电路
UART1通信模组数据收发4G/LoRa模块
I2C扩展传感器/存储温湿度传感器、EEPROM

2.2 系统架构:感知-决策-执行-回传四层

这套驱鸟装置的整体架构,从逻辑上可以分成四层:感知层、决策层、执行层和回传层。感知层负责检测鸟类是否进入防护区域,决策层是STM32F103主控板,运行检测算法和驱离策略,执行层负责把控制信号转换成物理驱离动作,回传层负责把设备状态和触发记录送到监控端。

感知层,微波雷达加红外热释电双通道复合检测。雷达模块检测运动物体,红外热释电检测温血动物体温,两个信号同时有效才确认“有鸟进入”,从硬件层面先挡掉一部分误报。决策层,STM32F103跑一个状态机,根据连续检测时间和触发次数,决定执行几级驱离。执行层,第一级超声驱离,第二级猛禽叫声语音驱离,第三级强声加激光照射。回传层,通过4G模块把触发时间、触发的驱离级别、设备电量状态上报到平台,同时接收远程强制驱离命令。

这套架构的优点在于,每一层都可以单独替换和调试。检测误报率高,只调感知层的判断逻辑,不影响执行层;要增加新的驱离手段,只需在执行层加一路控制输出。整体结构清晰,做毕设时也方便按模块拆开写文档、做演示。

3. 关键模块设计与实现细节

3.1 复合检测模块:微波雷达与红外热释电怎么配合

单一的传感器在户外环境里误报率非常高。微波雷达能感知任何移动物体,哪怕是一只飞过的昆虫或者晃动的树枝,都能触发信号。红外热释电对温血动物的体温敏感,但如果有阳光直射导致环境温度剧烈变化,也会产生误触发。把两个传感器的输出做逻辑与,是户外检测比较实用的做法。

具体实现上,微波雷达模块选用输出TTL电平的型号,检测范围内有物体移动时输出高电平。红外热释电模块选用带菲涅尔透镜的成品,输出同样是TTL电平。STM32F103的GPIO配置成上拉输入,直接读这两个电平。需要注意的是,热释电模块在检测到人体或动物后,输出高电平会持续几秒,而微波雷达在目标停止移动后会恢复低电平,所以单纯做电平与判断,在“鸟静止站在跑道上”的场景下会漏报,通常的做法是加一个“触发锁存”逻辑,只要热释电有效,就把检测状态保持一段时间,期间只要有雷达信号就触发确认。

3.2 分级驱离执行模块:超声、语音、强光三级策略

驱离手段不能一上来就放大招,一是声音和光照持续高强度输出容易让鸟类产生适应性,二是能耗高。实际使用中,我一般按三级策略来设计:一级驱离是超声波,功率小、无声,对鸟类有惊吓作用,不扰民;二级驱离是播放模拟猛禽叫声或者猎枪声,通过功放输出到定向喇叭;三级驱离是强光频闪加更大功率的强声驱离,用于顽固鸟群。

在电路设计上,超声驱离用STM32F103的定时器输出PWM,经过MOS管驱动升压电路带动超声换能器,通过改变PWM频率来调整超声波的频点,避免鸟类长期适应同一个频率。语音驱离用音频功放模块,输入端接主控的DAC引脚或PWM输出的音频信号,输出端接号角喇叭。强光灯和强声设备的启动,通过继电器控制,继电器选型时要注意线圈电压和触点电流,预留足够的余量。

3.3 通信回传模块:自定义帧协议与远程命令解析

通信模块承担两部分工作:把设备状态上报到远程监控端,接收远程的强制驱离命令。用4G模组时,STM32F103通过UART发送AT指令来联网并建立TCP连接,数据传输走自定义帧格式,每一帧包含帧头、设备ID、指令类型、数据长度、数据和CRC校验,这样可以在比较差的网络环境下尽量保证数据可靠。

// 帧协议定义示例 typedef struct { uint8_t head; // 帧头,固定0xAA uint8_t device_id; // 设备编号 uint8_t cmd; // 指令类型,0x01上报状态,0x02远程驱离 uint8_t len; // 数据长度 uint8_t data[8]; // 数据区 uint8_t crc; // CRC校验 } frame_t;

帧协议看起来简单,但实际踩坑不少。比如帧边界,如果只用帧头判断,数据区里恰好出现0xAA就会造成错位,通常的做法是再加一个帧尾,或者对数据区做转义处理。再比如CRC校验算法,不要为了省事直接用累加和,现场环境电磁干扰强,累加和的错误检出能力不够,建议用CRC8或者CRC16。

4. 软件实现:状态机、核心逻辑与可靠性设计

4.1 主程序状态机与状态转移

软件的核心是一个五态状态机:待机、预警、一级驱离、二级驱离、三级驱离。待机状态下,系统周期性采样两个传感器信号。检测到鸟类进入且确认后,进入预警状态,开始短促超声脉冲。如果鸟类在设定时间内没有被驱离,状态升级,进入一级驱离、二级驱离,最高到三级驱离。如果一段时间内检测不到鸟类活动,状态逐步退回待机。

状态转移的条件是软件设计的关键。转升级条件不能只看“当前有鸟”,还要看持续时间和触发次数,避免鸟只是短暂飞过就触发高强度驱离。状态机的设计让代码逻辑非常直观,调试时也只需要关注当前状态和转移条件。

4.2 核心代码:检测滤波与分级驱离逻辑

检测侧的软件滤波是挡误报最重要的一环。GPIO读到的电平信号不能直接作为有效触发,需要做防抖和连续确认处理。以下代码是检测滤波和状态机转移的核心片段。

#define DEBOUNCE_TIME 100 // 防抖时间 ms #define CONFIRM_TICKS 3 // 连续确认次数 uint8_t radar_flag = 0; uint8_t pir_flag = 0; uint8_t detect_tick = 0; // GPIO中断或10ms定时轮询中调用 void detect_update(void) { uint8_t radar_now = HAL_GPIO_ReadPin(RADAR_GPIO_Port, RADAR_Pin); uint8_t pir_now = HAL_GPIO_ReadPin(PIR_GPIO_Port, PIR_Pin); // 防抖:电平持续DEBOUNCE_TIME才认为有效 if (radar_now == 1) { radar_flag = 1; } else { radar_flag = 0; } if (pir_now == 1) { pir_flag = 1; } else { pir_flag = 0; } // 复合确认:两个信号同时有效且保持CONFIRM_TICKS次 if (radar_flag && pir_flag) { detect_tick++; if (detect_tick >= CONFIRM_TICKS) { state = STATE_ALERT; detect_tick = 0; } } else { detect_tick = 0; } }

代码里有一个细节,就是CONFIRM_TICKS的作用。在连续多次采样都满足条件时,才确认有鸟进入,这个机制可以过滤掉单个传感器瞬时抖动的干扰。实际项目中这个值要根据检测周期来调,如果采样周期是10ms,3次确认就是30ms,这个时间去抖比较合理,太长会导致响应变慢,鸟已经飞走了才触发驱离。

4.3 看门狗:系统不能死,尤其这种无人值守设备

驱鸟装置是无人值守设备,摆在机场围界或果园边上,一旦程序跑飞或者死循环,没有人现场复位,整个设备就变成“尸体”。所以独立看门狗是必须的。STM32F103的独立看门狗用LSI时钟驱动,一旦启动就无法关闭,必须在窗口时间内喂狗,否则强制复位。

喂狗的位置非常讲究。如果只在主循环末尾喂,一旦某个阻塞函数卡住,看门狗会在超时后复位系统,这是正确的;但问题是,有些阻塞等待是“卡了很久但最终会恢复”的情况,比如4G模块的AT指令响应,极端情况下要等十几秒,如果喂狗周期是3秒,系统就会被误复位。通常的做法是:主循环里保持正常喂狗,在可能长时间阻塞的通信流程中,用中断定时喂狗兜底。

5. 工程落地与常见问题排查:最容易翻车的五个点

驱鸟装置是典型的户外嵌入式设备,实验室调试通过不代表现场能用。项目做下来,最常遇到的问题集中在电源、误报、声音失真、看门狗复位和现场防护这几个方面。这一章把容易翻车的现象、原因和解决思路列清楚,照着排查能省下不少现场调试的时间。

5.1 误报率居高不下:现象、原因与解决

现象是设备装到现场后频繁触发驱离,一个下午的触发记录能有上百条,但实际并没有那么多鸟靠近。排查后发现,雷达模块的灵敏度调得过高,检测距离覆盖到围界外道路上的车辆和行人,只要有人或车经过,设备就误认为有鸟群。

原因有两层。第一层是微波雷达的检测距离没有根据现场环境调节,默认量程过大。第二层是热释电传感器的安装角度正对阳光照射区域,下午光线变化引起温度梯度变化,导致热释电误输出。解决方法是把雷达灵敏度调到只覆盖防护区域范围,并调整热释电模块的安装朝向,避免正对低角度阳光。

5.2 语音驱离时喇叭啸叫

现象是播放猛禽叫声时,喇叭出现尖锐的啸叫,驱离效果大打折扣,还非常刺耳。原因有两个:功放模块的增益调得过高,输出信号反馈到麦克风或输入端形成自激;供电电源的纹波太大,音频信号被电源噪声叠加。解决时先降功放增益,在输入端加强滤波电容,再把音频输出线和电源线分开走线,啸叫基本能消除。

5.3 看门狗误复位导致设备频繁重启

现象是设备运行一段时间后自动重启,重启时间点没有明显规律,看调试日志看不到程序死循环的痕迹。排查后发现问题出在喂狗位置:喂狗只安排在主循环末尾,而通信流程中AT指令等待响应时,会阻塞主循环数秒钟,超过了看门狗超时时间。

解决方法是把喂狗拆成两个路径。主循环正常运行到末尾时喂一次;通信模块在进入等待状态前,在定时器中断里启动周期喂狗,通信完成后停止中断喂狗。这样既不会误复位,也保留了死循环检测能力。这个问题的本质是看门狗策略设计问题,不能只看代码逻辑。

5.4 驱离瞬间设备复位,电源电压跌落

现象是继电器闭合或功放功率拉满的瞬间,设备直接掉电重启,复位后状态丢失。原因是电源余量不够。继电器线圈吸合瞬间有较大的冲击电流,功放满功率输出时瞬时电流也明显上升,而太阳能供电情况下蓄电池电压本来就不稳,瞬时压降触发单片机掉电复位。

解决思路有三个方向。一是加大蓄电池容量和电源模块的输出电流能力,别卡着额定值选型;二是在继电器控制端加软启动,也就是PWM渐进加大占空比,避免瞬间全功率;三是在主控板供电输入端加大容量电容,储能扛住毫秒级的跌落。这三个方向通常一起上,才能彻底解决。

5.5 防水防潮与雷击损坏

现象是设备在雨季频繁无常,PCB腐蚀、接口氧化、传感器灵敏度下降。

原因是接线盒的防护等级不够,接线端子长期暴露在潮湿环境,部分信号线没有做屏蔽,雷雨天气感应雷击穿电源模组。解决方法是把所有接线点移到IP65的防水接线盒内,信号线走屏蔽线并单端接地,电源入口加TVS管和压敏电阻,传感器探头本身检查是否有配套防水壳。这些看起来不“技术”的细节,恰恰是户外设备能不能长期运行的关键。

6. 验收与答辩:用一张测试用例表证明方案有效

功能验收这部分,一份可量化的测试用例表,比口头描述有用得多。测试时把设备放在模拟场景里,按检测、分级驱离、远程控制、状态回传几个维度逐项过。检测测试包括遮挡、远距离、逆光、夜间条件;分级测试验证各等级是否按时间和频次正确升级;远程控制测试确认下发强制驱离命令后,控制信号的响应时间是否在可接受范围内。每一项都要记录输入条件、操作步骤、预期结果、实际结果,形成完整的验收记录。

答辩时的讲述方式也很重要。不要按功能模块平铺,而是讲技术决策的逻辑。比如,为什么选用STM32F103而不是更高端的芯片,回答的核心是资源评估——传感器数据量小、控制逻辑不复杂,F103的资源恰好覆盖需求,成本和外设开发难度更优。再比如,为什么检测要走双传感器复合,因为单传感器误报率在户外无法接受,而复合检测用硬件条件和软件确认两次过滤,把误报控制在可接受范围内。抓住这样两三个关键决策点讲深,比把每个模块都讲一遍更有说服力。

还有一个实战细节:现场演示时,提前准备好触发驱离的方式。如果现场没有鸟,需要能用模拟信号触发检测,不要出现演示时设备无响应的尴尬。我第一次迭代这套装置时,就是在野外测试时没有备好模拟触发方案,结果现场演示变成“对着空气讲解”,后来每次验收都会带一个可调节的模拟红外信号源,强制走一遍完整流程才收工。希望这套方案能帮你把项目做得完整可控,省去验收时的返工。

本文还有配套的精品资源,点击获取

相关新闻

SnapShot v1.50轻量级系统镜像备份工具使用详解

SnapShot v1.50轻量级系统镜像备份工具使用详解

你有没有碰到过这种时刻:电脑昨天还正常用着,今天开机就卡在转圈界面不动,C盘里存的资料、多年攒下的软件配置、还没来得及拷出来的照片,全困在一个看不见的硬盘分区里。如果你手上没有一份完整的系统镜像备份,接下来的…

2026/10/19 15:58:25 阅读更多 →
把休眠当关机:Windows一键休眠、定时唤醒与避坑清单

把休眠当关机:Windows一键休眠、定时唤醒与避坑清单

下班前我从来不点关机,而是直接合上笔记本。第二天到工位打开盖子,屏幕亮起,浏览器、文档、命令行窗口全都还在,好像昨天从未离开过。这就是把“休眠当关机”的核心体验:用休眠代替一次完整关机,既不碰硬件…

2026/10/19 15:57:15 阅读更多 →
大模型指令微调实战:从损失函数到数据工程的完整指南

大模型指令微调实战:从损失函数到数据工程的完整指南

1. 预训练模型不是不聪明,而是"不听话":指令微调要解决的真正矛盾去年我帮团队优化一个内部问答系统,同事拿一个已经在通用语料上训练好的开源底座模型做指令微调,喂了十几万条问答数据,跑了一天一夜&#x…

2026/10/19 15:57:15 阅读更多 →

最新新闻

Web安全三要素:SQL注入、XSS与CSRF的真实场景解析

Web安全三要素:SQL注入、XSS与CSRF的真实场景解析

1. 为什么“学完就忘”的安全课,从来不是知识的问题,而是场景的缺失你有没有过这种经历:翻完一本《Web安全攻防实战》,笔记记得密密麻麻,OWASP Top 10 背得滚瓜烂熟,可真拿到一个真实上线的后台系统&#x…

2026/10/19 19:35:53 阅读更多 →
指数加权平均:从温度平滑到Adam优化器的核心机制

指数加权平均:从温度平滑到Adam优化器的核心机制

1. 从一个温度曲线说起:为什么优化算法需要“加权平均”先说一个我当年刚接触深度学习时的困惑:处理时间序列数据,比如某地一年的每日温度,数据往往带有很大的随机噪声。今天30度,明天25度,后天突然跳到31度…

2026/10/19 19:35:53 阅读更多 →
Popek-Goldberg定理:虚拟化可行性的数学基石

Popek-Goldberg定理:虚拟化可行性的数学基石

1. 项目概述:为什么“Popek和Goldberg定理”至今仍是虚拟化技术的基石你可能在读某篇关于云平台底层架构的文章时,偶然看到“Popek和Goldberg定理”这个名词,旁边还跟着一句“该定理证明了虚拟机监控器(VMM)的可行性”…

2026/10/19 19:35:53 阅读更多 →
Windows 开源输入法选型与配置实战:从 IME 机制到小狼毫

Windows 开源输入法选型与配置实战:从 IME 机制到小狼毫

如果你只是聊聊天、敲敲普通文档,Windows 自带的输入法确实够用。可一旦你需要在 Windows 上写代码、维护长篇文档、录入特殊符号,甚至同时保持拼音、五笔、注音几套输入习惯,自带输入法的短板就会一点点冒出来:词库排序不顺手、自…

2026/10/19 19:34:52 阅读更多 →
AI如何降低网店获客成本?从自动回复到意图识别的转化实战

AI如何降低网店获客成本?从自动回复到意图识别的转化实战

在这个流量越来越贵、平台规则越来越细的时候,很多做网店的朋友问我:AI到底能不能帮我把获客成本降下来?我的回答是,能,但前提是你得把它当成一个可以训练的销售助理,而不是许愿池里的锦鲤。今天我就拿大家…

2026/10/19 19:33:50 阅读更多 →
交通标志检测识别系统:YOLOv8+OpenCV+PyQt5实战

交通标志检测识别系统:YOLOv8+OpenCV+PyQt5实战

1. 方案选型与实际价值先说结论:这个项目是很多人入手深度学习落地时的首选练手目标。原因很简单——交通标志检测有真实场景价值,模型效果直观,又能把算法、界面、图像处理全部串起来。用 Python 作为底座,YOLOv8 负责目标检测&a…

2026/10/19 19:33:50 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 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/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 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/19 2:54:50 阅读更多 →
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/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练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/18 12:16:16 阅读更多 →