news 2026/10/24 4:59:54

PIC18F4680与PCA9422协同实现多路电源时序与故障监控

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PIC18F4680与PCA9422协同实现多路电源时序与故障监控

嵌入式设备做到一定复杂度,电源方案就不再是“选个 DCDC、接几个电容”就能糊弄过去的事情。多路电压轨、上电时序、过压欠压保护、远程状态上报,每一项都会变成实际问题。我最近在整理一个控制板项目,主控用的是 PIC18F4680,前端电源交给 PCA9422 这颗多通道 PMIC,整套系统基本做到了“上电有序、运行可控、故障可查”。这篇就围绕这个组合,把从硬件连接到软件配置、从调试到量产的完整思路写一写,给正在纠结电源管理架构的朋友一个参考。

先说结论:如果你的项目只是单路 5V 转 3.3V,老老实实用一颗 LDO 或者 DCDC 就好,没必要上 MCU 加 PMIC。但如果你手里有五六路电压轨,还要控制时序和监控故障,那 MCU 加可编程 PMIC 的组合就非常合适。PCA9422 这类芯片把多路 DCDC/LDO、时序控制、保护逻辑集成在一起,PIC18F4680 则负责用 I2C 去配置、读取、响应中断,两者各管一段,职责非常清楚。

1. 项目整体思路与方案拆解

1.1 核心需求:完整电源管理到底在管什么

“完整电源管理”这几个字听起来很空,落到项目里其实是几件非常具体的事。

第一是电压轨的数量和精度。常见嵌入式系统至少需要 5V、3.3V、1.8V、1.2V 这类电源,模拟前端可能还要独立的 3.3V 或 2.5V 稳压,数字核和 IO 供电有时甚至要求 1% 以内的偏差。每一路都用一个独立电源芯片,原理图会变得很庞大,而且很难统一做保护和监控。

第二是上电时序。很多处理器和外设对电源轨的启动顺序很敏感,比如核心电压必须先于 IO 电压,或者某路电压稳定之后再过几百毫秒才能开启另一路。用分立器件做延时电路也能实现,但改起来特别麻烦。用可编程 PMIC 的好处是时序参数可以写在寄存器里,硬件调试时无需改板子。

第三是故障监控和恢复。电源不是只要输出正常就行,还要能发现过流、过压、欠压、过温这些异常,并且把这些状态告诉主控。PIC18F4680 本身有 ADC 和中断输入,但直接采样每一路电压需要很多引脚,而且没法快速感知 PMIC 内部的故障。把监控放在 PMIC 里,MCU 定期读取状态寄存器,是最经济的方式。

第四是低功耗和动态行为。设备在不同运行阶段需要的功耗不一样,比如待机时关掉大功率外设电源,运行时再把电压提上去。如果 MCU 能通过 I2C 控制 PMIC 的通道开关和输出电压,就可以实现“按需供电”,而不是让所有电压轨一直白白耗电。

所以,标题里那“完整”两个字,指的不是把电源做得有多豪华,而是要覆盖生成、时序、监控、保护、调度这一整套闭环。

1.2 方案选型:为什么是 PCA9422 + PIC18F4680

选择 PCA9422 而不是普通 DCDC,最主要的原因是可配置性和集成度。这类 PMIC 内部通常包含多路降压转换器和 LDO,并且有一组寄存器用来设定输出电压、开关时序、软启动斜率、限流点甚至故障响应策略。只要用 I2C 或 SPI 写入配置,就能在很大范围内调整电源行为。对于原型阶段经常改参数的项目,这种灵活性非常宝贵。

PIC18F4680 这边,看中的是它的外设搭配。它自带 MSSP 模块,可以作为 I2C 主设备直接操作 PMIC 的寄存器,解决控制通路的问题;又有多通道 10 位 ADC,可以独立回采几路关键电压做交叉校验;再加上 CAN 硬件模块,如果需要把电源状态发送到总线上,比如车载或者分布式工业控制场景,这颗 MCU 可以直接完成,不需要额外接一颗协议芯片。

