news 2026/10/17 1:13:37

基于MP2642GR-Z与STM32L162ZE的两串电池被动均衡BMS设计实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于MP2642GR-Z与STM32L162ZE的两串电池被动均衡BMS设计实战

1. 从两个串联电芯说起:为什么被动均衡在储能BMS里依然是主流选择

储能和备用电源系统里,电池组从来不是单节电芯在战斗。为了达到系统需要的电压和容量,工程师通常会把多节电芯串联起来使用。串联带来的一个经典问题就是:每节电芯的容量、内阻、自放电率不可能完全一致,充放电循环跑下来,电芯之间的电压差会越来越大。这个电压差如果不处理,木桶效应就会显现——容量最小的那节电芯先到截止电压,整组电池的可用容量就被它拖住了。

解决这个问题的思路分两大派:被动均衡和主动均衡。主动均衡用变压器、电感或者电容把能量从高电压电芯搬到低电压电芯,效率高、发热小,但电路复杂、成本高、控制逻辑也麻烦。被动均衡则是把高电压电芯的多余能量通过电阻消耗掉,简单、可靠、成本低。在储能和备用电源这类对成本敏感、对可靠性要求高、充放电倍率不高的场景里,被动均衡反而是更务实的选择。

这次要聊的方案,就是用MP2642GR-Z这颗均衡前端芯片,配合STM32L162ZE这颗低功耗MCU,对两个串联电池单元做均衡管理。MP2642GR-Z 是一颗专门为多节串联电池设计的均衡芯片,内部集成了均衡MOSFET和驱动电路,支持通过外部电阻设定均衡电流,还能通过寄存器读取每节电芯的电压状态。STM32L162ZE 则是ST的Cortex-M3低功耗系列,带LCD控制器、12位ADC、多个定时器和丰富的通信接口,在电池管理系统里做主机控制非常合适。

这套组合的核心价值在于:用一颗专用均衡芯片把模拟侧的活儿揽过去,MCU只需要通过I2C或者SPI接口发指令、读状态,软件负担轻,硬件设计也干净。对于两串电池这种小规模系统,既不需要复杂的多节级联,也不需要昂贵的主动均衡拓扑,MP2642GR-Z加STM32L162ZE的方案在成本和性能之间找到了一个很舒服的平衡点。

这篇文章会从芯片选型逻辑、硬件电路设计、寄存器配置、软件状态机、实测数据、常见问题排查几个维度展开,把两串电池被动均衡这件事讲透。不管你是刚接触BMS的新手,还是想从分立方案切换到专用芯片的老手,都能从里面找到可以直接抄作业的内容。

2. MP2642GR-Z 与 STM32L162ZE 的选型逻辑与硬件连接细节

2.1 为什么是 MP2642GR-Z 而不是分立MOS加电阻

很多人第一反应是:两串电池均衡,直接用两个MOSFET加两个功率电阻,MCU的GPIO控制不就行了?理论上没错,但实际做起来有几个坑。第一,分立方案的均衡电流完全取决于电阻和电芯电压,没有恒流控制,电芯电压高的时候电流大、发热大,电压低的时候电流小、均衡慢。第二,MOSFET的驱动需要电平匹配,两串电池的高端MOS驱动需要额外的电荷泵或者自举电路,增加元件数量和故障点。第三,没有电压监测,MCU还得额外配ADC分压采样电路,精度受电阻温漂影响大。

MP2642GR-Z 把这些活儿都集成进去了。它内部有精密的电压基准和ADC,能直接测量每节电芯的电压,精度可以做到毫伏级。均衡电流通过外部电阻设定,内部有恒流控制环路,电芯电压变化时均衡电流基本稳定。高端均衡MOS的驱动也集成在芯片里,不需要额外的自举电路。对于两串应用,一颗MP2642GR-Z就能覆盖,外围只需要几个电阻电容和均衡电阻,BOM非常干净。

