news 2026/10/6 7:08:51

JET伺服限位信号刷入PLC:GXWORKS3配置与样例程序全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JET伺服限位信号刷入PLC:GXWORKS3配置与样例程序全解析

做运动控制这几年,限位信号这一环看似不起眼,但十次现场问题里起码有三次跟它有关。尤其是伺服本身带硬限位、PLC又要做逻辑联锁控的那种系统,限位状态能不能及时“刷”进PLC,直接决定设备是正常停机还是撞机。前阵子用三菱JET伺服配FX5U,在GXWORKS3里把限位信号刷新和软限位下发整套配置跑通后,我觉得这套流程值得单独写一篇,因为论坛上和文档里很少有把从硬件接线到参数刷新再到样例程序串起来讲的。这篇就按我的实际做法来拆,从限位信号怎么定义、JET伺服的通信刷新机制,到GXWORKS3的具体配置步骤,最后给出一段可直接参考的样例程序,覆盖从零到调试的完整链路。

先说结论:如果你想只用PLC的普通输入点去接伺服限位开关,然后靠程序里取反、互锁、延时去防撞机,这套做法不是不行,但响应速度和可靠性都不如把限位信号直接交给伺服驱动器处理,再把状态“刷”回PLC。JET伺服通过CC-Link IE TSN或者脉冲串加通信的方式,都能把驱动器内部已经处理过的限位状态、报警码、当前位置这些信息周期性映射到PLC软元件里,这才是工程上更稳的做法。

1. 项目背景:为什么伺服限位信号需要“刷”进PLC

1.1 限位信号的两层含义:硬限位与软限位

限位信号在伺服系统里其实分两层。第一层是硬件限位,就是设备行程两端装的那两个机械开关或接近开关,信号直接接到伺服驱动器的LSP和LSN端子。这层限位的本质是“最后一道物理防线”,由驱动器内部电路直接响应,不经过PLC,响应时间通常在毫秒级。第二层是软件限位,也就是在驱动器参数里设定一个最大行程范围,当编码器反馈的位置超出范围时,驱动器同样会报警停机。

很多刚接触的人会问:既然驱动器自己就能处理硬限位和软限位,为什么还要PLC去读?原因很实际:驱动器处理限位之后只是“停下来”,但PLC需要知道“为什么停”。比如设备在自动运行中突然停机,操作屏上要显示是正限位触发、负限位触发还是软限位超程;再比如系统回原点之后,限位开关的位置需要参与软限位的自动计算;还有手动寸动时,如果限位已经触发,PLC应当禁止该方向继续输出脉冲,否则就是驱动器和PLC双重保护都在,但没有协作,现场一样会出问题。

1.2 选择JET伺服与CC-Link IE TSN的理由

三菱JET伺服是当前通用伺服的主力系列之一,相比上一代JE系列,它把通信能力做成了标配项,尤其是支持CC-Link IE TSN的型号,一个网口既能跑运动控制又能跑普通I/O刷新,还能挂其他从站设备。对于中小型设备来说,这相当于把原来需要单独配置的定位模块、通信模块、I/O模块都省掉了,一台FX5U加几个JET伺服就能组成完整的多轴运动控制系统。

我这次选JET伺服的另一个原因是它和GXWORKS3的配合很顺。JET伺服从站添加到工程之后,GXWORKS3会按照CC-Link IE TSN的配置文件自动生成映射表,输入输出刷新区、远程寄存器区都可以直接在软件里拖拽配置,不需要手工去查每个地址的定义。限位信号、报警信号、到位信号、当前位置、当前转速这些信息,都能按照你想要的周期刷新到PLC的指定软元件区。这一点在调试阶段特别省心,改配置不用反复下载程序,在线修改刷新映射就能生效。

2. 硬件接线与驱动器参数准备

2.1 接线:从限位开关到驱动器的完整链路

