news 2026/10/24 3:28:41

基于PCA9422与STM32的电源管理方案设计与实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于PCA9422与STM32的电源管理方案设计与实现

平时做便携设备的朋友应该都有这种感觉:系统功能越来越复杂,电池、屏幕、射频、传感器各要各的电压,如果全靠分离的DCDC和LDO去搭,板子面积大、调试麻烦不说,上电时序和功耗管理也容易出问题。所以现在越来越多的项目开始引入PMIC(电源管理IC),配合一颗MCU去做统一的电源调度。前阵子我基于PCA9422和STM32F405RG做了一套完整的电源管理方案,从硬件连接、驱动配置到充放电管理和低功耗切换都跑通了,这篇文章把整个设计和踩坑过程记录下来,给打算自己搭电源管理系统的朋友做个参考。

这套方案的核心价值在于:PCA9422负责把电池或外部输入转成多路稳定的电源轨,STM32F405RG则通过I2C接口实时监控和配置PCA9422的各路输出、充电参数和保护阈值,两者配合能实现从硬件稳压到软件调度的完整闭环。适合正在做手持终端、便携仪器、低功耗IoT设备,或者想给自己的板子加一套可靠电源管理逻辑的开发者。

1. 整体设计与选型思路

1.1 为什么电源管理要MCU参与

很多人一开始会问:PMIC本身不是能自己工作吗,为什么还要加一颗STM32去管?这个问题的答案,取决于你对“电源管理”的定义。如果只是上电出电压,那PCA9422上电默认配置确实够用了,但完整的电源管理意味着充电电流可配置、输出电压可动态调整、各路负载的电流要能监控、异常状态要能报警,这些都需要一个控制器去实时调度。PCA9422是一颗带I2C接口的PMIC,内部集成了充电管理、多路DCDC/LDO输出和丰富的状态寄存器,正好和MCU形成配合。

这套方案里,STM32F405RG扮演的角色不是简单的“读寄存器”,而是整个电源策略的执行者。开机时通过I2C配置PCA9422的输出电压和限流值,运行时周期性读取电压、电流、温度寄存器判断系统状态,在低功耗模式下可以关闭不需要的电源轨,充电过程中还要根据电池电压动态调整充电参数。MCU让电源系统从“固定输出”变成了“可编程、可监控、可诊断”的智能子系统。

1.2 选型比较:PCA9422和STM32F405RG为什么搭

选PCA9422这颗PMIC,首先是看中了它的集成度。我以前用过分离方案的电源系统,一颗充电芯片加三四个DCDC加LDO,加起来七八颗芯片,布板的时候电源部分占了很大面积。PCA9422把充电管理、多路输出和保护逻辑集成在一颗芯片内,外围只需要少量电感电容,对板面积紧张的便携产品非常友好。另外它支持I2C动态配置,输出电压和电流限制都能在软件层面调整,这给低功耗设计留了很大的灵活性。

至于主控为什么选STM32F405RG,主要是看重它的外设资源和功耗表现。F405RG的主频有168MHz,在内核处理完业务逻辑之后,还能留出充足的资源去跑电源管理任务;它带了多个I2C外设和ADC通道,既可以直接驱动PMIC,也能用内部ADC去采集电池电压和负载电流。它的Stop模式功耗很低,配合PMIC的电源轨裁剪,整机待机电流能做到比较理想的水平。如果项目原本就是在ST生态里开发,选这颗芯片几乎不需要额外学习成本。

1.3 “完整电源管理”包含哪些关键环节

一个真正完整的电源管理系统,绝不只是给板子供电这么简单。我在做这套方案时,把整个系统拆成了五个关键环节,缺一不可:

  • 电源路径管理:外部适配器插入时同时给电池充电和系统供电,适配器拔掉后无缝切换到电池供电,不能出现瞬间掉电。
  • 多路电压轨输出:数字核心、外设、传感器、通信模块各需要不同的电压,输出必须稳定,带载能力要足够。
  • 动态调压:在运行态和低功耗态之间切换时,通过I2C调整某些电源轨的电压,降低功耗。
  • 状态监控与保护:过流、过压、过温时PMIC要能自己保护,同时通过中断通知MCU做软件层面的处理。
  • 低功耗联动:MCU进入Stop模式前,主动关闭非必要电源轨,休眠时保持最低功耗,唤醒后再恢复。