从成本角度看,分立方案看似便宜,但算上精密电阻、MOSFET、驱动电路、PCB面积和调试时间,总成本未必比专用芯片低。而且专用芯片有完善的保护逻辑,过温、过流、电芯短路都能自动处理,可靠性高出一个档次。

2.2 STM32L162ZE 在BMS里的角色定位

STM32L162ZE 是一颗低功耗Cortex-M3,最高主频32MHz,带128KB Flash和16KB RAM,对于两串BMS来说资源绰绰有余。它在这个方案里的核心任务有三个:第一,通过I2C接口配置MP2642GR-Z的工作参数,比如均衡电流阈值、均衡使能、电压采样周期;第二,周期性读取MP2642GR-Z的电压寄存器和状态寄存器,判断是否需要启动均衡;第三,通过UART或者CAN把电池状态上报给上位机,同时驱动LCD或者LED做本地显示。

选L162ZE而不是更便宜的F0或者G0系列,主要看中它的低功耗表现和LCD控制器。储能和备用电源系统里,BMS本身往往需要长期在线,功耗越低越好。L162ZE在低功耗运行模式下电流可以做到微安级,配合MP2642GR-Z的休眠模式,整机待机功耗可以压得很低。另外L162ZE内置的LCD控制器可以直接驱动段码屏,省掉一颗显示驱动芯片,对于需要本地显示电压和状态的备用电源产品来说很实用。

2.3 硬件连接:I2C上拉、均衡电阻和采样滤波

MP2642GR-Z 和 STM32L162ZE 之间通过I2C通信,SCL和SDA需要接上拉电阻。上拉电阻的取值要看总线速度和总线电容,标准模式100kHz下,4.7kΩ是常见选择;快速模式400kHz下,2.2kΩ到3.3kΩ更合适。如果总线上只挂MP2642GR-Z一颗从机,电容很小,4.7kΩ完全够用。注意上拉电压要和MCU的IO电平一致,L162ZE是3.3V供电,上拉也接到3.3V。

均衡电阻的选择直接决定均衡电流。MP2642GR-Z的均衡电流公式通常是 I_bal = V_cell / R_bal 再乘以一个内部系数,具体要看数据手册的恒流设定。假设单节电芯电压3.7V,想要100mA的均衡电流,均衡电阻大概在33Ω到39Ω之间。但电阻的功率要算清楚:P = I² × R = 0.1² × 39 = 0.39W,所以至少要选1W的电阻,留足余量。实际布板时均衡电阻要远离温度敏感元件,最好放在板边或者加散热铜皮。

电芯电压采样线要从电芯正负极直接引到MP2642GR-Z的采样引脚,中间串一个小电阻(比如100Ω)做限流,再并一个0.1μF电容做滤波。这个RC滤波的截止频率大概在16kHz,能滤掉开关噪声但对直流电压没有影响。采样线的走线要尽量短,远离均衡电阻和功率走线,避免均衡电流在采样线上产生压降导致测量误差。如果电芯到BMS板的线比较长,最好用双绞线或者屏蔽线,减少干扰。

3. 寄存器配置与均衡策略:从阈值设定到状态机实现

3.1 MP2642GR-Z 关键寄存器速查

MP2642GR-Z 的寄存器大致分几类:配置寄存器、电压数据寄存器、状态寄存器和保护阈值寄存器。配置寄存器里最重要的是均衡使能位和均衡电流设定位。均衡使能位打开后,芯片才会在满足条件时启动均衡。均衡电流设定位通常有几位,对应不同的内部恒流档位,具体档位和外部电阻共同决定实际电流。

电压数据寄存器每个电芯一个,16位精度,读出来的原始值需要乘以一个LSB系数才是实际电压。这个系数在数据手册里会给出,比如1LSB = 0.5mV,那么读到的0x1D4C就是7500mV。状态寄存器里会有均衡进行中标志、过温标志、电芯过压欠压标志等,MCU读状态寄存器就能知道当前芯片在干什么、有没有异常。

