news 2026/9/3 8:17:57

从单片机到数控云台:核心架构、控制算法与工程实践全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从单片机到数控云台:核心架构、控制算法与工程实践全解析

简介:本资源是面向电子工程与自动控制初学者及课程设计者的单片机实践项目,聚焦数控云台这一典型机电一体化系统,解决从理论控制算法到硬件闭环调试的学习断层问题。压缩包共66个文件,264KB,涵盖Proteus仿真工程(.dsn、.prj)、主从双轴C语言源码(.c/.h)、编译中间文件(.obj/.lst/.hex)、LCD显示驱动模块(LCD.C、sed1565_s.h等)及PID控制核心逻辑(skytmain.c、skytslave.c),完整呈现主轴(master)与副轴(slave)协同控制架构。已有160人学习下载,资源结构清晰分层:顶层为可直接加载运行的Proteus仿真电路,中层提供带注释的模块化程序(含角度传感器反馈处理、UART通信协议实现、电机PWM驱动接口),底层附有汇编输出(.asm)、内存映射(.map)及EEPROM配置(.eep),便于深入理解单片机底层运行机制与系统级调试方法。

1. 项目缘起:从“云台”到“数控”的跨越

最近在整理硬盘里的老项目,翻到了一个尘封已久的压缩包,文件名是“基于单片机的数控云台系统(proteus仿真+程序资料).zip”。看到这个名字,很多老朋友可能会心一笑,这几乎是每个单片机学习者都会接触到的经典项目之一。但今天,我想聊的不仅仅是这个压缩包里的代码和电路图,而是想深入聊聊,当我们把一个简单的“云台”加上“数控”二字后,整个项目的技术内涵、设计思路和那些容易被忽略的实战细节,会发生怎样的质变。

所谓云台,本质上就是一个可以控制物体在水平和垂直两个维度上旋转的机械结构。我们生活中最常见的例子就是监控摄像头或者单反相机的三脚架云台。而“数控”,即数字控制,意味着我们不再用手去拧旋钮,而是通过编写程序,用数字信号来精确指挥云台的每一个动作。这个项目之所以经典,是因为它麻雀虽小,五脏俱全,完美串联了单片机作为控制核心、电机驱动作为执行机构、传感器反馈作为“眼睛”、以及上位机或按键作为人机交互的完整闭环控制系统。无论是用于学习PID算法、步进电机控制,还是作为单片机课程设计单片机毕业设计的选题,它都具有极高的教学和实践价值。

很多人拿到类似资料包,解压,用Proteus仿真跑通,看到两个舵机(或步进电机)转起来,就觉得大功告成了。这其实只完成了不到30%的工作。真正的挑战和乐趣在于:如何让云台转得“聪明”、转得“精准”、转得“稳定”?如何从仿真平滑过渡到实物制作,并解决那些仿真中永远不会出现的干扰、抖动和误差问题?接下来,我将结合这个经典框架,拆解一个高完成度的数控云台系统应该如何从零构建,并分享那些在数据手册和教程里不会写的“踩坑”经验。

2. 核心架构选型:为什么是“单片机+步进/舵机”?

构建一个数控云台,首先面临的是核心控制与执行机构的选择。这直接决定了系统的精度、成本、复杂度和扩展性。

2.1 控制核心:51单片机还是STM32?

资料包名称里隐含了“单片机”,但具体是哪一款?从相关热搜词如“51单片机”、“stm32单片机”、“蓝桥杯单片机”等可以看出,这是初学者最常见的两个选择。

  • 51单片机(如STC89C52):这是最经典的入门选择。优势在于架构简单,资料浩如烟海(郭天祥51单片机教程影响了一代人),引脚操作直观,非常适合理解最底层的IO控制、定时器、中断等概念。对于控制一两个舵机或步进电机的基础云台,其性能绰绰有余。在Proteus仿真中,51系列元器件的模型也非常成熟,仿真结果可靠。如果你的目标是快速验证算法、完成课程设计,51单片机是稳妥的起点。
  • STM32(如STM32F103C8T6):这是性能与功能上的升级选择。它基于ARM Cortex-M内核,主频更高,外设更丰富(多个高级定时器、硬件PWM、编码器接口、丰富的通信接口如USART、I2C、SPI)。如果你设计的云台需要更复杂的控制算法(如闭环PID)、需要接入更多传感器(如MPU6050姿态传感器做自稳定)、或者需要通过单片机 usb通信单片机ftp协议与电脑高速交互,STM32几乎是必然选择。它的定时器可以产生更高精度、更高频率的PWM波,对步进电机的细分驱动支持更好。