PCA9422在这五个环节里覆盖了硬件层的大部分职责,STM32F405RG则负责“什么时候调压、什么时候断轨、什么时候报警、什么时候恢复”这套决策逻辑。后续的内容,我会从硬件接法、软件驱动、充放电逻辑和调试排查四个维度分别展开。

2. 硬件连接与PCB布局的实操经验

2.1 核心连接拓扑

PCA9422和STM32F405RG的硬件连接并不复杂,核心就四类信号:I2C通信、中断通知、电源路径和电池检测。先把连接拓扑理清楚,后面写软件才不会乱。

I2C部分是整个控制链路的基础。STM32F405RG的I2C1用于和PCA9422通信,SDA和SCL分别接PMIC对应引脚,两个信号线上各加一个4.7k欧姆上拉电阻到VDD。上拉电阻这一步不能省,PCA9422的I2C接口是开漏输出,不加上拉的话通信时序会不稳。I2C总线上如果没有其他从设备,地址可以固定由PMIC的ADDR引脚电平决定,硬件设计时直接通过上拉或下拉确定地址,避免和其他设备冲突。

INT中断引脚接到STM32F405RG的一个EXTI输入端,这里建议选一个支持任意GPIO映射的外部中断引脚。PCA9422在充电完成、充电异常、输入电源插入、过流保护动作等事件发生时都会拉低INT脚,MCU收到中断后再通过I2C读状态寄存器判断具体事件。这个机制比MCU定时轮询省电得多,低功耗场景下非常重要。

电池检测部分,PCA9422本身有电池电压检测引脚,MCU这边通过电阻分压把电池电压降到ADC可测范围,做双保险的电压监测。注意分压电阻阻值选大一点,一般各取100k以上,否则待机时漏电不可忽略。我在第一版硬件里贪图方便用了10k分压,实测待机电流多出来接近0.3mA,对电池供电设备来说这个量很可观,后来改成100k/100k分压才解决。

2.2 电源轨分配和负载规划

PCA9422的负载能力不是每条轨都一样的,做电源轨分配前必须先看数据手册里各路输出的最大电流。我这次设计了四条主要电源轨,分配思路可以参考一下:

  • 数字核心供电路:1.2V输出,带MCU内核和主控数字部分,峰值电流约0.8A,这是整板最重的负载。
  • IO和外设供电路:3.3V输出,给传感器、外部存储和接口电平转换供电,带载约0.3A。
  • 射频模块供电路:3.3V独立轨,给无线通信模块供电。这里单独拉一路不是因为它电流大,而是射频时隙发射会引起明显的电压毛刺,如果和传感器共用一路,毛刺会通过电源轨串扰到模拟采集,所以我特意让PCA9422这路输出的开关频率和布局都做了隔离。
  • 常备供电路:1.8V输出,给RTC和唤醒逻辑供电,这条轨在整机休眠时也不关闭。

分配电源轨时一定要把“哪些轨可以断电”和“哪些轨必须常供电”分清楚。RTC、唤醒按键检测、PMIC的关键控制电路属于常供部分,其余外设全部放在可断电的轨上,这样休眠时才能真正把功耗降下来。

2.3 PCB布局的实战教训

电源板的PCB布局,讲究的是“功率回路短、模拟信号远”。我前后打样了三版,总结几条比较实用的经验。

电感的位置非常关键。PCA9422的开关电源电感不要放在板边,否则边缘发射的噪声会干扰旁边天线的灵敏度,我在第一版里为了省空间把电感放在了板边,后来整机无线灵敏度测试掉了好几个dB,搬回板内才恢复。电感的摆放方向也要注意,同一个电源芯片的多个电感最好相互垂直,避免磁场耦合。输出电容要尽量靠近PMIC的输出引脚,缩短高频环路面积,这样输出电压纹波才会更干净。