保护阈值寄存器用来设定过压和欠压的门限。对于磷酸铁锂电芯,过压门限一般设3.65V,欠压门限设2.5V;对于三元锂电芯,过压设4.25V,欠压设2.8V。这些阈值要根据实际电芯的化学体系来定,设得太紧会频繁触发保护,设得太松起不到保护作用。

3.2 均衡启动条件的软件判断逻辑

被动均衡的启动条件不是简单的一句“电压高的就均衡”。实际做的时候要考虑几个因素。第一,电芯电压差要超过一个死区阈值,比如30mV,低于这个值不均衡,避免频繁开关。第二,电芯电压要在可均衡区间内,如果某节电芯已经过压了,应该先停止充电再均衡,而不是一边充一边放。第三,温度要在安全范围内,MP2642GR-Z内部有温度检测,但电芯本身的温度也要考虑,低温下均衡可能加剧析锂风险。

软件上可以用一个简单的状态机来实现。系统上电后先进入空闲状态,周期性读取两节电芯电压。如果电压差大于死区阈值,并且最高电压电芯没有过压,并且温度正常,就进入均衡状态,打开对应电芯的均衡使能位。均衡过程中继续监测电压,当电压差缩小到死区阈值以下,或者最高电压电芯降到均衡停止阈值以下,就关闭均衡,回到空闲状态。如果均衡过程中出现过温或者过压,立即关闭均衡并进入故障状态。

3.3 均衡电流与热管理的权衡

均衡电流选多大,是一个典型的权衡问题。电流大,均衡快,但发热也大。对于两串电池,如果容量是10Ah,电芯初始电压差100mV,想在一个小时内把电压差拉到10mV以内,需要多大的均衡电流?粗略估算,电压差90mV,电芯容量10Ah,假设电芯电压和SOC近似线性,那么需要转移的电荷量大约是10Ah × 90mV / 3.7V ≈ 0.24Ah。如果均衡电流100mA,需要2.4小时;如果均衡电流200mA,需要1.2小时。所以均衡电流的选择要和系统允许的均衡时间匹配。

发热方面,100mA均衡电流在39Ω电阻上产生0.39W热量,两节同时均衡就是0.78W。如果BMS板装在密闭外壳里,这个热量不容忽视。实测中可以用热成像仪看一下均衡电阻和MP2642GR-Z的温度,如果超过80℃就要考虑加大电阻功率、增加散热铜皮或者降低均衡电流。MP2642GR-Z内部有温度保护,结温超过一定值会自动关闭均衡,但最好还是在设计阶段就把热设计做好,不要依赖保护功能。

4. 软件实现:基于STM32L162ZE的均衡控制代码框架

4.1 I2C底层读写与MP2642GR-Z初始化

STM32L162ZE的I2C外设配置成标准模式或者快速模式,时钟频率100kHz或400kHz。初始化流程包括使能GPIO时钟和I2C时钟、配置GPIO为复用开漏模式、配置I2C时序寄存器、使能I2C外设。MP2642GR-Z的从机地址通常是7位地址,具体值看数据手册,比如0x0B或者0x0C。

初始化MP2642GR-Z的步骤:先读一遍设备ID寄存器确认通信正常,然后写配置寄存器设定均衡电流档位和使能位,再写保护阈值寄存器设定过压欠压门限,最后清一次状态寄存器。每一步写完最好回读验证,确保写入成功。I2C通信要有超时重试机制,如果连续几次读写失败,要报通信故障。

