news 2026/11/6 1:08:44

EtherCAT与FSoE原理及实战:从STM32从站到24轴伺服

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
EtherCAT与FSoE原理及实战:从STM32从站到24轴伺服

说起来挺有意思,在伺服运控和自动化设备圈子里,EtherCAT早就不是什么新鲜词了。你随便打开一台中高端PLC或者运动控制卡,几乎都能看到它挂在参数表里。可真要问一句:为什么EtherCAT能用一帧数据跑几十个轴还这么稳,它和普通以太网到底差在哪?再加上一个FSoE——所谓“安全EtherCAT”——又是凭什么敢把安全回路交给一根网线?能一次讲透的人其实并不多。

这篇文章就是写给正在搞伺服调试、运动控制、PLC编程,或者准备从CAN/脉冲方案转向EtherCAT的工程师。我会把EtherCAT的帧处理机制、分布时钟同步、CSP模式,以及基于它实现功能安全通信的FSoE,从原理到实战一次性拆开。文中还会结合STM32从站开发、汇川H5U带24个IS660伺服轴的参考案例,把配置步骤、同步调试和现场排查经验都放进去。不绕弯子,直接进正题。

1. EtherCAT为什么是工业运控的首选:先把协议本身讲透

1.1 一个以太网帧,整条产线都在抢着“搬砖”

我以前给新来的同事讲EtherCAT,最喜欢用“快递车”来打比方。普通以太网是“发件模式”:主站发一帧数据,交换机收到之后要么转发、要么丢弃,端点之间靠目的MAC和IP找路。EtherCAT不是这样,它只有一个主站,主站发出一个标准以太网帧,帧里装的所有子报文,从站设备在硬件层面直接“路过即处理”——报文经过从站时,从站把属于自己的输出数据从帧里提取出来,同时把自己的输入数据塞回帧里,然后立刻把这帧发给下一个从站。

整个过程不需要操作系统参与,也不需要CPU做协议栈解析,全部由从站控制器ESC芯片完成。这才是EtherCAT响应速度快的根本原因:整条总线上无论挂多少个从站,一个以太网数据帧从头走到尾,就能完成全部从站的数据交换。每个从站额外引入的硬件转发延迟只有微秒甚至百纳秒级别。

所以你看现场动不动就是“一拖二十轴”“一拖四十轴”,对EtherCAT来说数据量从来不是问题,1ms周期、100Mbps带宽下,哪怕几十个轴的过程数据也就占几十字节。真正考验人的,反而是拓扑规划、从站配置和同步精度的调试。

1.2 分布时钟(DC):让几百个轴心跳一致的关键

轴多了,最怕什么?怕“各跳各的舞”。你给1号轴发位置指令,2号轴晚了几十微秒才收到,到了高速插补的时候,两个轴的动作就差了半拍,做出来的轨迹自然歪。EtherCAT解决这个问题靠的是分布时钟(Distributed Clock,简称DC)。

EtherCAT要求每个从站都带一个本地时钟。主站在初始化阶段会测量帧在相邻从站之间的传输延迟,然后把每个从站的时间戳补偿到同一个基准上。所有从站再通过SYNC信号在同一个时刻同时采样输入数据、同时更新输出数据。这样,从站A和从站B尽管物理上隔着几十米网线,但在逻辑上,它们是在同一个“嘀嗒”声里干活的。

实际同步精度做到多少?标准EtherCAT的同步抖动远小于1微秒,好的方案可以做到百纳秒级别。这个精度对绝大多数伺服应用都够用,甚至有点过剩。但前提是:主站侧的DC配置必须正确,参考时钟选得对不对、周期设定和从站是否一致,都会直接影响同步效果。很多“轴在低速好好的、一跑高速就抖”的疑难杂症,最后查来查去,问题都出在DC配置上。

1.3 CSP/CSV/CST:三种周期模式到底怎么选