硬件接线是整个项目的地基。JET伺服驱动器的标准限位输入端子是LSP(正方向限位)和LSN(负方向限位),和SON(伺服使能)、EM1(紧急停止)一样,默认情况下都是常闭(NC)逻辑。也就是说,端子上有24V信号时代表“正常”,信号断开才代表“触发限位”。这种设计逻辑其实很讲究:它考虑的是断线安全,如果限位开关的线断了,驱动器的表现等同于限位触发,设备会停下来,而不是带着断掉的限位线继续跑。

接线时用三线制NPN型接近开关是最常见的做法,棕色接24V正极,蓝色接0V,黑色信号线接到LSP或LSN端子,同时在信号线和0V之间并一个2.2kΩ左右的电阻做下拉偏置。这里需要特别提醒:如果现场用的是PNP型接近开关,输出是高电平有效,直接接到伺服端子上会和驱动器内部的光耦输入电路不匹配,导致限位状态始终是触发状态,怎么调参数都解决不了,只能换传感器或者加继电器转换。

另外,如果设备行程比较长,限位开关离驱动器有两三米远,信号线建议用屏蔽双绞线,屏蔽层单端接地。我遇到过一次现场干扰案例:限位信号线跟伺服动力线走在同一个线槽里,结果每次主轴一加速,PLC上就偶尔报一次限位触发,排查了很久才发现是动力线干扰了限位信号,把线分开之后问题彻底消失。

2.2 驱动器参数预设置(PA参数)

JET伺服的参数在接通电源之后需要通过面板或者GXWORKS3的伺服配置工具来设置。关键的几项如下:

  • PA01:控制模式,设置成位置控制(或者网络定位模式,取决于你用的是哪种通信方式)。如果用CC-Link IE TSN通信,这一步尤其重要,通信模式下驱动器要接收来自PLC的指令报文。
  • PA05-PA07:电子齿轮比,根据机械减速比和丝杠导程计算。比如5比1减速器配5m同步轮,线速度0.8米每秒这种场景,电子齿轮比设错会导致实际速度完全对不上。
  • PA10:LSP/LSN限位输入的有效逻辑,默认NC常闭即可。如果现场因为传感器类型问题需要改成NO常开,就在这里改。
  • 软限位相关参数:包括正方向软限位值、负方向软限位值、软限位无效区。软限位值要结合回原点后的机械坐标来设定,而不是随便填一个脉冲数。

设置这些参数时有一个经验:先断掉伺服使能再改参数,改完必须执行参数写入和软复位(断电重启一次更稳)。我见过不少人在驱动器运行状态下直接改参数,改完发现不生效,其实不是参数没写进去,而是没有让驱动器重新加载参数。

2.3 接线注意事项与常见坑

和伺服有关的接线,踩过的坑基本可以列成一份清单。首先是限位开关的电源,24V电源不能和伺服主电源共用同一个开关电源,至少要在限位回路前面加一个独立的断路器。原因是伺服电机启停时母线电流波动很大,如果限位开关和控制器的电源被拉低到18V以下,驱动器内部的输入电路会误判信号状态,轻则报警,重则直接撞机。

其次是LSP和LSN不要空接。如果某一方向确实没有硬限位,也要把对应的端子短接到24V,否则驱动器会一直认为该方向限位被触发。这一点在调试初期最容易忽略,设备一上电就报限位报警,查来查去发现根本不是开关问题,而是端子没接线。

第三是伺服使能和限位信号的上电时序。很多驱动器的说明书会写“先供控制电源,再供主电源”,但实际项目里控制电源往往和主电源一起合闸的。这种情况下,建议在主电路接触器旁边加一个时间继电器,让控制电源先稳定200毫秒左右再合主电,能避免相当一部分上电瞬间的报警误报。

3. GXWORKS3配置与刷新映射

3.1 创建工程与网络拓扑