#include "stm32l1xx.h" #define MP2642_ADDR 0x0B #define MP2642_REG_CONFIG 0x01 #define MP2642_REG_VCELL1 0x02 #define MP2642_REG_VCELL2 0x03 #define MP2642_REG_STATUS 0x04 uint8_t MP2642_WriteReg(uint8_t reg, uint8_t data) { uint8_t buf[2] = {reg, data}; return I2C_Write(MP2642_ADDR, buf, 2); } uint8_t MP2642_ReadReg(uint8_t reg, uint8_t *data) { if (I2C_Write(MP2642_ADDR, &reg, 1) != 0) return 1; return I2C_Read(MP2642_ADDR, data, 1); } void MP2642_Init(void) { uint8_t id; MP2642_ReadReg(0x00, &id); // 设定均衡电流档位为100mA,使能均衡功能 MP2642_WriteReg(MP2642_REG_CONFIG, 0x05); // 设定过压门限3.65V,欠压门限2.5V MP2642_WriteReg(0x05, 0xE4); MP2642_WriteReg(0x06, 0x64); // 清除状态寄存器 MP2642_WriteReg(MP2642_REG_STATUS, 0x00); }

4.2 电压读取与均衡决策的周期任务

主循环里用一个定时器产生1秒的周期任务,在任务里读取两节电芯电压,计算电压差,然后根据状态机做均衡决策。电压读取要注意做滑动平均滤波,比如连续读5次取平均,滤掉偶发干扰。电压差计算用绝对值,然后和死区阈值比较。

均衡决策的状态机可以用一个枚举类型表示:IDLE、BALANCING、FAULT。IDLE状态下如果满足均衡条件就切到BALANCING,BALANCING状态下如果电压差缩小到停止阈值或者出现异常就切回IDLE或者FAULT。每次状态切换都要记录日志,方便后期分析。