整套组合的界线很清晰:PCA9422 负责“电源业务”,PIC18F4680 负责“管理业务”。硬件上只有 I2C、使能、中断、电源四组连接,软件上 MCU 不会陷进复杂的电源环路设计,PMIC 也不需要理解整个系统在跑什么业务逻辑。

1.3 系统架构里各个角色的职责

先画一个简单的逻辑架构:外部输入电源(比如 12V 或者电池)进 PCA9422 的输入引脚,PMIC 内部经过通道配置输出多路电压,供给 MCU、传感器、通信模块等负载。PIC18F4680 的 I2C 引脚接 PMIC 的 I2C 从机端口,GPIO 接 PMIC 的 EN 引脚和中断输出引脚,ADC 再引几路采样电阻来监测关键电压。整个系统的决策链是这样的:PMIC 产生电源并检测自身异常,一旦发生故障就把中断引脚拉低,MCU 被触发后读取状态寄存器,明确是哪一路出了问题,再决定是尝试恢复还是直接关机告警。

这套架构还有一个隐藏优势:如果 PMIC 的中断引脚接到 PIC18F4680 的外部中断输入,那么 MCU 平时可以进入休眠状态,不需要轮询电源状态。真正出现电压跌落或者过流时,PMIC 会通过中断把 MCU 唤醒,既保证了响应速度,又降低了待机功耗。这一点在小电流电池供电的设备里特别有用。

2. 硬件设计与关键连接

2.1 电源链路与参数选择

做硬件设计时,先别急着看软件、写代码,把电源链路算清楚再动手。我这里拿一个典型的项目场景做例子:输入是 12V 直流,系统需要 3.3V 给主控,5V 给传感器和通信模块,还要一路 1.8V 给某个数字模块。PCA9422 内部对应通道会承担不同的输出。

选择输出电容时,一般按每输出 1A 配 10uF 到 22uF 的 X7R 或 X5R 陶瓷电容,放在芯片输出引脚附近。容量太小,瞬态响应会差;容量太大,软启动时充电电流会过大,可能触发 PMIC 的限流保护。比如 3.3V 输出按 500mA 峰值电流算,输出电容用 22uF 是稳妥的,1.8V 输出功耗小,用 10uF 就够。输入电容要更大一些,因为在多路负载同时切换时,输入电压容易跌落,我用的是 47uF 加一个 0.1uF 高频去耦电容。

电感的选择要关注饱和电流。DCDC 通道的电感饱和电流最好留 30% 以上的裕量,比如实际负载最大 500mA,电感的饱和电流最好在 750mA 以上。曾经遇到过电感选小了,负载一上来电感就饱和,输出纹波变得非常难看,而且电感还会啸叫。

注意:PMIC 的输出电压和限流值,不要只看芯片手册里“最大能输出多少”,还要结合自己的负载变化率一起评估。动态负载的启动电流往往比稳态电流高一截,硬件上留出裕量,软件上也要设计好软启动。

2.2 I2C 接口连接与上拉电阻

PIC18F4680 的 MSSP 模块可以工作在 I2C 主模式,与 PCA9422 的 I2C 从机接口连接。连接本身很简单:SCL 接 SCL,SDA 接 SDA,两边共地,然后加 I2C 总线上拉电阻。上拉电阻的选择不能随便来,我一般先用 4.7kΩ,总线速度快不起来的时候再改为 2.2kΩ。

如果 MCU 和 PMIC 的 IO 电平不一致,比如 MCU 是 3.3V IO,PMIC 那边是 1.8V IO,就必须加电平转换或者确认双方是否兼容。PCA9422 这类 PMIC 的 I2C 电平通常会在数据手册里写清楚,设计时最好留一个电平转换芯片的位置,等确认实验板没问题后再决定法拉不焊。