很多人第一次接触EtherCAT,会被CSP、CSV、CST这几个词搞晕。其实它们是CiA402规范里定义的三种周期同步运行模式,区别只在于主站下发什么、驱动器闭环做什么。

  • CSP(周期同步位置模式):主站下发目标位置,驱动器内部负责位置环。适合插补、联动、轨迹运动这类应用,是运控项目中最常用的模式。
  • CSV(周期同步速度模式):主站下发目标速度,驱动器内部只做速度环。适合对位置精度要求不高、但需要连续调速的场景。
  • CST(周期同步转矩模式):主站下发目标转矩,适合张力控制、压力控制等需要直接控制力矩的场合。

我个人的建议是:能做CSP就尽量用CSP。原因很简单,位置环在驱动器内部跑,周期更短、实时性更好,主站只负责轨迹规划,CPU压力小。CSV和CST更像“半遥控”,主站干预程度更深,对总线的实时性要求反而更高。另外,使用CSP模式时,PDO里必须同时映射控制字(0x6040)、目标位置(0x607A)和状态字(0x6041),这些映射错一个字节,轴都动不起来。

1.4 拓扑选择和线缆的隐性坑

EtherCAT的拓扑非常灵活,支持线型、树型、星型,还可以用端子模块组合成混合结构。但如果让我选,我永远优先推荐线型:最直观、最好排障、最容易算负载。星型和树型需要额外购买分支模块,费用上去了,排查问题的时候还要一个个分支去试,得不偿失。

线缆方面有几个接地气的注意点:

  • 站间距离按标准以太网是100m,但现场环境建议控制在80m以内,留出余量。
  • 必须使用带屏蔽层的工业以太网线,普通的办公室网线在强电柜里很可能被干扰到掉站。
  • 网线屏蔽层要正确接地,现场最常见的干扰问题往往不是协议栈,而是屏蔽层没有良好接地。
  • 水晶头和线缆要买正品,伺服驱动器生产线上弯折频繁,劣质网线的弹片断掉是掉站的头号杀手。

另外强调一句:EtherCAT不要随便串入普通交换机。EtherCAT的帧结构是“一路直通”,普通交换机引入的存储转发延迟会破坏从站处理时序,哪怕看似能通讯,同步精度也会大打折扣。要用交换功能,就选专用的EtherCAT端子模块。

2. 从站实现:STM32做EtherCAT从站会遇到什么

2.1 三种从站硬件路线(没耐心的直接看结论)

如果你想自己做EtherCAT从站设备,比如做一个带EtherCAT接口的IO模块、阀岛或者简易伺服驱动器,硬件方案大体有三条路:

  1. ESC芯片 + 普通MCU:最常见。ESC芯片(比如LAN9252、ET1100)负责处理EtherCAT帧,MCU通过SPI或并口与ESC通信,跑从站协议栈。优点是灵活、资料多、成本可控,适合绝大多数定制从站开发。
  2. 集成ESC的处理器:有些芯片把ESC功能做进单片机里,比如AX58100,还有一些瑞萨的RZ系列。省了一颗外部芯片,但软件生态相对封闭,受制于原厂。
  3. EtherCAT模块/SOM:直接买别人做好的从站核心模块,你只写应用层。适合出货量不大或者想快速出样的情况,缺点是定制空间小、成本偏高。

对新手来说,最稳妥的路线就是STM32+LAN9252。STM32负责应用逻辑和协议栈,LAN9252负责实时帧处理,两边用SPI通信。第一次做时,重点把ESC的寄存器读写调通,再把中断和SYNC事件对接好,后面就顺了。

2.2 SSC生成代码后,一定要动手改的几个地方

做从站,基本绕不开倍福官方的SSC工具(Slave Stack Code Tool)。这工具能根据你选择的从站类型、PDO个数、SM通道数量,直接生成一份从站协议栈工程。