我的选型建议:对于纯粹的学习和仿真验证,可以从51单片机开始,成本低,思维链路短。但如果你的项目有向实物发展,尤其是对精度和扩展性有要求,我强烈建议直接使用STM32。现在STM32的开发环境(如Keil MDK、STM32CubeMX)和社区资源已经非常友好,学习曲线并不比51高太多,但带来的能力提升是巨大的。很多单片机毕业设计为了体现技术深度,也倾向于使用STM32。

2.2 执行机构:舵机 vs 步进电机

这是决定云台性能的关键。两者都能实现角度的精确控制,但原理和特性天差地别。

  • 舵机(Servo Motor):这是一个封装好的“位置伺服”系统。你只需要给它发送一个特定宽度的PWM信号(通常是20ms周期,0.5ms-2.5ms的高电平脉宽对应0-180度位置),它内部的控制电路和电机就会自动转到指定角度并保持。优点是控制简单、扭矩大、在额定角度内无累积误差。缺点是通常旋转范围有限(普通舵机在180度或270度以内),且连续旋转舵机无法反馈位置。它适合需要快速定位、对绝对位置精度要求高、但运动范围不大的场景。
  • 步进电机(Stepper Motor):通过按顺序给线圈通电,驱动转子一步一步地转动。它的角度控制是“开环”的,通过控制脉冲数量来控制旋转步数,通过脉冲频率控制转速。优点是可以在360度范围内连续旋转,精度由步距角(如1.8度/步)和驱动器细分决定,理论上无累积误差(只要不失步)。缺点是控制相对复杂(需要驱动器),低速可能振动,高速扭矩下降快,且一旦失步(因负载突变或速度过高导致),位置信息就完全丢失。

为了更直观地对比,我整理了以下表格:

特性舵机步进电机(带细分驱动器)
控制方式PWM脉宽(位置信号)脉冲(步数)与方向信号
控制复杂度极低,单片机定时器产生PWM即可中,需要脉冲序列,通常需定时器中断或PWM模拟
旋转范围通常有限(<360°)连续360°无限旋转
保持扭矩有,靠内部反馈维持有,靠线圈通电维持
精度较高,由内部电位计分辨率决定极高,由步距角和细分数决定
运行噪音通常较小(到达位置即停)可能有(尤其是低频振动)
是否怕失步不怕,是闭环系统非常怕,失步后需回零
成本相对较低电机+驱动器成本稍高
典型应用机器人关节、摄像头俯仰/偏航3D打印机、激光雕刻机、精密旋转台

对于数控云台的选择

  • 如果云台只需要在两个固定角度间摆动(如扫描式监控),舵机是简单高效的选择。
  • 如果云台需要连续、平滑地追踪一个运动目标,或者需要高精度多圈定位,步进电机配合细分驱动器是更专业的选择。这也是为什么很多高端摄影云台和望远镜赤道仪使用步进电机的原因。

在最初的仿真项目中,为了简化,很可能使用的是两个舵机模拟水平和垂直轴。但在实际进阶设计中,垂直轴(俯仰)因需对抗重力,可能选用扭矩更大的舵机;水平轴(偏航)若需连续旋转扫描,则可考虑步进电机。这种混合架构在实际产品中也很常见。

3. 控制系统的“大脑”与“神经”:编程与电路设计精要

确定了架构,接下来就是实现。这部分是代码和硬件结合的战场,也是问题的高发区。

3.1 核心控制逻辑:状态机与定时器