另一个容易被忽略的是地址引脚。PMIC 的 I2C 地址一般由 ADDR/SEL 引脚的电平决定。硬件上接上拉或下拉后,软件里要先确定实际地址,再写死到通信代码里。如果 PCB 上这个引脚悬空,默认电平往往不是你想要的地址,第一轮调试就会栽在通信上。

2.3 使能、中断与复位逻辑

PMIC 的 EN 引脚是总开关,我用 PIC18F4680 的一个 GPIO 控制。为什么要用 GPIO 控制而不直接接输入电源?因为这样可以实现“软开关”:MCU 先跑起来,再决定是否开启 PMIC 输出。如果 PMIC 默认上电就输出,MCU 可能还没运行,负载就已经被供电,某些负载可能在没有初始化完成时出现不确定状态。

中断引脚 INT 连接 PIC18F4680 的外部中断输入,触发方式应设置为下降沿触发。PMIC 检测到故障时通常会把 INT 拉低,MCU 从休眠中唤醒后去读状态寄存器。这里要特别注意:中断是事件触发,不是状态触发,所以在中断里应该快速读取状态并做一次“清中断”动作,否则相同的故障会反复触发。

复位逻辑上,我给 PMIC 的中断输出和使能控制都加了 RC 延时或缓冲,避免 MCU 上电期间 GPIO 状态不稳定,导致 PMIC 被误开或误关。PIC18F4680 的 GPIO 在上电瞬间是输入状态,外部控制脚的默认电平必须靠上下拉电阻保证。

2.4 PCB 布局中的几个重点

布局决定成败。DCDC 开关节点的高频噪声非常容易串到 I2C 信号线上,一旦 I2C 通信被干扰,读取电压配置就会得到乱值。

第一,PCA9422 的输入电容要尽量靠近芯片电源引脚,输出电感下面不要铺大面积的信号参考层,减少开关噪声对地平面的污染。第二,I2C 的 SDA 和 SCL 走线尽量短,最好相邻走线中间夹一根地线,或者至少保持平行且靠近地参考层。我一开始图省事,把 I2C 走线在板子上绕了大半圈,结果 100kHz 工作正常,400kHz 一开就跑飞,后来才发现是走线过长且离电感太近。第三,如果要回采输出电压,ADC 的分压电阻要放在负载端取样,直接量 PMIC 输出端和负载端会有差异,尤其是大电流路径上有明显压降的话。

提示:能用一个完整的地平面就尽量用。PMIC 的多种输出电压轨如果回流路径不干净,会出现奇怪的两个地之间有电位差的问题,轻则 ADC 读数不准,重则烧逻辑。

3. 软件驱动与实操流程

3.1 底层 I2C 通信函数

写软件时,先做一组可靠的 I2C 读写原语,不要一上来就写业务逻辑。PIC18F4680 的 MSSP 模块用库函数或者直接操作寄存器都行,我这里给出一个基于寄存器的简化思路。