GXWORKS3里新建工程的流程比较容易上手,但有几个细节要注意。导航窗口中选择“新建工程”,PLC系列选择FX5U,机型根据你的实际CPU型号来定,工程类型选“结构化工程”或者“简单工程”都可以,我习惯用简单工程加梯形图,做运动控制项目时梯形图更直观。

打开工程之后,第一步不是写程序,而是先配置网络。如果JET伺服是CC-Link IE TSN通信方式,需要在“CC-Link IE TSN配置”里点击“添加从站”,然后在设备列表里找到对应的JET伺服型号(比如MR-JET-G系列)。添加之后,软件会自动分配一个从站号,同时生成该从站的通信配置文件。这里要注意:从站号的分配必须和驱动器面板上实际设置的站号一致,不然通信建立不了。

网络配置界面的扫描周期和刷新模式也要提前想好。限位信号这类布尔量刷新周期可以设成1毫秒到4毫秒,位置数据或者需要实时性要求更高的数据可以单独指定高速刷新区域。很多人习惯把所有数据扔在一个刷新周期里,这会造成总线负载偏高,抖动也会变大。

3.2 添加JET伺服从站

GXWORKS3从站配置窗口打开后,最核心的操作是理解“对象”和“映射”两层概念。对象指的是伺服驱动器内部的数据项,比如“状态字1”、“报警代码”、“指令位置”、“当前位置”、“正限位信号标志”、“负限位信号标志”这些。映射指的是把对象数据连接到PLC侧的具体软元件,比如D100、M50、X100这些。

在分布式配置文件里,CC-Link IE TSN会划分出“远程输入输出刷新”和“远程寄存器刷新”两大类。JET伺服从站默认会有若干字(Word)的输入输出区域,输入方向(伺服到PLC)承载状态信息,输出方向(PLC到伺服)承载指令信息。GXWORKS3提供了一个映射表格界面,你可以在里面直接拖拽,把“正限位信号”拖到M50,把“当前位置”拖到D100-D101,保存后刷新映射就自动生成了。

这里要提醒一点:JET伺服的总线刷新数据是按字对齐的,布尔量也会占用一个字的位。所以你在映射表里看到限位信号可能和伺服ON状态、到位信号、零速信号等打包在同一个字的不同位里。修改映射时不要手动去改位偏移,尽量在GXWORKS3的表格里操作,否则很容易出现地址重叠,编译还不报错。

3.3 刷新参数映射:把限位状态放进PLC软元件

刷新参数映射是整篇攻略的核心,也是标题里“限位信号PLC刷新”的真正含义。PLC每经过一个刷新周期,会把伺服驱动器里最新的限位位状态读取到指定的软元件。

具体操作步骤可以这样走:

  1. 在“CC-Link IE TSN配置”里双击JET伺服从站,打开从站详细设置。
  2. 切换到“刷新映射”或“全局标签”页面,GXWORKS3会显示伺服对象的完整列表。
  3. 把“正限位信号”映射到M50,“负限位信号”映射到M51,“到位信号”映射到M52,“伺服准备好”映射到M53。
  4. 把“当前位置”映射到D100/D101(32位),把“当前转速”映射到D102/D103。
  5. 把“软限位正方向设定值”映射到D110/D111,把“软限位负方向设定值”映射到D112/D113,这样PLC运行中可以直接用MOV指令修改软限位值。

配置完成后,点击“应用”,GXWORKS3会自动生成一段设备初始化程序,这段程序在PLC启动时负责和JET伺服建立通信握手。注意不要把这段自动生成的程序删掉或者修改它的执行条件,否则上电后伺服会一直处于通信超时报警状态。

3.4 伺服参数写入的关键步骤

限位信号不仅要“读”,有时还要“写”,这就涉及伺服参数写入的流程。JET伺服的大部分参数既可以在驱动器面板上改,也可以通过CC-Link IE TSN由PLC远程写入。远程写入的价值在于:设备换型时不需要人跑到电柜前面按面板,直接在触摸屏上输入新的软限位值,PLC程序把它写到刷新区,伺服参数就自动更新了。

