首页/新闻资讯/正文详情

AD9361 FIR滤波器群延迟优化:5个实战技巧解决宽带信号EVM恶化

发布时间:2026/9/25 5:16:24 来源:云帆数科 栏目:资讯中心
AD9361 FIR滤波器群延迟优化:5个实战技巧解决宽带信号EVM恶化
1. 群延迟为什么会在AD9361链路上变成“隐形杀手”做AD9361基带调试的人十有八九都经历过这样的场景频谱仪上看发射信号EVM看着还行星座图也没散得太离谱但一跑高阶QAM或者宽带信号误码率就是压不下去。排查了一圈从时钟、电源、增益分配一路查到接口时序最后发现罪魁祸首是群延迟不平坦——不同频率分量在链路里走的“路程”不一样宽带信号到达接收端时波形已经被“揉”变形了。群延迟这个概念说白了就是相位对频率的导数。一个理想的线性相位滤波器群延迟是一条水平直线所有频率分量延迟相同时间波形形状不变。但实际FIR滤波器很难做到全频带线性相位尤其是当你在AD9361的发射或接收通道里塞进一个用来做通道均衡或者抗混叠的FIR时如果只盯着幅频响应看相位响应往往被忽略群延迟就在带内出现了起伏。这个起伏对窄带信号影响不大但对宽带信号就是致命的。AD9361的FIR滤波器结构比较特殊它挂在收发通道的数字部分支持可编程的抽头系数。发射端有TX FIR接收端有RX FIR每个都有固定的抽头数量和位宽限制。很多人拿到官方例程直接用MATLAB的fdatool或者filterDesigner设计一个低通把系数导出来写进寄存器就完事了。这样做功能上没问题但如果你做的系统对群延迟有要求比如要做相位相干的多通道接收、要做高精度的时间同步、或者要跑宽带高阶调制那这个FIR的相位特性就必须认真对待。我见过不少项目硬件射频部分做得挺讲究本振相位噪声、通道间隔离度都控制得不错结果数字FIR一加群延迟波动直接吃掉了几十纳秒的相位一致性预算。更麻烦的是这种问题在窄带测试时往往看不出来等到系统联调跑宽带波形时才暴露返工成本很高。所以这篇内容就是围绕“怎么在AD9361的FIR设计里把群延迟管起来”这个核心分享五个我在实际项目里反复验证过的技巧。每个技巧都会说清楚为什么这么做、怎么做、以及我踩过哪些坑。提示群延迟的单位是时间通常用纳秒或采样周期数表示。在AD9361的采样率下一个采样周期对应的延迟可能只有几纳秒所以群延迟波动几十纳秒已经是非常大的量了。2. 先搞清楚AD9361 FIR的抽头约束再谈优化2.1 抽头数量、位宽与时钟速率的三角关系AD9361的TX FIR和RX FIR在结构上是对称的但资源不同。TX FIR最多支持128个抽头RX FIR最多支持64个抽头抽头系数是16位有符号数但实际有效位宽和增益分配有关。这里有一个很多人一开始会忽略的点FIR的抽头数量直接决定了你能实现的过渡带宽度和阻带衰减同时也决定了群延迟均衡的自由度。从信号处理的基本原理来说一个N抽头的线性相位FIR其群延迟是(N-1)/2个采样周期。这个值是固定的但群延迟的“平坦度”取决于系数设计。抽头越多你在频域上能控制的自由度越大越容易把群延迟压平。但AD9361的FIR是跑在特定的时钟域下的抽头数量增加意味着每个采样周期内需要完成的乘加运算更多如果时钟速率不够你就得降低采样率或者用半带滤波器做级联。我在一个宽带发射项目里做过对比同样是要在20MHz带宽内把群延迟波动控制在5ns以内用64抽头设计出来的FIR群延迟峰峰值大概在12ns左右换成128抽头同样的优化算法下能压到4ns以内。但代价是TX FIR的时钟配置需要调整而且系数存储和加载的复杂度也上去了。所以第一步不是急着打开MATLAB而是先确认你的系统时钟预算和AD9361的采样率配置看看最多能用多少抽头。参数TX FIRRX FIR说明最大抽头数12864受FPGA/芯片内部资源限制系数位宽16位有符号16位有符号实际有效位取决于增益分配群延迟基数(N-1)/2 采样周期(N-1)/2 采样周期线性相位结构下固定可调自由度高中抽头越多均衡能力越强2.2 为什么不能直接用MATLAB默认的等波纹设计MATLAB的fdatool或者designfilt默认的等波纹设计equiripple在幅频响应上确实很漂亮通带波纹和阻带衰减都能精确控制。但等波纹设计的目标函数里通常不包含群延迟约束它只保证相位是线性的对于线性相位FIR但不保证群延迟在通带内是平坦的。实际上等波纹设计的群延迟在靠近通带边缘的地方往往会有明显的翘起。我早期就吃过这个亏。用fdatool设计了一个64抽头的低通通带20MHz阻带40MHz幅频响应看着完美群延迟在通带边缘翘了大概8个采样周期。当时采样率是30.72MHz一个采样周期32.5ns8个周期就是260ns的群延迟波动。这个量级对于任何做相位相干的应用都是灾难。后来改用iirlpnorm或者手动构造优化目标函数把群延迟也纳入代价函数才把这个问题解决掉。所以第二个技巧的核心就是不要信任默认设计必须把群延迟作为显式约束加入优化过程。具体做法可以用MATLAB的fmincon或者lsqnonlin做凸优化目标函数里同时包含幅频误差和群延迟误差权重根据你的系统需求来调。如果群延迟是主要矛盾就把群延迟的权重加大。2.3 抽头系数的量化效应与群延迟恶化AD9361的FIR系数是16位量化的这意味着你从MATLAB里算出来的浮点系数需要先量化再写入寄存器。量化本身会引入误差这个误差对幅频响应的影响通常不大但对群延迟的影响可能被放大。尤其是当你的系数动态范围很大时小系数被量化到零或者量化步长过大都会导致相位响应偏离设计值。我的经验是在MATLAB里设计完系数后一定要做一次量化仿真把系数按AD9361的位宽要求量化然后用量化后的系数重新计算群延迟和浮点结果对比。如果群延迟恶化超过你预算的20%就需要调整设计比如增加抽头数、放松幅频指标、或者换一种系数缩放方式。AD9361的FIR系数加载时有一个增益缩放因子这个因子选得不好也会影响有效位宽进而影响群延迟。注意量化后的群延迟仿真不能只看通带中心要扫整个通带。有些设计在中心频率处群延迟很平但边缘翘得厉害这种在宽带信号下照样出问题。3. 用相位均衡器“反向补偿”群延迟起伏3.1 相位均衡的基本思路级联一个全通网络如果主FIR的群延迟已经确定无法再优化或者你用的是官方例程里固定的系数那还有一个办法在链路里再级联一个相位均衡滤波器。这个均衡器通常是一个全通滤波器幅频响应是平的只改相位。全通滤波器的群延迟可以设计成“反向”于主滤波器的群延迟两者级联后总群延迟就平了。在AD9361的架构里这个均衡器可以放在FPGA里做也可以尝试合并到FIR系数里。如果放在FPGA里灵活性最高你可以用多个二阶全通节级联每个节的极点位置控制群延迟的形状。但缺点是增加了FPGA资源消耗和延迟。如果合并到FIR系数里就是把主FIR和均衡全通的冲激响应卷积得到一个更长的FIR。但AD9361的抽头数有限卷积后可能超出限制所以需要做模型降阶。我通常的做法是先在MATLAB里设计主FIR计算其群延迟曲线然后设计一个全通均衡器用iirgrpdelay或者手动优化极点让均衡器的群延迟近似为主FIR群延迟的负值加上一个常数最后把两者级联验证总群延迟。如果总抽头数超了就用balred或者fir2做降阶再重新优化。3.2 全通均衡器的阶数选择与数值稳定性全通滤波器的阶数不是越高越好。阶数越高你能拟合的群延迟曲线越复杂但数值稳定性也越差尤其是当极点靠近单位圆时量化误差会被放大。在AD9361这种定点平台上全通节的系数也是要量化的所以稳定性必须优先考虑。我的经验是对于AD9361的典型应用2到4个二阶全通节通常就够了。每个二阶节的群延迟峰值大概在几个采样周期量级通过调整极点半径和角度可以覆盖大部分群延迟起伏场景。如果主FIR的群延迟波动超过10个采样周期可能需要更多节但这时候我更倾向于回去优化主FIR而不是硬用均衡器去补。还有一个坑是全通均衡器会引入额外的绝对延迟。虽然群延迟平坦了但总延迟增加了。如果你的系统对绝对延迟有要求比如做TDD切换或者时间同步这个额外延迟也要算进去。我一般会在设计前先算好延迟预算把均衡器的延迟也纳入考虑。3.3 在AD9361上实现均衡器的两种路径对比实现路径优点缺点适用场景FPGA内级联全通灵活可动态调整消耗FPGA资源增加延迟多模式、需要在线重构合并到FIR系数不额外占资源抽头数受限降阶有误差固定配置、资源紧张混合方式平衡资源和灵活性设计复杂度高对群延迟要求极高的场景我实际项目中用得最多的是合并到FIR系数这条路因为AD9361的FIR资源是现成的不用额外动FPGA逻辑。但前提是主FIR的抽头数不能太多留出足够的余量给均衡器卷积后的长度。如果主FIR已经用了100个抽头那合并后肯定超128这时候就只能走FPGA级联。4. 群延迟测量与验证从仿真到实测的闭环4.1 MATLAB仿真阶段的关键验证步骤设计完系数只是第一步验证才是重头戏。在MATLAB里我通常会做三层验证第一层是浮点系数的群延迟曲线用grpdelay函数直接算第二层是量化后系数的群延迟模拟AD9361的定点效应第三层是把系数写入AD9361模型或者用实际采集的数据做回放验证。第一层和第二层之间的差异往往能揭示量化问题。如果量化后群延迟恶化明显就要检查系数的缩放和位宽分配。AD9361的FIR系数加载时有一个共同的缩放因子这个因子决定了系数的有效动态范围。缩放因子选得太大小系数被截断选得太小大系数可能溢出。我一般会用MATLAB的fi对象做定点仿真扫描不同的缩放因子找到群延迟最优的那个。第三层验证最接近实际但需要你有AD9361的采集数据或者一个行为级模型。如果没有实际数据可以用MATLAB的comm.RaisedCosineTransmitFilter或者自己搭一个包含AD9361 FIR的链路模型输入宽带信号看输出星座图和EVM。群延迟不平坦会导致星座点旋转和扩散这个在EVM上会直接体现出来。4.2 实测中用矢量网络分析仪看群延迟的注意事项如果有条件用矢量网络分析仪VNA测整个收发链路的群延迟那是最直接的。但要注意几个点第一VNA测的是模拟域的群延迟数字FIR的群延迟需要单独测或者从总延迟里减掉第二AD9361的收发通道有多个增益档位不同增益下群延迟可能略有变化要固定增益测第三校准要准尤其是电缆和连接器的相位校准否则测出来的群延迟波动可能是校准误差而不是真实特性。我通常的做法是先用VNA测模拟环路的群延迟作为基准然后在数字域加入FIR再测一次总群延迟两者相减得到FIR的群延迟贡献。如果数字FIR的群延迟和MATLAB仿真对不上就要检查系数加载是否正确、时钟配置是否匹配、以及AD9361内部的数据路径有没有额外的延迟环节。4.3 用宽带调制信号做端到端群延迟评估VNA测的是小信号S参数对于实际工作的调制信号群延迟的影响还要结合信号带宽来看。我更喜欢用宽带调制信号做端到端评估在发射端生成一个宽带OFDM或者单载波信号经过AD9361环回或者实际信道在接收端解调看EVM和星座图。如果群延迟在信号带宽内波动大EVM会明显恶化而且星座图会呈现频率相关的旋转。这个方法的好处是直接反映系统性能不需要复杂的校准。缺点是定位问题比较难EVM恶化可能是群延迟、幅频响应、相位噪声、非线性等多种因素共同作用。所以我会先确保其他因素都控制住了再单独看群延迟的影响。具体做法是先用一个群延迟平坦的FIR做基准测EVM然后换上待测FIR再测EVM两者的差值就是群延迟不平坦带来的恶化量。提示做端到端评估时信号的峰均比不要太高否则会掩盖群延迟的影响。我一般用峰均比6dB左右的信号既能反映宽带特性又不会让功放非线性成为主导。5. 五个实战技巧的落地细节与避坑记录5.1 技巧一把群延迟约束写进FIR优化目标函数这是最根本的一条。不要用默认的等波纹设计而是自己构造优化问题。在MATLAB里可以用fmincon或者lsqnonlin目标函数写成function err fir_obj(x, N, f_pass, f_stop, gd_target, w_gd) % x: 系数向量半对称只优化一半 % N: 抽头数 % f_pass: 通带频率向量 % f_stop: 阻带频率向量 % gd_target: 目标群延迟 % w_gd: 群延迟权重 h [x; flipud(x(1:end-1))]; % 构造线性相位FIR [H, w] freqz(h, 1, 1024); gd grpdelay(h, 1, 1024); % 幅频误差 mag_err 0; pass_idx w f_pass(end); stop_idx w f_stop(1); mag_err mag_err sum((abs(H(pass_idx)) - 1).^2); mag_err mag_err sum(abs(H(stop_idx)).^2); % 群延迟误差 gd_err sum((gd(pass_idx) - gd_target).^2); err mag_err w_gd * gd_err; end这个目标函数里w_gd是群延迟的权重。如果群延迟是主要矛盾就把w_gd调大比如设成10或者100。但要注意权重太大可能导致幅频响应恶化需要折中。我一般会先设一个较小的权重看群延迟能压到什么程度再逐步加大直到幅频响应接近临界。这个方法的坑在于优化问题的非凸性。fmincon可能陷入局部最优所以初始值很重要。我通常用等波纹设计的结果作为初始值然后跑优化。如果结果不理想就换几个不同的初始值多跑几次取最好的。5.2 技巧二用频率采样法直接控制群延迟形状除了优化方法频率采样法frequency sampling也可以用来设计FIR而且可以更直接地控制群延迟。频率采样法的思路是在频域上指定一组采样点的幅值和相位然后做逆FFT得到系数。对于线性相位FIR相位是频率的线性函数群延迟就是常数。但如果你想要非线性的群延迟可以指定非线性的相位。具体做法是在通带内指定一组频率点每个点指定幅值为1相位为-2*pi*f*delay(f)其中delay(f)是你想要的群延迟曲线。然后做逆FFT加窗得到系数。这个方法的优点是直观你可以直接“画”出群延迟的形状。缺点是频率采样点之间的响应不可控可能出现过冲或者振铃。我一般在需要特定群延迟形状时用这个方法比如补偿已知的链路群延迟。但设计完后一定要做频域验证看采样点之间的群延迟有没有异常。如果有就增加采样点数或者加窗优化。5.3 技巧三量化后做群延迟的蒙特卡洛分析AD9361的系数是16位量化的量化误差对群延迟的影响不是确定性的而是和具体系数值有关。为了评估最坏情况我会做蒙特卡洛分析在量化前给系数加一个小的高斯扰动然后量化计算群延迟重复几百次看群延迟波动的分布。这个分析能告诉你在当前设计下量化误差导致的群延迟恶化最坏能到多少。如果最坏情况超出了你的预算就需要调整设计比如增加抽头数、改变系数缩放、或者换一种量化策略比如噪声整形。我做过一个项目蒙特卡洛分析显示最坏情况下群延迟波动会翻倍后来把抽头数从48增加到64最坏情况就降到了可接受范围。5.4 技巧四利用AD9361的FIR旁路模式做对比测试AD9361的FIR可以旁路这给了你一个天然的对比基准。在调试群延迟时我通常会先旁路FIR测整个链路的群延迟作为基准然后启用FIR再测一次两者的差值就是FIR的贡献。如果这个差值和MATLAB仿真对不上就说明系数加载或者时钟配置有问题。旁路模式下AD9361的收发通道还有半带滤波器和其他数字滤波它们的群延迟也要算进去。所以基准测量要包含这些环节。我一般会查AD9361的芯片手册找到各个数字滤波器的群延迟典型值和实测对比。如果手册数据和实测差太多就要检查采样率配置和时钟分频比。5.5 技巧五把群延迟纳入系统级延迟预算最后一个技巧是系统层面的群延迟不是孤立的它要和整个链路的延迟预算一起考虑。AD9361的收发通道有固定的数字延迟、模拟延迟、接口延迟FIR的群延迟只是其中一部分。如果你的系统做TDD或者时间同步总延迟的绝对值和波动都很重要。我通常会在项目初期就建立一个延迟预算表把各个部分的延迟和波动都列出来FIR的群延迟波动作为其中一项。这样在设计FIR时你就知道群延迟波动的预算有多少不会过度设计也不会设计不足。这个表在后期调试时也很有用当系统性能不达标时可以快速定位是哪个环节的延迟出了问题。延迟环节典型延迟波动范围备注模拟前端几ns小取决于器件和匹配ADC/DAC固定小查手册半带滤波器固定小查手册FIR滤波器(N-1)/2采样周期取决于设计本文重点接口传输取决于协议中与FPGA逻辑有关这个表看起来简单但在实际项目中能省很多事。我见过一个团队FIR设计得很漂亮群延迟压得很平结果接口传输的延迟波动没算进去系统联调时相位一致性还是不达标。后来把接口延迟也纳入优化才解决问题。6. 从寄存器0x247读出0x80说起一个真实的调试插曲说到AD9361的调试有个现象很多人应该都遇到过初始化时读0x247寄存器一直读出0x80同时CP OVRG HIGH被置位RX PLL没有锁定。这个问题表面上看和FIR群延迟没关系但实际上它会影响你对FIR的验证。因为如果PLL没锁采样时钟就不对FIR的群延迟测量就完全不可信。我遇到这个问题的排查过程是这样的先确认参考时钟是否正常用示波器看参考时钟的幅值和频率然后检查SPI通信是否正常读其他寄存器看返回值是否合理接着查电源尤其是PLL的供电是否干净最后发现是参考时钟的驱动能力不够导致PLL锁定不稳定。换了驱动能力更强的时钟源后0x247恢复正常RX PLL锁定FIR的群延迟测量也稳定了。这个插曲的教训是在验证FIR群延迟之前一定要确保AD9361的基础初始化是正常的。PLL没锁、时钟不对、电源不干净这些都会让群延迟测量失去意义。我现在的习惯是每次调试FIR之前先跑一遍基础初始化检查清单确认所有PLL锁定、所有电源正常、SPI通信无误然后再动FIR。注意AD9361的初始化顺序对PLL锁定影响很大。如果顺序不对即使参考时钟正常PLL也可能不锁。建议严格按照官方例程的初始化顺序来不要随意调整。7. 群延迟优化后的系统级收益与后续扩展把群延迟压平之后最直接的收益是宽带信号的EVM改善。我在一个20MHz带宽的发射项目里做过对比优化前EVM大概在3.5%左右优化后降到了1.8%提升了将近一倍。这个改善对于高阶QAM来说就是能不能用的区别。另一个收益是多通道相位一致性变好做波束成形或者相位干涉测量时通道间的相位误差从十几度降到了几度以内。后续如果想进一步优化可以考虑几个方向一是把温度补偿加进去因为AD9361的模拟延迟会随温度变化FIR的群延迟虽然数字域稳定但和模拟域级联后总群延迟还是会漂二是做在线自适应根据接收到的信号质量动态调整FIR系数这需要FPGA里有相应的优化逻辑三是把群延迟优化和幅频响应优化联合起来做多目标优化找到帕累托最优解。我个人在实际操作中的体会是群延迟这件事早做比晚做好。项目初期花几天时间把FIR的群延迟设计对比后期系统联调时发现相位问题再返工要划算得多。而且一旦你掌握了这套方法后面换项目、换采样率、换带宽都可以快速复用。MATLAB的优化工具箱和定点仿真工具是核心武器AD9361的芯片手册和官方例程是基础参考剩下的就是多动手、多测量、多对比。