无论用51还是STM32,控制程序的核心都是一个状态机配合定时器的精妙协作。程序绝不能是简单的while(1)里顺序执行,而应该由定时器中断作为“心跳”,驱动状态迁移。

以STM32控制步进电机云台为例,一个稳健的程序框架如下:

  1. 系统初始化:配置系统时钟、GPIO(脉冲、方向、使能引脚)、定时器(用于产生精确的脉冲序列或PWM)、串口(用于接收上位机指令)、ADC(如果接入了电位器作为手动输入)等。
  2. 主循环(Main Loop):这里只处理非实时性任务,如:
    • 解析来自串口的上位机指令(例如,GOTO X100 Y50表示转到水平100步,垂直50步的位置)。
    • 扫描按键输入,设置目标位置或速度。
    • 更新系统状态显示(如果有LCD)。
    • 处理一些低速的逻辑判断。
  3. 定时器中断服务程序(TIMx_IRQHandler):这里是实时控制的核心。
    • 对于步进电机:在中断里根据当前目标位置和实际位置(一个记录步数的变量)的差值,决定是否发出一个脉冲(翻转脉冲引脚电平),并更新实际位置。同时,可以计算“步进间隔”,用更高级的算法(如S曲线加减速)来调整中断频率,从而实现电机的平滑启停,避免失步和抖动。这就是所谓的“步进电机加减速算法”,是步进电机应用的精髓。
    • 对于舵机:通常不需要在高速中断里处理,因为PWM波形由硬件定时器的PWM输出功能自动生成,只需在需要改变角度时,更新一下定时器的比较寄存器(CCR)值即可。STM32的定时器硬件PWM功能非常强大,完全无需软件干预。
// 伪代码示例:步进电机定时器中断中的核心逻辑 void TIM2_IRQHandler(void) { if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) { // 清除中断标志 TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // 水平轴电机控制 if (target_step_x != current_step_x) { // 设置方向 DIR_X_PIN = (target_step_x > current_step_x) ? 1 : 0; // 发送一个脉冲 PULSE_X_PIN = 1; delay_us(2); // 短暂高电平,脉冲宽度 PULSE_X_PIN = 0; // 更新当前位置 current_step_x += (target_step_x > current_step_x) ? 1 : -1; } // 垂直轴电机控制同理... // 这里还可以加入速度规划计算,动态调整定时器重载值(TIM2->ARR)来改变中断频率,实现调速。 } }

3.2 驱动电路设计:从仿真到实物的“惊险一跃”

Proteus仿真中,我们可以用一个简单的“Motor”模型或者直接连上舵机模型,点击运行就能动。但实物制作中,驱动电路是成败关键。单片机IO口的驱动能力(通常只有几十毫安)远远不足以直接驱动电机。

  • 舵机驱动:相对简单。虽然舵机内部有控制电路,但多个舵机同时工作或快速转动时,瞬间电流也可能很大。务必确保你的电源(常用5V或6V)能提供足够的电流(每个舵机堵转电流可能高达1A以上)。建议在电源入口处并联一个大容量(如470μF)电解电容和一个小容量(如0.1μF)瓷片电容,以缓冲电流冲击。舵机信号线直接接单片机IO即可,但若距离较远,可考虑加入74HC14等施密特触发器整形信号,防止干扰。
  • 步进电机驱动必须使用专用驱动器芯片或模块。常见的有A4988、DRV8825、TB6600等。单片机只向驱动器发送“脉冲PUL”、“方向DIR”和“使能EN”三个信号。驱动器的强大之处在于:
    1. 电流放大:将单片机毫安级的信号放大到驱动电机所需的安培级电流。
    2. 细分控制:通过拨码开关设置,可以将电机的一个整步细分为多个微步(如1/16、1/32步),使运动极其平滑,分辨率大幅提高,基本消除低频振动。这是提升云台运行品质的关键。
    3. 保护功能:具有过流、过热保护。