uint8_t pca9422_write_reg(uint8_t device_addr, uint8_t reg_addr, uint8_t data) { // 发送起始条件 // 发送 device_addr << 1 | 0 (写标志) // 等待 SSPIF 置位,检查 ACK // 发送 reg_addr,等待 ACK // 发送 data,等待 ACK // 发送停止条件 // 返回成功或失败 }

代码看起来简单,但有几个容易出错的地方。第一,每一次发送字节后都要等待 MSSP 的中断标志位,并检查 ACK 状态,如果从机没有应答就继续发,会导致总线挂死。第二,重复一些寄存器写入时,最好加一个小的延时,尤其是 PMIC 内部 EEPROM 或者配置加载期间,写太快会丢数据。第三,错误处理不应该是清一下标志就完事,还要考虑总线恢复:连续 9 个 SCL 时钟脉冲可以帮忙解除 SDA 被拉死的状态,这个逻辑可以放在重试函数里。

I2C 时钟速度方面,我习惯先用 100kHz 调试,稳定后再改到 400kHz。波特率由 MSSP 的 SSPADD 寄存器决定,以系统时钟 8MHz、目标频率 400kHz 算,理论值是 Fosc 除以 4 倍再减 1,也就是SSPADD = 8MHz / (4 * 400kHz) - 1 = 4。但实际还要考虑上升沿时间和线上电容,我经常会设成 4 或者 5,再拿示波器看实际波形,保证满足时序要求。

3.2 初始化与输出电压配置

初始化 PMIC 的顺序,我总结成一句:先确认通信,再确认身份,最后才写配置。

上电后 MCU 先调用pca9422_read_id(),读取芯片 ID 寄存器,确认 I2C 地址和通信链路都没问题。如果读到 0xFF 或者 0x00,说明 SDA/SCL 可能有接触问题、上拉不对或者地址不对,这时候不要继续往下写,先把问题解决掉。

接下来配置各通道输出电压。PCA9422 的电压配置寄存器一般是一路一个字节,其中低几位是电压索引,高几位可能还有使能位或模式选择。我这里用一个表列出示例配置:

通道目标电压寄存器配置值(示例)说明
VOUT13.3V0x1A主控电源,软启动时间较长
VOUT25.0V0x2C传感器电源,限流点略高
VOUT31.8V0x0F数字核心,电压精度要求高

注意,上面这些数值不是给你直接抄的,不同批次、不同型号定义不一样,必须对着手头数据手册找。我见过有人直接把另一个项目的寄存器值移植过来,结果输出电压高了 0.4V,后级芯片直接冒烟。

配置写完之后,还有一个关键步骤:回读验证。写进去再读出来,跟期望值比对一次。很多 PMIC 寄存器写一次不一定马上生效,可能需要等内部 LDO 稳定之后才能读回真实值。

3.3 上电时序控制的实现

PCA9422 这类 PMIC 一般会提供可编程延时,比如 VOUT1 使能后延时 5ms 再使能 VOUT2。寄存器里通常会有seq_delay或startup_delay之类的位,配置方式是把延时档位写到某个寄存器。

不过,软件上也不能完全把时序甩给 PMIC。MCU 需要知道每一个电源轨什么时候就绪。我的做法是:使能 PMIC 输出之后,不要立刻初始化外设,而是利用一个 GPIO 或者 PMIC 的 Power Good 状态来等待稳定。如果 PMIC 有 PGOOD 引脚,直接接到 MCU 的另一个 GPIO;如果只有状态位,那就轮询状态寄存器直到对应位置位。

这里要提一个坑:不要把 Power Good 当成“电压已经稳定”的绝对依据。它更多是芯片内部比较器判断的结果,从比较器到 MCU 读取之间还有延迟,所以重要外设的复位释放时间要额外加一点余量。比如 Power Good 已经置位,我再加 2ms 延时才释放传感器的复位引脚,这样稳妥很多。

3.4 状态监控与故障处理

运行时要做的不是反复读所有电压寄存器,而是依靠中断和状态寄存器配合。

主循环里可以只定期核对两个状态:全局 status 寄存器有没有非零错误位,当前工作模式是否正常。如果发现异常,再按位解析是哪一路故障。PIC18F4680 的中断服务程序里,可以设置一个power_fault_flag,主循环发现标志后调用故障处理函数,不推荐在中断里做长时间处理。

故障处理函数至少要做这些事:读到状态寄存器;区分过流、过压、欠压、过温;如果是瞬态过流,可以尝试重新使能对应通道;如果连续重启几次都失败,就不要再反复尝试,直接进入保护状态,把 LED 或者蜂鸣器拉响,同时保存故障代码到 EEPROM。

PIC18F4680 自带 EEPROM,不用外挂存储,这个优势在电源故障记录上很好用。我做过一个设备,每次故障重启后蜂鸣器叫一声,用户也不知道是哪种问题;后来把故障码写进 EEPROM,现场维护人员通过通信接口读出来,问题定位快了很多。

4. 低功耗运行与动态电源调度

4.1 低功耗模式的设计思路

电池供电的设备,最关心的往往不是极限性能,而是待机能耗。MCU 进入休眠只是其中一部分,PMIC 的负载才是大头。如果几个外设电源轨在待机时仍然开着,那待机电流依然降不下去。

低功耗设计的第一步,是把 PMIC 的通道按照系统状态分组。比如通信模块算一组,传感器算一组,核心主控算一组。在待机状态下,关闭通信模块和传感器的电源轨,只保留主控电源和实时时钟电源。PIC18F4680 在休眠前通过 I2C 写 PMIC 对应通道的使能寄存器,把不需要的通道关掉。

第二步,MCU 进入 SLEEP 指令前,要确认 PMIC 的中断引脚仍然接到外部唤醒源上。否则用户按键或者外部设备发来唤醒信号时,主控还在睡。PCA9422 如果有关键电压跌落,也会通过 INT 引脚唤醒主控,这是系统最后一道防线。

4.2 动态调整输出电压

有些模块在不同工作模式下对电压要求不同。比如射频模块发射时可能需要 3.3V,接收时可以降到 2.8V 来节能。这种动态调压可以通过 I2C 修改 PMIC 对应通道的输出电压寄存器实现。

但要注意,动态调压不能一步切台。如果一下子从 3.3V 改到 2.8V,负载端可能来不及适应,而且输出电容的充放电电流对 PMIC 内部环路也是个扰动。我一般会分几步调整,先写一个中间档,延时几毫秒,再写目标档,必要时配合 MCU 工作频率一起降。

这里有一个工程经验:动态调压前,先看看该通道有没有“transient response”或者“slew rate”相关的寄存器。有的 PMIC 可以设置压摆率,专门用来控制输出电压变化速率。如果硬件上不支持,那就靠软件多写几步实现软切。

4.3 掉电保存与快速保护

系统掉电时,PMIC 的输入电压会下降,之后各通道输出电压跟着跌落。如果主控还在写 Flash 或者保存关键参数,半路断电会让数据损坏。常规做法是把 PMIC 的输入电压检测引脚接到一个比较阈值,一旦检测到输入低于阈值,迅速产生中断,MCU 利用输出大电容里残余的电荷,在几十毫秒内完成关键数据保存。

PIC18F4680 内置 EEPROM,写一个字节大概是几毫秒,足够保存几百字节的状态。硬件设计时最好在 PMIC 输入侧放一个较大的储能电容,这样掉电后还能维持主控运行一段时间。我实际测过,10uF 的输入电容在 12V 输入掉电后维持不了几毫秒,至少要用 100uF 铝电解或者超级电容才能保证写入时间。

5. 常见问题与排查技巧实录

5.1 I2C 读写全是 0xFF 或 0x00

这是最常遇到的第一个问题。原因通常是几个简单但对新手很隐蔽的地方。

先检查设备地址。PMIC 的地址引脚如果接法不对,读出来的地址就跟数据手册不一样。我习惯写一个小函数扫描 0x00 到 0x7F 所有地址,然后打印出哪几个地址有 ACK 应答,就能快速确认实际地址。第二查 SDA/SCL 是否反接,很多 PCB 布局为了绕线方便会故意交叉,但 I2C 不允许 SDA/SDA 混着接,逻辑分析仪一看波形就能发现。第三查上拉电阻,没有上拉电阻的话,总线空闲时 SDA 和 SCL 都可能被芯片内部拉到一个不确定电平,通信自然失败。

5.2 上电时序导致后级反复重启

如果一个系统上电后一直重启,先把输出纹波和电源轨上电波形抓出来看。我遇到过 PMIC 默认输出顺序跟后级需求正好相反,导致后级芯片先供电后复位,逻辑混乱。解决办法是利用 PMIC 的时序配置把目标顺序显式写死。

还有一个常见原因是过流保护误触发。空载的时候一切正常,接上负载后某一路启动电流超过 PMIC 限流点,PMIC 自动关断输出又迅速重启,形成循环。排查时最好断开负载,先让 PMIC 空载启动,观察每一路电压,再逐步接负载。如果确认是限流问题,调整限流寄存器或者把对应通道的软启动时间调长。

5.3 输出纹波偏大和开关噪声干扰

纹波大不一定就是电容少。我遇到过电感选型不当导致饱和,输出纹波从 20mV 变成 100mV,换了一颗饱和电流更大的电感之后明显改善。排查手段是先看开关节点波形,再量输出电压纹波。如果开关节点波形边缘有过冲,要查电感电容的寄生参数和 PCB 走线;如果开关节点波形没问题但输出纹波大,重点查输出电容的 ESR 和反馈取样点。

I2C 通信被干扰也是类似情况。如果只有在某个电源通道开启后通信才报错,大概率是 PCB 上 DCDC 开关噪声耦合到了 I2C 线上。解决方法是调整布局,或者给 I2C 走线做包地,再不行就把 I2C 速率从 400kHz 降回 100kHz,稳定性优先。

5.4 PMIC 默认寄存器值让 MCU 为难

很多 PMIC 出厂配置不一定适合你的系统。比如默认电压、默认使能状态可能都不是你想要的,而 MCU 必须自己先跑起来才有能力去重新配置 PMIC。这时就出现一个“鸡生蛋”的问题:MCU 的电源也需要 PMIC 输出,但 PMIC 又默认输出了一组并不合适的电压。

解决思路有两个方向。一是选择支持出厂配置烧写的 PMIC,通过配套工具把量产配置烧进去,上电就按你的要求跑。二是硬件上做兼容设计,把 MCU 这一路电源单独用一个小 LDO 供电,确保 MCU 在任何情况下都能启动,再让 MCU 去初始化 PMIC。我比较推荐第二种,不仅调试方便,量产也少了一个配置依赖。

5.5 把数据手册变成自己的“查错表”

最后分享一个我自己养成的习惯:把 PCA9422 数据手册里的寄存器映射、位定义、默认值和状态位整理成一张速查表,打印出来放在工位上。每次调试出问题,先从状态寄存器开始查,再对照速查表找可能影响的配置项,比反复翻几百页 PDF 高效得多。

我在实际项目里踩过几次坑之后,最大的体会是:电源管理不是把 PMIC 接上、抄几个初始化代码就结束了,真正花时间的往往是硬件布局、时序细节和故障恢复逻辑。PCA9422 和 PIC18F4680 这套组合,胜在把“电源本身”和“电源管理”拆成了两个可以独立迭代的部分——硬件工程师可以专心调 PMIC 的电性能,软件工程师只需要通过 I2C 操作寄存器,两边都不会被对方的复杂性拖住。如果你正在做一个有多路电源轨、有严格时序要求、又希望把电源状态纳入整机监控的项目,这个思路可以直接拿过去当起点。

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

操作系统四大特征详解:并发共享虚拟异步的关系链

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

作者头像 李华
网站建设 2026/10/24 4:57:39

图像质量三要素:对比度、直方图与标准差的协同判据

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

作者头像 李华
网站建设 2026/10/24 4:56:49

PCA9422与PIC18F47K40的可穿戴电源管理方案

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

作者头像 李华
网站建设 2026/10/24 4:54:00

网络流量分析器源码拆解:抓包、协议解析与会话重组

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

作者头像 李华
网站建设 2026/10/24 4:52:51

PMIC+MCU协同实现低功耗动态电源管理:从硬件设计到固件实战

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

作者头像 李华
网站建设 2026/10/24 4:52:32

电动车控制器C语言源码解析:霍尔采样与PWM调速实战

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

作者头像 李华