但生成代码只是开始,有几处必须自己动手:

  • 改厂商ID和设备ID:必须改成你自己的厂商编号和设备型号,否则主站扫描时只能识别成“未知设备”。而且这些ID要和ESI文件里的完全一致,主站就是靠ESI文件匹配从站的。
  • 确认SM(SyncManager)配置:同步管理器的分配直接决定过程数据的通道路数。一般至少要有SM2用于输出(主站到从站),SM3用于输入(从站到主站),缓冲区模式设置成“立即模式”或“DC模式”要对应上。
  • 应用层函数要挂对:协议栈生成的App_ProcessDataExchange和App_StateChange这两个回调,必须在主循环或者中断里高频调用,才能及时处理状态切换和数据交换。很多从站卡在PreOp进不了SafeOp,就是因为状态切换回调没处理完。
  • DC同步事件要接中断:如果你要用分布式时钟,就把ESC的SYNC0中断接到MCU的GPIO/EXTI上,在中断里做“那一刻”的采样和输出,才能保证从站侧的同步精度。

从站调试初期,先用主站软件开启“扫描配置”看从站处于什么状态,比瞎猜快得多。

2.3 那条objdef.c(890)警告,到底要不要管

热词里出现了一条很典型的IAR编译告警:“..\ethercat\objdef.c(890): warning: #767-d: conversion from pointer to small”。这条告警我在不少从站项目里都见过,它说的是IAR编译器检测到某个指针被转换成了小整数类型。

出现这条告警的位置通常在EtherCAT从站堆栈里访问对象字典或者处理EEPROM偏移量的代码段。很多情况下,这是代码模板故意做的强转,把某个地址的低16位提取出来做索引,属于无伤大雅的操作。但你不能因此就习惯性忽略它,尤其是当你自己写代码时也遇到“指针转小整型”,就要多留个心眼:在STM32这类32位MCU上,如果把一个32位指针直接转成uint16,高位地址会被截断,变量访问必然出错。

处理建议是:先确认报警位置的转换值范围,如果确实只需要低16位,就用显式强转并注释说明意图;如果转换的是指针变量本身,赶紧改回uint32。编译告警可以“选择性忽略”,但不能“无条件无视”。

2.4 PDO映射:配置从站最花时间的环节

做过一次从站配置你就会发现,大部分时间其实都耗在PDO映射上。PDO(Process Data Object)就是过程数据对象,决定主站往从站发什么、从站往主站回什么。

拿一个常见的伺服轴为例,RXPDO(主站→从站)通常包含:

对象含义类型
0x6040控制字(使能、复位、急停等)U16
0x607A目标位置S32
0x60FF目标速度(可选)S32

TXPDO(从站→主站)通常包含:

对象含义类型
0x6041状态字(反映当前状态机)U16
0x6064实际位置S32
0x606C实际速度(可选)S32

配置PDO时最容易犯的错就是映射顺序不一致。主站侧PDO顺序和从站侧PDO顺序差一个字节,数据就全错位了。检查方法很简单:主站软件里看“输入/输出映射”的长度和具体对象是否和从站ESI文件里写的一致。另外,EtherCAT里多字节参数默认是小端字节序,做上位机解析的时候一定要记得翻转。

3. FSoE:安全通信不是“再拉一根线”

3.1 黑通道:功能安全的底层逻辑

FSoE的全称是FailSafe over EtherCAT,中文常叫“安全EtherCAT”或“Safety over EtherCAT”。它的核心思想很有意思:不需要重新发明一套新的实时通信协议,也不要求在EtherCAT协议栈内部做安全处理,而是把安全数据当作普通过程数据,跑在原本的EtherCAT通道上。这个通道在安全设计里被称为“黑通道”。

所谓黑通道,意思是安全层已经默认这个底层通道是不可靠的——可能丢帧、可能重复、可能乱序、甚至可能被篡改。所以FSoE要在数据链路的上层,额外加一套安全机制,把“不安全的传输”变成“可检测错误的安全通信”。只要检测到异常,就立刻把设备拉到安全状态。

FSoE最高支持SIL3安全完整性等级,符合IEC 61508和IEC 61784-3的要求。这也是它敢用于安全相关应用的底气。简单理解:普通EtherCAT传的是“指令”,FSoE传的是“带保险的安全指令”,两者的物理链路是同一根网线,但安全层面做了独立防护。