I2C和中断信号线建议包地处理,特别是I2C走线不要和电源开关节点走平行线。我遇到过一版I2C数据偶尔被干扰拉死的情况,追查了很久发现是SCL走线和大电流开关节点过长平行,产生耦合干扰。后来把I2C信号线改到内层并用GND包围,问题就消失了。GND过孔在PMIC底部区域要多打几个,这不仅是为了散热,也是降低地弹的关键,地弹会让ADC采样噪声变大,影响电池电压检测的准确度。

3. 软件驱动与核心逻辑实现

3.1 驱动架构:把PMIC操作封装成独立模块

写驱动之前,我先把整个电源管理模块在STM32工程里做了清晰的层级划分。最底层是硬件抽象层,管I2C读写和中断引脚操作;中间层是PCA9422的驱动层,封装了寄存器读写和设备初始化;最上层是电源策略层,负责充放电管理、电源轨切换、状态监控这些业务逻辑。这样做的好处是:如果后续要换PMIC型号,只需要重写中间层,上层策略代码不用大动。

I2C读写函数是驱动的基础,建议直接基于STM32标准库或HAL库封装一层。需要注意的一点是,I2C通信失败的处理不能简单返回错误就完事,因为PMIC在异常状态下可能暂不响应。我在驱动层加了重试机制,连续读失败三次才向上层报错,效果比单次读失败直接跳错要好得多。底层代码结构大致是这样:

typedef struct { I2C_HandleTypeDef *hi2c; uint8_t dev_addr; uint8_t retry_cnt; } pmic_handle_t; uint8_t pmic_read_reg(pmic_handle_t *dev, uint8_t reg, uint8_t *val) { uint8_t retry = 0; HAL_StatusTypeDef status; do { status = HAL_I2C_Mem_Read(dev->hi2c, dev->dev_addr, reg, I2C_MEMADD_SIZE_8BIT, val, 1, 50); retry++; } while (status != HAL_OK && retry < dev->retry_cnt); return (status == HAL_OK) ? 0 : 1; }

这个封装虽然简单,但把HAL库返回状态和重试逻辑统一收敛了,后面所有寄存器操作都走这两条读写函数。驱动要好用,底层先得稳。

3.2 初始化时序:为什么不能一上电就写寄存器

初始化这部分我踩过一个很实在的坑:控制芯片和PMIC的上电时间要配合好,否则I2C通信会超时失败。PCA9422的VDD建立到自己启动完成需要一点时间,如果STM32复位后立刻就去读PMIC寄存器,大概率读到0xFF或者通信无响应。

我的做法是在电源管理模块初始化之前,先做一次延时等待,让PMIC完成内部上电复位。实际操作时用了一个简单的电平检测思路:先把INT引脚配置为输入,读取它的电平状态,PMIC上电复位过程中INT处于确定状态,等它拉高进入正常状态后再开始I2C通信。复位后延时200ms再初始化,这块地方加个超时保护,如果多次检测还是准备未完成就要给出错误指示。

初始化流程的顺序也很讲究,建议按照下面的步骤来:

uint8_t pmic_init(pmic_handle_t *dev) { // 1. 等待PMIC复位完成,INT引脚准备就绪 if (wait_pmic_int_ready(200) != 0) { return PMIC_ERR_TIMEOUT; } // 2. 读取芯片ID,确认真实存在且版本匹配 uint8_t chip_id = 0; if (pmic_read_reg(dev, PMIC_REG_ID, &chip_id) != 0 || chip_id != EXPECTED_ID) { return PMIC_ERR_CHIP_ID; } // 3. 配置各路输出电压和限流值 pmic_write_reg(dev, PMIC_REG_BUCK1_CFG, BUCK1_1V2_CFG); pmic_write_reg(dev, PMIC_REG_BUCK2_CFG, BUCK2_3V3_CFG); pmic_write_reg(dev, PMIC_REG_LDO1_CFG, LDO1_1V8_CFG); // 4. 配置充电参数(充电电压、充电电流等) pmic_config_charge(dev, CHARGE_V_4_2V, CHARGE_I_500MA); // 5. 配置中断屏蔽寄存器,使能关心的中断源 pmic_write_reg(dev, PMIC_REG_INT_MASK, INT_EN_CHARGE_DONE | INT_EN_INSERT); // 6. 软件复位或使能输出,进入正常工作状态 pmic_write_reg(dev, PMIC_REG_CTRL, PMIC_CTRL_ENABLE_ALL); return PMIC_OK; }

读芯片ID这步一定要放在配置前面,这是判断I2C通信链路是否正常、正确的关键动作。我遇到过硬件连错引脚导致I2C时序完全异常,通过读ID返回错误快速定位,比盲目调后面的参数省时间得多。

3.3 充放电管理策略

充放电管理是这个方案里业务逻辑最重的部分。PCA9422内部集成充电控制,MCU要做的不是直接控制充电电流的PWM波形,而是通过寄存器设置充电参数并监控充电状态。

充电配置主要涉及三个参数:充电电压、充电电流和截止电流。以单节锂电为例,充电目标电压设为4.2V,充电电流根据适配器功率和电池容量动态选择,我试过500mA和1A两档,最终方案里固定用500mA。截止电流设的是充电电流的1/10左右,也就是50mA——当充电电流跌到50mA就认为电池基本充满。这些参数不是固定的,实际项目里要根据电池规格书调整。

充电状态机是整个流程的核心,我把逻辑整理成四个状态:预充电、恒流充电、恒压充电和充满维护。状态迁移条件如下:

  • 预充电:电池电压低于2.9V时,先以1/10的设定电流慢充,把电池电压抬到安全范围。
  • 恒流充电:电池电压超过2.9V后,以设定电流恒流充,电压逐渐升高。
  • 恒压充电:电池电压达到4.2V后,维持电压不变,电流逐渐下降。
  • 充满维护:电流跌到截止电流后,进入充满状态,MCU收到中断后更新电量显示和充电指示。

代码里,MCU通过读取PMIC的状态寄存器获取当前充电状态,同时用ADC采集电池电压做交叉验证。状态机的每一次迁移都要记录时间戳,调试时通过串口打印状态迁移日志,很容易看出充电流程是否按预期走。配好状态机之后,充电部分基本不用频繁干预,PCA9422自己会处理大部分保护逻辑,MCU只在关键节点响应中断。

3.4 电量监测和精度心得

电量显示是电源管理方案里最容易让人头疼的部分。直接读电池电压然后查表估算电量,简单是简单,但误差很大,电池放电过程中电压的平台期很长,充满和放空的电压差只有很小一段,直接线性映射电量会非常不准。

我的方案是开路电压法和电流积分法结合。先说开路电压法:电池静置较长时间后电压和电量有比较好的对应关系,适合开机时校准初始电量。电流积分法则在运行过程中累加充放电电量,适合短时动态估算。具体逻辑为:

void battery_soc_update(uint32_t delta_ma_ms) { int32_t delta_ma = (int32_t)(delta_ma_ms / 1000); g_soc_mah -= delta_ma; // 放电为负,充电为正 if (g_soc_mah <= 0) { g_soc_mah = 0; } if (g_soc_mah > g_design_capacity) { g_soc_mah = g_design_capacity; } g_soc_percent = (uint8_t)((g_soc_mah * 100) / g_design_capacity); }

每次充满电时把累计电量重置为设计容量值,这样就消除了积分漂移。实际使用中,我在开机时先通过开路电压法估算初始电量,然后切换到电流积分模式,每个完整充放周期结束都做一次校准。这套组合方案用下来,电量显示误差能控制在5%以内。

还有个提升ADC采样精度的细节:电池电压采样引脚加RC滤波器,时间常数取1ms左右,抑制输出电压纹波。采样时我做了16次取平均,同时把ADC采样结果做一阶低通滤波,这样显示出来的电量数字不会在充放电时跳来跳去,用户体验好很多。

3.5 低功耗模式切换

低功耗是这个方案最出彩的地方。整机运行态和休眠态的电流差距非常大,实现的关键就在“断电隔离”和“时钟降速”两件事上。

进入休眠前,MCU按顺序做三件事:先把当前运行状态和上下文保存好,主动关闭非必要外设的电源轨,然后配置PCA9422关闭对应通道,最后进入Stop模式。这里要注意顺序:一定是先关闭外设电源轨,再让MCU进入Stop模式,否则MCU进入休眠后就没有人再去关电源了。唤醒方式我做了两种:RTC定时唤醒和外部按键中断唤醒。RTC报警时MCU从Stop模式唤醒,第一件事就是重新使能之前关闭的电源轨,然后恢复上下文。

电源轨动态切换时还要注意负载的浪涌。某个外设轨从关闭到开启的瞬间,输出电容充电会拉一下输入电流,如果输入电源路径配置不当可能触发PMIC的输入限流保护。所以我在使能电源轨前先做100ms的延时,等输入电压稳定再开负载较重的通道,这个细节让我少调了很多问题。

实测下来,这套系统休眠态整机电流能到50uA左右,相对于运行时几百毫安的电流,整整降了四个数量级。对于电池供电的便携设备来说,这个数值已经可以支持很长的待机时间了。

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

4.1 I2C通信不稳、偶发超时

I2C通信是这套方案里最脆弱的环节,问题表现五花八门:有时候上电读不到设备、有时候跑着跑着通信超时、有时候读写数据偶尔出错。排查时我按频率从高到低检查,总结成一张速查表供参考:

  • 先量SDA和SCL波形,看有没有上拉。示波器看空闲电平是否被拉高,没上拉的话波形边沿会特别缓,通信时序直接失效。
  • 检查I2C总线电容。PCA9422和STM32引脚距离较远、走线过长时总线电容过大,通信速率就要降档,I2C时钟从400kHz降到100kHz往往就稳定了。
  • 检查地址设置。ADDR引脚电平决定地址,硬件做了上下拉的话要确认和代码里的地址一致,不一致时通信表现为“无应答”。
  • 最后检查软件层面的重试机制。这个之前提过,驱动里做好三次重试,可以吸收大部分瞬时毛刺。

通信问题最诡异的是运行时偶尔死锁。后来我用逻辑分析仪抓了几次,发现SCL线在一种极端情况下被PMIC拉低,总线一直占用不释放。这种情况只能靠软件做超时复位,我在I2C错误处理里加了总线复位逻辑:连续多次失败就切换SCL引脚为普通GPIO翻转几个时钟周期,把总线骗出来,再重新初始化I2C外设。

4.2 输出电压偏低、带载能力不足

有朋友按参考设计画板后说某路输出电压只有标称的80%,带载以后还会往下掉。这种问题第一怀疑对象是电感选型。PCA9422这类PMIC的电感感值和工作频率是配套的,感值太小的纹波大,太大的瞬态响应差。我遇到过BOM里电感参数替换成一颗感值奇高的,结果带载时电压直接拉垮。换回规格书推荐的参数后问题消失。

输出电容容值不足也会导致带载电压跌落。轻载时输出电容还好,一旦负载电流出现大的阶跃,电容储能不够瞬间就会被拉低。我的经验是输出电容至少要选择规格书推荐电容的二倍容量,同时用MLCC电容时要注意直流偏压特性——小封装的电容在较高电压下实际容量会大幅缩水,这一条特别坑人。

还有一个容易被忽略的因素:PMIC芯片的散热焊盘没有正确接地。开关电源芯片底部的大焊盘不接地,芯片自身温度会快速升高,过温保护启动后会限制输出电流,带载能力直接崩掉。如果是高密度板子,检查一下焊盘下方过孔和地平面的连接,热量路径越短,带载越可靠。

4.3 电池充电不满、充电时间异常

充电充不满的问题,我排查方向通常分两类:一类是电池本身的问题,另一类是配置和保护参数的问题。

电池侧最常见的情况是电池进入保护状态后电压为零,充电流程认为电池异常直接拒绝充电。这个时候要根据电池规格书判断是否允许强制恢复,如果能,先把充电电压设成较小的值,小电流预充一段时间重建电池电压,再恢复标准充电流程,切记不要让电池电压反向接错。

配置侧的坑主要是充电电压和电池规约不匹配。有次我把目标充电电压设成4.35V给一个4.2V的电池充电,电池电压到4.2V之后还要继续往上充,充电时间大幅拉长,而且始终无法正常进入结束阶段。后来按电池规格改回4.2V就正常了。充电温度保护也值得注意:低温环境下锂电池不允许大电流充电,夏天在户外设备晒了很久、电池温度比较高时,充电也会被暂停。如果设备充电断断续续,先看温度寄存器是不是触发了温度保护限制。

4.4 低功耗电流降不下去

整机待机电流偏大是低功耗项目最头疼的问题。我调试时手里常备一个精确到微安级的电流表,通过“二分排除法”定位耗电模块:先把所有外设轨都关闭,看基础电流,然后一路一路独立打开,找到电流异常的模块。

最容易忽略的耗电点有三个:一个是GPIO浮空输入,引脚悬空时内部电流路径会形成额外的漏电通道,所有未使用的引脚一律配置成模拟输入或下拉输出;二是I2C上拉电阻,之前提到的4.7k上拉在休眠时一直通着电,如果VDD没有完全切断,上拉电阻会持续漏电;三是PCB上的分压电阻,电池电压采样分压电路如果不做开关控制,100k对地分压也会有微安级持续电流。我最后把分压电阻换成MOS管控制的采样开关,需要读电压时才打开,待机电流又降了一截。

5. 最后再分享几个实践心得

这套方案我前后调了两周,最深的体会是:电源管理项目的问题往往不是单点问题,而是硬件、软件、外围器件三者的耦合结果。单独查代码看不出毛病,单独量波形也看不出毛病,必须把PMIC的寄存器状态、硬件波形和电源轨行为放在一起对比分析,才能快速定位。我建议所有做类似项目的朋友,一开始就把串口日志设计好,充电状态变化、中断事件、I2C错误重试都要打出来,后期排查问题会非常省时间。

还有个心得是关于中断处理。PCA9422的中断脚是电平触发还是边沿触发,要看具体芯片行为,我这次用的是低电平有效,MCU进入中断服务程序后第一件事就是通过I2C读状态寄存器并清除中断源。如果中断服务程序里读了寄存器但没正确清除,INT脚会一直拉低,MCU会反复进中断,系统表现就是跑一会儿就卡死。遇到这种情况先查中断清除流程,这个坑我印象很深。

如果后续想在这个方案上继续扩展,我建议可以把电量管理和外设电源策略做成参数化配置,不同产品型号只需要修改配置表,不用改代码逻辑。另外可以引入状态机日志记录,把每次电源状态迁移都存下来,通过上位机工具分析功耗曲线,对调优很有帮助。这套方案的完整代码和原理图设计,我整理一下之后会分享出来,到时候有问题可以直接对照参考。

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

明日方舟MAA自动化助手:从配置到多账号管理的完整指南

/* 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 3:25:28

PCA9422与PIC32MX470F512H的便携设备电源管理系统设计

/* 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 3:23:57

极简导航页实战:用状态管理构建个人数字工作流

/* 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 3:22:14

Visual Studio中scanf报错C4996详解:原因与四大解决方案

/* 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 3:22:14

libuv源码分析:DNS异步解析与线程池实现原理

/* 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 3:21:07

全双工LoRa反向散射:一台网关简化部署,解决自干扰难题

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

作者头像 李华