实物制作中最容易忽略的问题:

  1. 共地!共地!共地!:单片机、驱动器、电机电源的地线必须可靠连接在一起,形成一个共同的参考零电位。否则会导致控制信号紊乱,电机不转或乱转。
  2. 电源隔离与滤波:电机是巨大的噪声源。强烈建议为单片机和数字电路部分(驱动器逻辑电源)使用独立的LDO(如AMS1117-3.3)供电,并与电机动力电源分离。在驱动器的电源输入端,同样需要并联大电容进行储能和滤波。
  3. 信号线干扰:脉冲和方向信号线应尽量短,如果必须延长,建议使用双绞线。可以在单片机输出端串联一个100-220欧姆的电阻,以限制信号边沿的陡峭程度,减少高频辐射干扰。

4. 从“能动”到“精准”:反馈与校准的必要性

一个开环的步进电机系统,或者一个普通的舵机,其精度是有限的。舵机有回差,步进电机可能失步。要让云台达到“数控”级的精度,引入反馈环节是必由之路。

4.1 位置反馈的几种实现方式

  1. 编码器:安装在电机轴上的旋转编码器(增量式或绝对式)可以实时反馈电机实际转过的角度。结合PID算法,可以构成一个真正的全闭环位置控制系统,彻底消除失步和负载扰动带来的误差。这是最专业、成本也最高的方案。STM32的定时器大多带有编码器接口模式,可以硬件解码编码器信号,非常方便。
  2. 电位器:在从动轴(云台转轴)上安装一个多圈精密电位器,将其电压通过单片机的ADC采集进来,通过标定就可以知道当前绝对位置。这是一种经济有效的半闭环方案(反馈在负载端,而非电机端)。需要注意电位器的线性度、寿命和安装同心度。
  3. 限位开关/原点传感器:在云台运动范围的极限位置安装微动开关或光电传感器。每次系统上电或复位后,驱动云台向一个方向缓慢运动,直到触发限位开关,将此点定义为机械原点(Home Position)。后续的所有位置控制都基于这个原点进行推算。这不能提高运动中的精度,但可以消除每次上电的累积误差,是绝大多数数控机床和3D打印机的标准做法。

4.2 系统标定:将“读数”转化为“角度”

无论采用哪种反馈,都需要进行标定。这是一个枯燥但至关重要的过程。

假设我们用电位器反馈。步骤是:

  1. 将云台手动转到水平方向的物理零位(例如,指向正前方)。
  2. 记录此时单片机ADC的采样值,记为ADC_X_zero
  3. 将云台手动转到水平方向的最大角度(例如,正左方),记录ADC值ADC_X_left
  4. 同理,记录正右方的ADC_X_right

那么,任意时刻ADC采样值adc_x对应的角度angle_x可以通过线性映射(假设电位器线性度良好)计算出来:angle_x = (adc_x - ADC_X_zero) * (机械角度范围 / (ADC_X_left - ADC_X_right))

这个公式需要根据你的安装方向和电气特性进行调整。标定数据可以保存在单片机的EEPROM或Flash中,下次上电直接读取。

5. 上位机与交互:让控制更直观

一个孤立的云台意义有限。通过上位机,我们可以解锁更多功能:预设点位、轨迹规划、实时监控、参数调整等。

5.1 通信协议设计

单片机与电脑(上位机)之间最常用的就是串口(UART)通信。设计一个简单而健壮的自定义串口协议是第一步。

例如,我们可以定义这样的指令帧:[帧头][指令码][数据长度][数据域][校验和][帧尾]

  • 帧头:如0xAA0x55,用于标识一帧数据的开始。
  • 指令码:1字节,表示要做什么。如0x01代表“绝对移动”,0x02代表“速度设置”,0x03代表“读取当前位置”。
  • 数据长度:1字节,表示后面数据域的字节数。
  • 数据域:具体参数。对于“绝对移动”指令,可以包含两个16位整数,分别表示水平目标步数和垂直目标步数。
  • 校验和:可以是前面所有字节的累加和取低8位,用于验证数据传输是否正确。
  • 帧尾:如0x0D0x0A(回车换行),标识帧结束。

在单片机端,需要在串口接收中断中实现一个状态机来解析这个协议,确保能正确识别出完整的指令帧,并丢弃错误或残缺的数据。

5.2 上位机软件开发