3.2 FSoE帧结构:序列号、CRC和连接ID都在做什么

FSoE报文会作为一个子报文嵌入到EtherCAT帧的过程数据区里,从外部看,它只是“普通数据”的一部分。但打开FSoE报文,里面包含了一整套安全校验信息:

  • Frame Type:标识报文类型,比如安全连接建立、周期数据、连接关闭。
  • CRC:32位校验字段,生成多项式沿用CRC-32常用的0x04C11DB7。发送方算好CRC,接收方校验,任何一位翻转都会引发校验失败。
  • ConnID(连接ID):每条FSoE安全连接都有一个唯一ID,用于防止不同安全设备之间“接错线”。
  • Sequence Number(序列号):发送方每发一帧就加1。接收方发现序列号不连续,就知道发生了丢帧或者乱序。
  • Command:协议命令,承载连接管理和数据交互的指令。
  • Data:有效数据,比如安全命令(STO、SS1)或状态反馈。

另外,FSoE还强制要求看门狗。一个安全连接建立之后,如果在一个设定的时间窗口内没有收到新的安全帧,通信就被判定为故障,安全输出立即进入停止状态。看门狗时间天然是冲突的:设太长,安全响应迟钝;设太短,正常通讯抖动可能误报。这个时间要结合总线的实际循环周期来定,后文会专门说。

3.3 驱动器安全功能:STO/SS1/SS2怎么映射

把FSoE接到伺服驱动器上,最终发挥作用的是一组安全子功能。最常用的三个:

  • STO(安全转矩关断):直接切断电机转矩输出,不会产生任何轴向力。相当于给驱动器“断电式”的急停,但保留控制电源通信。
  • SS1(安全停止1):先让电机按安全斜坡减速停止,速度降到阈值之后,再自动执行STO。适合需要受控停止的场景,避免自由滑行。
  • SS2(安全停止2):电机受控减速并停在目标位置,之后保持位置状态。相当于“安全保位”,比如设备排料时需要保持工作台位置。

这些安全功能在驱动器里的落地,不只是一句FSoE命令,还涉及到驱动器内部的硬件安全回路和固件安全模块。现场接线时,除了FSoE安全报文,还必须保留急停按钮、安全门锁这类硬接线安全回路。我的实际经验是:FSoE可以替代一部分安全硬接线,但不能完全替代所有安全硬回路,尤其是急停回路,该硬接还得硬接。软安全加硬安全双保险,才是设备安全的底线。

3.4 FSoE配置中的几个反直觉陷阱

我在刚开始配FSoE时踩过不少坑,写出来给各位提个醒:

连接ID必须成对匹配。主站里给某个从站分配的FSoE连接ID,必须和从站里配置的完全一致。两边不一致,握手阶段就会卡住,而且报错信息往往模棱两可。

看门狗时间别凭感觉填。我之前见过有人把看门狗填到1秒,理由是“怕抖动误报”,结果安全停止动作慢得一塌糊涂。比较合理的起点是“循环周期×3~5”,比如1ms周期就填3~5ms,调试时先放宽一点,确认正常工作后逐步减小,直到贴近实际通信抖动边界。

安全主站和安全从站的角色不能填反。配置界面里一般都要求指定设备角色,一旦反了,FSoE连接根本建立不起来。这些看似不起眼的配置项,往往是卡你一天的元凶。

4. 实战复盘:汇川H5U带24个IS660伺服轴的EtherCAT项目

4.1 先算负载账:网络带宽和轴数不是瓶颈,周期才是

网上有个流传度很高的参考案例,是汇川H5U带24个IS660系列伺服轴,跑EtherCAT通信,很多新手就是奔着这个配置入门的。我按这个方向做个复盘。

先算带宽账。每个轴按标准PDO算,RX方向8字节(控制字+目标位置),TX方向8字节(状态字+实际位置),24个轴就是384字节过程数据。加上EtherCAT帧头、子报文头、WKC等开销,一帧总长大概四百多字节。就算1ms周期,换算下来数据率也才几十Mbps,对100Mbps的EtherCAT来说留有大量余量。