相关推荐

FPGA高速串行通信实战:Aurora 64B/66B协议解析与Vivado调试
FPGA高速串行通信实战:Aurora 64B/66B协议解析与Vivado调试

做FPGA开发三四年,我越来越确信一件事:高速串行收发器是绕不过去的坎。我最早接触Aurora 64B/66B是在一个视频采集项目里,两块板卡之间用光纤传原始图像数据,一开始用自定义的8B/10B协议,速率和带宽勉强够,… · 2026/9/25 5:16:24

DoWhy causal_prediction.algorithms:ERM 与 CACM 因果预测算法包的源码级详解
DoWhy causal_prediction.algorithms:ERM 与 CACM 因果预测算法包的源码级详解

机器学习数据分析 【免费下载链接】dowhy DoWhy is a Python library for causal inference that supports explicit modeling and testing of causal assumptions. DoWhy is based on a unified language for causal inference, combining causal graphical models and potent… · 2026/9/25 5:16:18

IronClaw Kernel 权威边界解析:九阶段安全外围的架构设计与源码实现
IronClaw Kernel 权威边界解析:九阶段安全外围的架构设计与源码实现

人工智能AI 应用交互助手AI Agent 【免费下载链接】ironclaw IronClaw is an Agent OS focused on privacy, security and extensibility 项目地址: https://gitcode.com/gh_mirrors/iro/ironclaw 点击查看 免费下载 本文以 docs/internal/reborn/target-architect… · 2026/9/25 5:16:18