上位机可以用任何你熟悉的语言开发,如C#(WinForm/WPF)、Python(PyQt/Tkinter)、甚至LabVIEW。其核心功能包括:

  • 连接管理:选择串口号、设置波特率、打开/关闭连接。
  • 指令发送:通过按钮或输入框,组装上述协议指令并发送。
  • 数据接收与显示:解析单片机返回的数据(如当前位置、状态),实时显示在界面上。
  • 点位管理:保存多个预设位置(如“位置1:看门口”、“位置2:看窗户”),一键调用。
  • 手动控制:提供类似游戏手柄的UI,用鼠标或键盘方向键实时控制云台微动。

一个简单的Python + PySerial + Tkinter的上位机,可能只需要几百行代码,但能极大提升项目的完整度和可玩性。这也是将单片机课程设计提升一个档次的有效手段。

6. Proteus仿真:高效验证与调试的利器

在动手焊接电路之前,Proteus仿真是无价的工具。它不仅能验证电路逻辑的正确性,更能调试程序,尤其是那些与定时相关的复杂逻辑。

6.1 在Proteus中构建云台仿真模型

  1. 绘制原理图:放置单片机(如AT89C52或STM32F103模型,需安装相应库)、晶振、复位电路、电源。
  2. 添加电机模型:对于舵机,Proteus中有“SERVO-MOTOR”模型,它有三个引脚:控制、电源、地。连接非常简单。对于步进电机,可以搜索“MOTOR-STEPPER”,并配合“ULN2003”或“L298”这类驱动芯片模型一起使用。
  3. 添加虚拟仪器:为了观察PWM波形,可以放置一个“Digital Oscilloscope”(数字示波器),将单片机的PWM输出引脚连接到通道上。为了监控串口数据,可以放置一个“Virtual Terminal”(虚拟终端),连接到单片机的TXD/RXD引脚,并设置好波特率。
  4. 加载程序:双击单片机,在弹出的属性框中,选择你编译好的HEX文件(对于51)或ELF文件(对于ARM,需要配合Keil MDK和Proteus的VDM插件)。

6.2 仿真调试技巧与局限

  • 观察PWM波形:运行仿真后,打开示波器,你可以清晰看到单片机输出的PWM脉宽是否随你的程序改变,这是调试舵机控制最直观的方法。
  • 虚拟终端交互:你可以在虚拟终端里输入字符,模拟上位机发送指令,观察单片机的回显,调试串口通信协议。
  • 设置断点与单步:Proteus支持与Keil等IDE联合调试。你可以像调试软件一样,在程序里设置断点,观察变量,单步执行,这对于理解程序流程、排查逻辑错误极其有效。

然而,仿真有其无法替代的局限性

  • 无实时性:仿真速度远慢于真实硬件,无法模拟严格的时序要求。一个在仿真中完美的步进电机脉冲序列,在实物上可能因为中断响应延迟而出错。
  • 无噪声与干扰:仿真电路是理想的,没有电源纹波、没有信号串扰、没有电机反电动势。很多在实物上让你头疼的问题,仿真里永远不会出现。
  • 外设模型不全:很多复杂的传感器(如MPU6050)或驱动器芯片,可能没有精确的仿真模型。

因此,仿真的定位应该是逻辑验证和前期调试,绝不能替代实物测试。一个良好的开发流程是:在仿真中完成基本功能验证 -> 制作最小系统板进行实物核心功能测试 -> 逐步添加外围电路和负载进行联调。

7. 从项目到产品:进阶优化与扩展思路

当你完成了基础版本的云台,还可以从以下几个方向进行深化,这会让你的项目从“作业级”跃升到“作品级”。