所以24轴这个规模,网络带宽根本不是瓶颈,真正的瓶颈在主站PLC的周期任务调度。如果主站用250微秒周期带24轴,意味着每250微秒要处理一次全部轴的数据刷新和插补计算,CPU压力会非常大。对新手项目,我强烈建议从1ms或者2ms周期起步,先把功能跑通,再考虑缩短周期提升动态响应。

4.2 InoProShop里的轴配置与PDO映射

H5U是汇川的中型PLC,工程软件是InoProShop,内置EtherCAT主站组态功能。基本流程是:

  1. 新建工程,在“网络组态”里添加EtherCAT主站。
  2. 扫描总线上的从站设备。扫描前先把所有伺服轴的站号拨码拨开,一个一个分配,别一上来就全部挂上去,否则站号冲突会搞得你毫无头绪。
  3. 导入伺服轴的ESI文件。汇川伺服一般在安装软件目录里自带,找不到就去官网下。没有ESI文件,主站无法识别设备对象字典。
  4. 为每个轴设置工作模式,统一选CSP(周期同步位置模式)。
  5. 核对PDO映射。主站侧看到的PDO对象和顺序,必须和伺服侧一致。
  6. 设置循环周期、同步模式(建议DC同步)和看门狗参数。
  7. 编译、下载配置。

实测下来,最容易出错的环节就是PDO映射不一致。建议在伺服面板上先把PDO映射清空,然后用主站软件“写”配置到伺服,再回读校验,保证两侧完全同步。

4.3 CSP模式的同步调试步骤

24个轴全部执行CSP模式,调试时的操作顺序很关键:

  1. 单轴点动,确认每个轴的方向、电子齿轮比、编码器反馈正常。
  2. 单轴切CSP模式,给一个缓慢的目标位置斜坡,观察实际位置是否平稳跟随。
  3. 检查主站侧同步状态,确认每个轴的“实际位置-目标位置”误差都在可控范围,且没有周期性波动。
  4. 让1~2个轴做小范围联动,观察轴间配合,确认没有“一个轴到了、另一个轴还在走”的相位差。
  5. 逐步加快插补速度,重点看高速段跟随误差是否发散。
  6. 所有轴使能,做整机空载联动测试。

调试时如果发现某个轴在高速运行时抖动,先别急着调伺服增益,优先检查该轴的DC补偿值是否正确、网线长度是否超出规格、屏蔽层是否良好接地。我见过太多“调了半天下垂”的案例,最后发现就是网线质量差。

4.4 24轴项目调试验收的经验清单

项目调试验收时,我习惯做一张检查清单,逐项打勾:

  • 所有轴在设定周期内无掉站、无重传。
  • 各轴实际位置跟随误差在匀速段保持稳定,不随速度增大而明显发散。
  • DC同步误差在合理范围,主站软件里能看到所有轴误差数量级基本一致。
  • 总线负载率留有30%以上余量。
  • 24轴同时使能后,动力线无异常发热,总线屏蔽层无干扰波动。
  • FSoE连接(如果用了)在正常运行时无重连、无超时报警。
  • 急停回路和FSoE安全回路同时触发时,所有轴都能立即进入安全状态。

这个清单做完,项目才算有底。很多现场问题其实都发生在“看起来能跑,但没做满负荷联调”的阶段。

5. 常见问题速查:丢站、同步超差、FSoE报警

5.1 从站掉线:八成不是协议问题,先看这三处

“我轴怎么又掉了?”这是现场最常听到的一句话。EtherCAT从站掉线,绝大多数情况下不是协议本身的问题,而是物理链路的问题。

按优先级排查:

  • 站号和拨码:某两个轴的站号设重复了,主站扫描到的设备数量就会飘忽不定。
  • 供电:特别是多个轴同时使能瞬间,总线供电电压跌落会导致从站掉电重启。用万用表测一测从站端子的实际电压,别只看电源屏上的表。
  • 网线:屏蔽层破损、水晶头弹片断裂、线缆弯折半径太小,这些在现场都是常见的。看主站软件里每个从站的错误计数,能帮你快速定位是哪个链路片段出了问题。