参数写入在GXWORKS3里通常分成两步:先写参数值,再触发参数存储命令。比如要把软限位正方向值改成500000脉冲,可以直接对映射的D110/D111写入数据,但这只是把数据送到了伺服对象的缓冲区,还没真正生效。要让参数生效,需要对某个控制字写入特定值,相当于发送“参数保存并生效”的命令。

具体控制字的值在JET伺服通信手册里有定义,常见操作是置位“参数请求位”,然后监测“参数执行完成位”上升沿,再复位“参数请求位”。如果程序里没有做这个完成握手,会导致连续写入时第一次成功、第二次失效,因为上一次的参数保存还没执行完。我在程序里专门用了一个子程序处理这个握手逻辑,效果很稳定。

4. PLC程序与样例实现

4.1 软元件规划

程序设计的第一步是软元件规划,这一步做得好,后面写梯形图就是填空。下面是我这次项目里实际用到的分配表,供参考:

软元件方向功能说明
M50输入正限位触发状态,1为正常
M51输入负限位触发状态,1为正常
M52输入定位完成/到位信号
M53输入伺服准备好信号
M54输入伺服报警信号
M60内部正限位触发锁存
M61内部负限位触发锁存
D100-D101输入当前位置(32位)
D102-D103输入当前转速(32位)
D110-D111输出软限位正方向设定值
D112-D113输出软限位负方向设定值
D120内部报警代码(伺服侧)
D130内部当前位置换算后的mm值

软元件规划的原则是:输入区和输出区尽量分开,中间锁存区单独用一组,避免程序一复杂就出现线圈重复输出。尤其是M50这种来自刷新区的输入点,千万不要在程序里对它用SET/RST指令,否则会破坏通信数据的实时刷新。

4.2 限位状态读取程序

限位状态读取程序其实很简单,因为GXWORKS3的刷新映射已经把状态搬进软元件了,新增IO模块程序里主要做的是保护和锁存。下面是一段参考梯形图逻辑,用指令语言描述:

// 限位触发锁存 LD M50 // 正限位正常信号,常开触点 ANI M60 // 如果已经触发过,锁存保持 OUT M60 // 锁存正限位触发事件 LD M51 // 负限位正常信号,常开触点 ANI M61 OUT M61 // 一旦伺服报警,同时闭锁正负方向脉冲输出 LD M54 // 伺服报警 OR M60 OR M61 OUT M70 // 禁止运动标志

这里体现了常闭信号的用法:M50为ON表示限位未触发,为OFF表示已触发。当限位信号断开时,M60被置位,M70输出禁止运动信号。这样即使PLC侧脉冲输出程序段没有对限位做判断,M70也能在总线上把运动指令封锁住,形成双重保护。

另外我在程序里加了一个限位恢复判断:当限位开关重新闭合,且操作员按下了复位按钮,M60和M61才允许被RST。这么做的原因是防止限位开关抖动或者人员误操作导致锁存标志闪动,影响设备重新启动。

4.3 软限位设定与报警复位程序

软限位设定程序利用前面映射好的D110-D113。实际设备换型时,操作员在触摸屏输入一个mm值,PLC程序先换算成脉冲数,再写入D110-D111。换算公式是:脉冲数 = 位移(mm) x 1000 / 每脉冲对应位移(μm)。

举个例子:伺服电机带5比1减速器,配5m20同步轮,同步轮周长200mm,那么电机转一圈负载走200 / 5 = 40mm。如果编码器分辨率是10000脉冲/圈,那么每个脉冲对应的位移就是40000μm / 10000 = 4μm,写程序时用4μm作为换算系数。你输入软限位500mm,对应的脉冲数就是500 x 1000 / 4 = 125000脉冲,这个数值直接MOV到D110-D111。