typedef enum { STATE_IDLE, STATE_BALANCING, STATE_FAULT } BMS_State_t; BMS_State_t bms_state = STATE_IDLE; uint16_t cell1_mv, cell2_mv; uint16_t delta_mv; void BMS_PeriodicTask(void) { uint8_t raw[2]; uint16_t v1_sum = 0, v2_sum = 0; for (int i = 0; i < 5; i++) { MP2642_ReadReg(MP2642_REG_VCELL1, &raw[0]); MP2642_ReadReg(MP2642_REG_VCELL2, &raw[1]); v1_sum += raw[0] * 20; // 假设1LSB=20mV v2_sum += raw[1] * 20; } cell1_mv = v1_sum / 5; cell2_mv = v2_sum / 5; delta_mv = (cell1_mv > cell2_mv) ? (cell1_mv - cell2_mv) : (cell2_mv - cell1_mv); switch (bms_state) { case STATE_IDLE: if (delta_mv > 30 && cell1_mv < 3650 && cell2_mv < 3650) { if (cell1_mv > cell2_mv) { MP2642_WriteReg(MP2642_REG_CONFIG, 0x05 | 0x10); // 均衡电芯1 } else { MP2642_WriteReg(MP2642_REG_CONFIG, 0x05 | 0x20); // 均衡电芯2 } bms_state = STATE_BALANCING; } break; case STATE_BALANCING: if (delta_mv < 10) { MP2642_WriteReg(MP2642_REG_CONFIG, 0x05); bms_state = STATE_IDLE; } break; case STATE_FAULT: MP2642_WriteReg(MP2642_REG_CONFIG, 0x00); break; } }

4.3 故障处理与低功耗休眠策略

故障处理要覆盖通信故障、过温、过压、欠压几种情况。通信故障通过I2C重试次数判断,连续3次失败就报故障。过温和过压欠压通过读MP2642GR-Z的状态寄存器判断。进入故障状态后,先关闭均衡,然后根据故障类型决定是等待恢复还是永久锁定。过温通常是可恢复的,温度降下来后可以自动回到空闲状态;过压欠压要看系统策略,如果是充电过程中过压,应该通知充电器停止充电。

低功耗策略方面,STM32L162ZE可以在空闲时进入Stop模式,用RTC或者外部中断唤醒。MP2642GR-Z也有休眠模式,通过写配置寄存器进入。系统待机时,MCU进入Stop模式,MP2642GR-Z进入休眠,整机功耗可以降到几十微安。唤醒后先重新初始化MP2642GR-Z,再恢复周期任务。注意休眠前要确保均衡已经关闭,否则休眠期间均衡还在跑,功耗降不下来。

5. 实测数据与常见问题排查记录

5.1 两串磷酸铁锂电芯均衡实测

用两节标称3.2V/10Ah的磷酸铁锂电芯串联,初始电压分别是3.35V和3.28V,电压差70mV。设定均衡电流100mA,死区阈值30mV,停止阈值10mV。实测数据如下:

时间(min)电芯1电压(mV)电芯2电压(mV)电压差(mV)状态
03350328070均衡电芯1
153342328557均衡电芯1
303335329045均衡电芯1
453328329533均衡电芯1
603322330022均衡电芯1
753318330513均衡电芯1
90331533087停止均衡

从数据看,90分钟把70mV的电压差拉到7mV,均衡速度符合预期。均衡过程中电芯1电压缓慢下降,电芯2电压缓慢上升,这是因为均衡电阻消耗电芯1的能量,同时电芯2通过串联回路有轻微充电效应。实际均衡电流用电流探头测下来在95mA到105mA之间波动,恒流效果不错。

5.2 均衡电阻发热与温升测试

均衡电阻选用39Ω/1W的贴片电阻,两节同时均衡时总功耗约0.78W。在25℃环境温度下,用热成像仪测电阻表面温度,稳定后在65℃左右,MP2642GR-Z芯片表面温度在55℃左右。如果环境温度升到45℃,电阻表面温度会到85℃左右,接近电阻的降额上限。所以如果产品要在高温环境下工作,建议把均衡电阻换成2W的,或者降低均衡电流到70mA。

注意:均衡电阻的功率降额很重要。1W的电阻在70℃以上环境里实际能承受的功率可能只有0.5W到0.6W,如果按满功率设计,长期运行容易失效。建议按实际功耗的2倍以上选功率。

5.3 I2C通信失败与电压采样异常的排查链路

调试过程中遇到过一次I2C通信时好时坏的问题。排查过程如下:先用示波器看SCL和SDA波形,发现SDA上升沿有明显台阶,判断是上拉电阻太大导致上升时间过长。原来用的是10kΩ上拉,换成4.7kΩ后波形明显改善,通信稳定。这个问题的根因是总线电容加上大上拉电阻导致RC时间常数过大,400kHz下上升时间超过了规格要求。

还有一次电压采样值跳动很大,读数在±50mV范围内波动。排查发现采样线的滤波电容虚焊,重新焊接后读数稳定在±5mV以内。另外均衡电阻的走线和采样线平行走了一段,均衡电流在采样线上感应出噪声,把采样线改道远离均衡电阻后问题解决。这两个问题都是PCB布局和焊接质量导致的,提醒我们在调试时不要只盯着软件,硬件细节往往才是罪魁祸首。

6. 从两串到多串:方案扩展与设计边界

6.1 多节级联时的架构变化

两串方案跑通后,如果要扩展到四串或者更多串,架构上要做调整。MP2642GR-Z本身支持多节级联,多颗芯片可以通过菊花链或者I2C多地址的方式挂在同一总线上。STM32L162ZE的I2C总线可以挂多颗MP2642GR-Z,每颗分配不同的从机地址。软件上要把电压读取和均衡决策从两节扩展到N节,状态机也要相应调整,比如均衡时只均衡电压最高的那节,而不是简单比较高两节。

多串系统的均衡策略更复杂,因为电压差可能出现在任意两节之间。常见的做法是找出最高电压电芯和最低电压电芯,只均衡最高电压电芯,直到它降到和次高电压电芯接近,再重新排序。这样每次只均衡一节,热管理简单,但均衡总时间会变长。另一种做法是同时均衡所有高于平均电压的电芯,速度快但发热集中。具体选哪种要看系统的热设计能力和均衡时间要求。

6.2 主动均衡与被动均衡的边界条件

被动均衡的适用边界很明确:均衡电流小、系统成本敏感、充放电倍率低、对能量效率要求不高。储能和备用电源系统基本都落在这个范围内。但如果系统要求快速均衡、或者电芯容量很大导致被动均衡时间不可接受、或者对发热极其敏感,就要考虑主动均衡。主动均衡的典型场景是电动汽车和需要大电流充放电的系统,那些场景下被动均衡的电阻发热和均衡速度都满足不了要求。

从两串被动均衡切换到主动均衡,硬件上要换成电感或者变压器拓扑,软件上要控制PWM和电流采样,复杂度上升一个数量级。对于大多数储能和备用电源产品,被动均衡加合理的电芯分选,已经能把电压差控制在可接受范围内。电芯分选做得好,初始电压差小,被动均衡的压力就小,这是最经济的做法。

6.3 电芯分选与均衡策略的配合

很多人把均衡当成万能药,觉得只要均衡做得好,电芯一致性差一点没关系。这个想法很危险。均衡只能解决使用过程中产生的电压差,解决不了电芯本身容量和内阻的差异。如果两节电芯容量差10%,均衡把电压拉平了,但放电时容量小的那节还是会先到欠压保护点。所以电芯分选是基础,均衡是补充。

分选时重点看容量、内阻和自放电率三个参数。容量差控制在2%以内,内阻差控制在5%以内,自放电率差控制在每月2%以内,这样的电芯配组后,被动均衡完全能维持电压差在合理范围。如果分选条件达不到,就要考虑加大均衡电流或者缩短均衡周期,但这些都是治标不治本。我在实际项目中见过因为电芯分选不到位,均衡电阻长期满负荷工作,最后电阻烧毁的案例。所以均衡设计再好的方案,也架不住电芯本身差异太大。

7. 写在最后:几个容易忽略的实操细节

MP2642GR-Z的均衡使能位在写入后不是立即生效的,芯片内部有一个状态机切换过程,大概需要几十毫秒。如果写完立刻读状态寄存器,可能读到的还是旧状态。建议写完均衡使能后延时50ms再读状态,或者用中断方式等芯片的完成信号。

STM32L162ZE的I2C外设在低功耗模式下会关闭,唤醒后需要重新初始化。如果系统频繁在运行和休眠之间切换,I2C初始化的开销不能忽略。可以考虑用GPIO模拟I2C,在休眠时保持引脚状态,唤醒后直接通信,省掉初始化时间。

均衡电阻的布局要远离温度传感器和电压基准源。均衡电阻发热会导致局部温升,如果温度传感器离得近,测到的温度会偏高,触发误保护。电压基准源受温度影响会导致电压采样漂移,虽然MP2642GR-Z内部基准温漂很小,但外部电阻分压网络如果靠近热源,分压比会变化,影响测量精度。

最后一点,均衡功能在出厂前一定要做老化测试。至少跑24小时连续均衡,观察电阻温度、芯片温度和电压采样稳定性。有些问题在短时间测试里看不出来,比如电阻的长期温漂、焊点的高温老化,只有跑够时间才能暴露。我自己的习惯是老化测试至少48小时,中间记录温度曲线和电压曲线,确认没有异常再批量生产。

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

面试官视角:新手面试官如何化解面试尴尬与提升沟通效率

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

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

BeautifulSoup入门:Python爬虫解析HTML与提取数据实战

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

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

Vensim DSS 5.6a 安装激活与系统动力学批量建模实战指南

简介&#xff1a;Vensim DSS 5.6a 是一款面向系统动力学研究者、政策分析人员及高校教学用户的成熟数据建模工具&#xff0c;专用于构建、仿真与分析含反馈机制的复杂动态系统&#xff0c;广泛适用于经济演化、环境承载力评估、公共卫生策略推演等场景。资源包为完整可安装版本…

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

FPN特征金字塔网络:从原理到实战的多尺度目标检测详解

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

作者头像 李华
网站建设 2026/10/17 1:10:36

2串锂电池主动均衡方案:MP2642GR-Z与PIC18LF45K22协同设计

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

作者头像 李华
网站建设 2026/10/17 1:10:15

tkinter文件拖拽完整解决方案:tkinterdnd2安装、实现与打包避坑

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

作者头像 李华