排障技巧:把疑似有问题的网线换到另一个轴位,看故障是否“跟着网线走”。跟着走,就换线;不跟着走,查供电和从站硬件。比用万用表一根根量线方便得多。

5.2 伺服跟随误差大:从分布时钟下手

跟随误差大往往表现为:电机在匀速运动时,主站侧的实际位置一直追不上目标位置,或者误差呈周期性波动。这时候调伺服增益往往没用,因为问题出在“时钟”而不是“环”。

先确认主站和从站的循环周期是否一致。比如主站设1ms,从站侧DC配置却残留着默认的250us,同步基准一乱,跟随误差自然波动。再看参考时钟的选择:多个从站时,通常以第一个支持DC的从站为参考时钟,所有其他从站向它对齐。参考时钟选错,整个网络的同步都会乱。

另外,如果你用的是Windows平台软主站,还要检查网卡驱动是否优化过,普通驱动在系统调度抖动面前不堪一击。PLC内置主站一般没这个问题,但如果CPU被其它通讯任务占满,也会出现周期波动。

5.3 FSoE安全连接无法建立

FSoE连接建立失败,是最容易让新手崩溃的问题。按照序检查:

  1. 急停和安全门回路是否复位。很多安全PLC设计是“安全回路断开时不建立安全连接”,你按下急停之后,连接肯定起不来。先复位安全回路。
  2. 安全地址是否配对。主站配置的安全地址和从站实际地址必须一致。
  3. 连接ID是否一致。主站和从站两侧各自配置的ConnID必须成对匹配。
  4. 看门狗时间是否合理。太短会导致握手过程中就超时,一般先用较大的值把连接建起来,再逐步调优。
  5. CRC参数是否一致。如果主站和从站的CRC计算配置来自不同工具版本,要确认多项式、初始值和最终异或是否一致。

5.4 排查思路速查表

问题现象主要排查方向常用处理手段
从站偶尔掉站站号冲突、供电跌落、网线损坏核对站号、补供电、换线
轴高速抖动DC同步异常、PDO映射错位核对映射、校准DC参考
跟随误差发散同步周期不一致、负载过重统一周期、检查机械负载
FSoE建不上安全回路未复位、连接ID不匹配先复位急停,再逐项核对配置
从站编译告警指针转小整型查告警位置,确认转换值范围

我个人的体会是,EtherCAT这套东西,协议本身并不难理解,真正拉开差距的是配置细节和现场排查经验。从站开发、PDO映射、DC同步、FSoE安全连接,每一个环节都有它自己的脾气。新手入门,别想着一步到位上几千轴的安全项目,先把单轴CSP调顺,再逐步扩展到多轴联动和功能安全。顺序反了,你会被各种莫名其妙的“软故障”折磨到怀疑人生。

最后分享一个小技巧:不管用哪家主站软件,养成“改动前备份配置、改动后保存日志”的习惯。一天调试下来,对比前后版本,很多问题的答案其实就藏在配置差异里。

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

STM32嵌入式C++实战:从内存约束到Renode仿真

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

作者头像 李华
网站建设 2026/11/6 1:07:34

FPGA低功耗设计五大硬核技巧:时钟门控、格雷码、BRAM优化实战

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

作者头像 李华
网站建设 2026/11/6 1:07:12

嵌入式Linux驱动开发实战:从寄存器操作到中断管理

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

作者头像 李华
网站建设 2026/11/6 1:07:10

从直流电机到FOC:物理-数学-工程三线贯通的电机控制进阶路径

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

作者头像 李华
网站建设 2026/11/6 1:06:41

芯片逆向实战地图:从版图到固件提取的完整技术链路

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

作者头像 李华
网站建设 2026/11/6 1:05:51

智能车电路开源全解析:从电源管理到电机驱动的实战设计

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

作者头像 李华