报警复位程序同样走通信区。伺服报警时M54会ON,PLC读取D120里的报警代码并在触摸屏上显示。操作员复位时,程序向控制字写入复位命令,等伺服返回报警清除完成标志后,再复位复位命令位。这里一定要加握手,否则复位命令发太快,伺服还没处理完就会被下一次扫描周期再次触发。

手动寸动方向互锁的程序段放在脉冲输出之前,核心逻辑是:

// 正方向寸动,禁止正限位触发时输出 LD X10 // 正方向寸动按钮 ANI M50 // 正限位未触发(M50为ON才是未触发) AND M70 // 无报警且无锁存 OUT Y10 // 正方向脉冲输出 // 负方向寸动,禁止负限位触发时输出 LD X11 ANI M51 AND M70 OUT Y11

这段程序的关键在于把限位状态判断放在脉冲输出的最前端,而不是只放在报警处理里。这样即使手动操作时,限位触发也能立刻切断输出方向。

4.4 测试步骤与验证方法

程序写完后,在真机上测试时我建议按下面的顺序做:

  • 第一步,空跑通信。PLC和伺服都上电但不使能,GXWORKS3在线监控M50-M54的状态,手动按限位开关,确认M50/M51能实时翻转。
  • 第二步,低速寸动。给伺服使能,用10%的默认速度手动寸动,跑到限位附近减速,确认限位触发后伺服立即停止且不报警。
  • 第三步,验证软限位。在触摸屏上设定一个小于硬限位的软限位值,比如让软限位先触法,确认PLC能读取到软限位超程报警。
  • 第四步,验证复位流程。触发报警后,按复位按钮,确认报警清除、M60/M61被复位、M70解除。
  • 第五步,满载跑一遍自动程序,同时用GXWORKS3的采样跟踪功能记录M50、M51、M70这几个点的波形,确认在极限位置处各信号的动作时序符合预期。

测试中最关键的一个指标是“限位触发到电机停止的总时间”。实测下来,JET伺服硬限位直接接入驱动器时,从触发到停止一般在几十毫秒内;而PLC通过刷新读取限位再发停止指令的路径会多一个通信周期,所以现场总时间会稍微长一点。这个特性决定了硬限位仍然是设备安全的第一道防线,PLC侧的限位读取和软限位判断是第二道防线,两者不能互相替代。

5. 现场调试常见问题实录

5.1 通信连不上怎么办

通信连不上这个问题在现场出现频率极高。我排查的思路通常是这样:先看CC-Link IE TSN配置文件里的从站号和实际驱动器面板显示的是否一致,这是最容易出错的地方;然后看GXWORKS3的设备列表里是否显示“从站状态正常”,如果显示“从站不存在”,基本可以判断是站号或网线问题。

网线方面,JET伺服的CC-Link IE TSN网口用的是工业以太网接口,不能用普通办公网线代替,至少要用超五类屏蔽网线,水晶头必须带金属外壳,压接工艺要规范。我碰到过几次通信时好时坏的情况,最后都是水晶头压接不牢导致的,重新压制之后问题立即消失。

另外还有一类情况是PLC配置下载后通信正常,但伺服侧一直报“通信超时”。这时候要检查PLC程序的运行状态,尤其是自动生成的初始化程序有没有被其他程序跳过或者复位。如果初始化程序没运行,伺服就在那里干等心跳包,自然报超时。

5.2 限位一直触发或者不触发

限位信号的表现和预期不一致时,先不要急着改程序,先去驱动器面板或者GXWORKS3监控界面看原始输入状态。如果是常闭逻辑,面板应该显示LSP/LSN为“正常”;如果你的限位开关是常开型,那面板显示的就是“触发”,这时要判断到底是接线问题还是参数问题。

常见情况有三种:一是传感器输出类型和驱动器不匹配,NPN传感器接了PNP输入的端子;二是传感器供电电压不足,限位开关指示灯看着亮,但实际输出电平不够,驱动器判断不了;三是端子接线松动,尤其是插簧端子使用时间长了之后,振动环境下容易虚接。