零基础一小时C语言入门:从变量循环到数组指针的极简指南
零基础一小时C语言入门:从变量循环到数组指针的极简指南

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

CTF流量分析实战:USB键盘与鼠标流量提取与还原
CTF流量分析实战:USB键盘与鼠标流量提取与还原

CTF流量分析做了几年,USB这个方向真的是“老面孔”了。从入门赛到省级决赛,USB流量题几乎成了标配,尤其是键盘流量,几乎人手一把梭。但是很多人卡在不知道USB流量到底在说什么、键盘映射怎么处理、鼠标坐标怎么还原,更… · 2026/9/25 6:25:25

辉芒微MCU烧录校验全指南:从Hex到FMD-Link实操
辉芒微MCU烧录校验全指南:从Hex到FMD-Link实操

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

SpringBoot+MySQL学生成绩管理系统开发实践
SpringBoot+MySQL学生成绩管理系统开发实践

1. 项目背景与核心价值作为一名长期从事教育信息化系统开发的工程师,我深知学生成绩管理是每所学校最基础也最关键的日常事务。传统Excel表格管理方式在数据安全、多人协作和统计分析方面存在明显短板。这个基于SpringBoot和MySQL的学生成绩管理系统,正是… · 2026/9/25 6:25:19

AI编程工具上传.git目录引发隐私争议:技术原理与开发者防护指南
AI编程工具上传.git目录引发隐私争议:技术原理与开发者防护指南

1. 事件背景与核心争议拆解1.1 一个“仓库快照”功能为何引发轩然大波事情的起因并不复杂。有开发者在日常使用 ZCode 这款 AI 编程辅助工具时,通过抓包和本地文件监控发现,工具在特定操作触发下,会把当前项目的.git目录整体打包上传。注意&a… · 2026/9/25 6:25:19

51单片机驱动24BYJ48步进电机:ULN2003接线、代码与避坑指南
51单片机驱动24BYJ48步进电机:ULN2003接线、代码与避坑指南

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

数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)
数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)

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

创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战
创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战

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

MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX
MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX

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

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码