7.1 运动控制算法升级

  • S曲线加减速:这是步进电机高级应用的标志。让电机以S型曲线(加速度先增后减)启停,而不是匀加速,可以极大减小机械冲击,避免失步,实现更平滑、更快速的运动。这需要单片机有较强的计算能力(STM32完全胜任),在定时器中断中动态计算下一个脉冲的时间间隔。
  • 直线/圆弧插补:如果你的云台需要让激光笔或摄像头光轴画一条直线或圆弧,就需要插补算法。它根据路径起点和终点,实时计算出两个电机(水平、垂直)需要配合运动的步数序列。这是多轴数控系统的核心。
  • PID位置闭环:如果加了编码器,就可以实现PID闭环控制。PID控制器根据目标位置和编码器反馈的实际位置的偏差,动态调整输出给驱动器的脉冲频率,从而抵抗负载变化,实现精准定位。调试PID参数(Kp, Ki, Kd)本身就是一个充满挑战和乐趣的过程。

7.2 功能扩展

  • 无线控制:加入蓝牙模块(如HC-05/06)或Wi-Fi模块(如ESP-01S),用手机APP或网页来控制云台,彻底摆脱线缆束缚。
  • 视觉反馈:在云台上加一个小摄像头(如OV7670模组),将图像传回电脑,结合OpenCV进行图像处理,实现人脸追踪、颜色追踪、自动对焦等智能功能。这就是一个简易的“智能跟踪云台”。
  • 环境感知:加入光敏电阻或单片机太阳能追光舵机项目中提到的光敏传感器阵列,让云台自动追踪光源(太阳),这就是一个太阳能追光系统。或者加入温湿度传感器,让云台指向特定环境参数的区域。

7.3 工程化与可靠性考量

  • 错误处理与恢复:程序里要加入超时判断、指令校验失败重发、电机堵转检测(通过电流采样或编码器反馈长时间无变化)等机制。一旦发生异常,系统应能安全停止,并向上位机报告错误代码。
  • 参数存储:将标定数据、用户预设点位、PID参数等存储在单片机的内部Flash或外置EEPROM芯片中,实现掉电保存。
  • 低功耗设计:如果使用电池供电,需要考虑休眠模式。当长时间无操作时,单片机进入休眠,关闭电机驱动器电源,仅保留唤醒源(如按键中断、串口中断)工作。

回过头来看,“基于单片机的数控云台系统”这个项目,它绝不仅仅是一个压缩包里的几行代码和几张电路图。它是一个微缩的、完整的机电一体化系统原型。从芯片选型、电路设计、固件编程、算法实现,到上位机开发、系统联调,它几乎涵盖了嵌入式开发的所有核心环节。通过深入实践这个项目,你真正收获的将是如何让代码与硬件共舞,如何将抽象算法转化为精确的物理运动,以及如何系统地思考和解决从仿真到实物过程中层出不穷的工程问题。这远比单纯地“跑通一个仿真”要有价值得多。希望我的这些拆解和心得,能帮你打开思路,做出一个不仅“能动”,而且“卓越”的数控云台。

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/3 8:17:38

树莓派四驱小车:具身智能的硬件闭环实践

简介&#xff1a;这是一套面向计算机、电子信息与自动化专业学生的树莓派四驱智能小车完整开发资源&#xff0c;适用于课程设计、期末大作业及毕业设计参考&#xff0c;覆盖黑线循迹、超声波避障、红外遥控、网络远程控制、磁轨引导及YOLO红绿灯识别等六大核心功能模块。资源包…

作者头像 李华
网站建设 2026/9/3 8:15:48

《和平精英》反外挂实战指南:从识别、取证到高效举报

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

作者头像 李华
网站建设 2026/9/3 8:13:25

Momenta上半年毛利增79.4%:智驾盈利爬坡逻辑拆解

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

作者头像 李华
网站建设 2026/9/3 8:12:40

仿微拍堂源码真相:Vue拍卖系统的技术陷阱与重构路径

简介&#xff1a;这是一套2022年仿微拍堂古玩字画拍卖系统的完整前端后端源码&#xff0c;面向中高级Web开发者及全栈学习者&#xff0c;聚焦拍卖类电商场景的工程化实现与业务逻辑落地。资源包共1479个文件&#xff0c;涵盖237个JavaScript文件&#xff08;含63个Vue单文件组件…

作者头像 李华
网站建设 2026/9/3 8:12:15

基于Electron的跨平台MC启动器开发实战

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

作者头像 李华