排查时我习惯用万用表直接测24V和信号线之间的电压,用手动按限位开关看电压是否在20V到24V之间切换。如果电压切换正常但PLC侧的M50不动,那问题就出在伺服映射配置上,回去检查刷新映射表。

5.3 参数刷新失败排查

软限位等参数通过通信写入时偶尔会失败,这个问题调试时也很隐蔽。排查时要分清是“写入失败”还是“写入后不生效”。写入失败通常是通信链路问题,比如正在写入时总线上有大流量数据碰撞,或者写入的数据长度和伺服对象定义的长度不匹配。写入后不生效则几乎都是握手时序问题,前面提到过的“参数请求位”完成后没有复位就发下一次请求,就会导致后续的参数更新全部被忽略。

我自己的做法是写一个参数写入子程序,用SM400(常开)作为扫描标志,内部用置位和复位来严格控制写参数流程:先置参数请求位,等待参数执行完成位上升沿,再复位参数请求位,最后延时一个扫描周期再允许下一次写入。这样虽然写一组参数需要多花几十毫秒,但可靠性高很多。

如果多次写入后还是不生效,可以尝试在GXWORKS3里通过在线伺服监视工具直接写入一次参数,再和PLC程序写入做对比。如果软件写能成功而程序写不成功,那就是程序的握手逻辑有问题,检查复位位置是否写正确。

5.4 干扰问题

最后说一下干扰。伺服系统是干扰源也是受害者,限位信号线的抗干扰能力一定要重视。项目落地时我建议限位线、编码器线、动力线分开走独立的线槽,间距至少保持20厘米以上。如果必须交叉,动力线从上跨过信号线,且交角尽量接近90度,能减小耦合。

遇到顽固干扰时,尝试在限位开关的信号线上加一个RC滤波器,或者在PLC输入侧加中间继电器隔离。我遇到过一次很奇怪的现象:设备一启动自动程序,M50偶尔会闪断一下,但不会触发报警。后来查出来是电磁接触器吸合瞬间的浪涌干扰,在接触器线圈两端并了RC吸收回路之后,现象彻底消失。干扰类问题往往不是单一措施能解决的,抗干扰要从接地、布线、滤波三个方面同时下手。

6. 一点个人经验

这套配置跑通之后,我最大的感受是:JET伺服加CC-Link IE TSN这种组合,把原来很多需要靠PLC程序“绕”的事情变成了配置项,限位信号的处理逻辑清晰了很多。但好处之外也有代价,那就是对配置人员的通信理解和从站对象熟悉程度要求更高了,出了问题不能再像以前那样只看梯形图就行,还得检查网络映射和从站状态。调试时建议准备一份从站映射表,把每个软元件对应的伺服对象和位定义打印出来放在手边,排查问题会快很多。最后再分享一个小技巧:每次修改完刷新映射后,把GXWORKS3生成的映射配置导出一份保存到项目文件夹里,设备交付后现场维护的人照着表查问题,能省下大量沟通成本。

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

Modbus寄存器数值解析:字节序、字序与数据类型的16种组合

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

作者头像 李华
网站建设 2026/10/6 7:08:23

PRBS在高速信号完整性测试中的核心原理与工程实践

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

作者头像 李华
网站建设 2026/10/6 7:06:26

Hirschmann RS20工业交换机配置实战:IP分配、环网RM与故障排查

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

作者头像 李华
网站建设 2026/10/6 7:06:26

新手四层板实战:从USB3.0扩展坞设计掌握信号完整性与电源完整性

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

作者头像 李华
网站建设 2026/10/6 7:06:25

通用脱机烧录器握手失败?CI-03下载协议与免唤醒参数解析

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

作者头像 李华
网站建设 2026/10/6 7:05:50

USB A/B系列连接器引脚定义、接线与调试全攻略

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

作者头像 李华