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

从零搭建QPSK收发链路:AD9361初始化与GNU Radio同步调试实战

发布时间:2026/9/25 1:58:54 来源:云帆数科 栏目:资讯中心
从零搭建QPSK收发链路:AD9361初始化与GNU Radio同步调试实战
1. 为什么我要从零搭一条 QPSK 收发链路把一段 bit 流变成空口上的 QPSK 点簇再在接收端把它还原回来这件事听起来像是教科书里一章的内容但真正动手做一遍你会发现中间隔着一堆文档里不会写、但不过就卡死的细节。我这次用的硬件是 P201ProAD9361 射频前端方案软件侧是 GNU Radio目标很朴素发端把一串已知的 bit 映射成 QPSK 符号、成型滤波、上变频发出去收端做同步、匹配滤波、判决最后在星座图上看到四个干净的点簇最好还能顺手看一眼眼图。为什么选 QPSK 作为切入点因为它是一个刚刚好的调制方式。BPSK 太简单看不出同步和频偏处理的必要性16QAM 又太敏感链路没调通之前你根本分不清是算法问题还是射频问题。QPSK 每个符号 2 bit星座点少、判决门限清晰一旦点簇糊成一团你几乎可以立刻判断是频偏、相位噪声还是定时没对齐。对于第一次搭 SDR 收发链路的人来说QPSK 是性价比最高的练手对象。这篇总结面向的是已经摸过 GNU Radio、手里有一块 AD9361 类板子、但链路还没真正跑通的同好。我会把整条链路拆成几个阶段先讲清楚 AD9361 初始化里那个让人头大的 0x247 寄存器问题再讲发端链路怎么搭、收端同步怎么做最后讲星座图和眼图怎么调出能看的效果。中间会穿插我自己踩过的坑尤其是那些寄存器读出来不对、PLL 没锁、CP OVRG 被置高的排查过程——这些才是真正卡人的地方。先说结论这条链路能跑通但前提是你得先把射频前端伺候好。软件侧的 GNU Radio 流图再漂亮如果 AD9361 没正常初始化你看到的星座图永远是一团噪声。所以我把射频初始化放在最前面讲这不是跑题这是整条链路的地基。2. AD9361 初始化0x247 读出 0x80 与 RX PLL 未锁的排查链路2.1 现象描述寄存器读回值不对PLL 死活不锁我第一次上电配置 AD9361 的时候遇到的现象非常典型初始化流程走到一半读 0x247 寄存器期望值应该是某个配置后的状态结果一直读出 0x80。同时伴随两个症状——CP OVRGCharge Pump Overrange被置高RX PLL 没有锁定。这三个现象是连锁的不是独立问题。0x247 这个寄存器在 AD9361 的寄存器映射里属于 RX 相关配置区读回 0x80 意味着某一位被强制置位而这个位通常和校准状态或者 PLL 状态相关。CP OVRG 置高说明电荷泵的输出超出了正常工作范围这直接导致 PLL 环路无法锁定。PLL 不锁RX 链路就没有本振后面的一切都无从谈起。很多人遇到这个问题的第一反应是是不是我寄存器配置顺序错了然后开始翻手册逐条对照。这个方向没错但效率很低。我的建议是先建立一个排查链路从电源和参考时钟开始逐级往上查而不是一上来就怀疑配置序列。2.2 根因定位从参考时钟到电荷泵的逐级排查我当时的排查顺序是这样的你可以直接复用参考时钟检查AD9361 的参考时钟输入是否稳定、频率是否正确。用示波器或者频谱仪看一眼确认没有停振或者频率偏移。参考时钟不对PLL 的鉴相器就没有正确的比较基准电荷泵自然会过载。电源域检查AD9361 有多个电源域尤其是 VCO 和电荷泵相关的供电。如果某一路电源纹波过大或者电压偏低电荷泵的工作点就会偏移CP OVRG 被置高是必然的。SPI 通信检查确认寄存器写入是否真正生效。有时候 SPI 时序不对你写进去的值根本没进芯片读回来的自然是默认值或者错误值。0x247 读出 0x80 有可能就是写入没生效芯片保持在一个中间状态。初始化序列检查AD9361 的初始化有严格的顺序要求尤其是 PLL 使能、校准触发、滤波器配置这几步。顺序错了PLL 可能在一个未校准的状态下被使能直接导致不锁。我最后定位到的根因是参考时钟的驱动能力不足导致 PLL 鉴相器输入信号幅度偏低电荷泵为了补偿这个偏差而进入过载状态。换了一个驱动能力更强的时钟源之后CP OVRG 不再置高RX PLL 顺利锁定0x247 的读回值也恢复正常。这里有个经验AD9361 的很多寄存器问题其实是模拟前端问题。数字侧读出来的异常值往往是模拟侧工作点不对的映射。所以排查的时候不要只盯着寄存器手册要抬头看看射频和电源。2.3 初始化顺序里最容易搞反的几步AD9361 的初始化序列很长但有几步的顺序特别容易搞反我列出来给你提个醒先配置参考时钟和电源相关寄存器再使能 PLL。如果先使能 PLL 再配时钟PLL 会在一个错误的参考下尝试锁定大概率失败。先触发校准再使能 RX/TX 通道。校准需要在通道关闭的状态下进行通道开着的时候校准结果会被干扰。滤波器配置要在 PLL 锁定之后。因为滤波器的时钟来自 PLLPLL 没锁的时候配滤波器时钟频率不对滤波器系数加载会出错。提示如果你用的是现成的驱动或者 GNU Radio 的 AD9361 模块这些顺序通常已经封装好了。但如果你是自己写初始化代码这几步一定要按顺序来。我见过太多人因为顺序问题卡了好几天。2.4 一个可复用的初始化自检清单为了避免每次上电都重新排查一遍我整理了一个自检清单初始化之后逐项确认检查项正常表现异常时的可能原因参考时钟频率与配置值一致幅度足够时钟源驱动不足、停振电源电压各域电压在手册范围内电源纹波大、电压偏低SPI 回读写入值与回读值一致SPI 时序错误、片选问题CP OVRG未置高电荷泵过载查参考时钟和电源RX PLL 锁定状态锁定位置位参考时钟、环路滤波器参数0x247 读回值与预期一致上述任一环节异常都可能导致这个清单我每次换板子或者改配置都会跑一遍能省下大量瞎猜的时间。3. 发端链路从 bit 流到 QPSK 符号的 GNU Radio 实现3.1 流图整体结构与我为什么这样分层发端的 GNU Radio 流图我分成了四层信源层、映射层、成型层、射频层。这样分层的好处是每一层都可以单独测试出问题的时候能快速定位是哪一层的锅。信源层就是一个简单的随机 bit 源或者文件源产生 0/1 序列。映射层把每 2 个 bit 映射成一个 QPSK 符号映射规则我用的是格雷码因为格雷码相邻星座点只差一个 bit误判的时候误码率最低。成型层做脉冲成型我用的是根升余弦RRC滤波器滚降系数 0.35。射频层就是把基带信号送到 AD9361 的 TX 通道。为什么用 RRC 而不是直接矩形脉冲因为矩形脉冲的频谱是 sinc 函数旁瓣衰减慢带外泄漏严重实际空口上会干扰相邻信道。RRC 能在保证无码间干扰的前提下压缩频谱是 SDR 链路里的标准做法。滚降系数 0.35 是一个折中太小了频谱效率高但实现难度大太大了频谱浪费。0.35 是工程上常用的值。3.2 QPSK 映射与格雷码的实操细节QPSK 映射本身很简单四个星座点每个点对应 2 bit。但映射规则有讲究。我用的是这样的映射00 → (1j)/√201 → (-1j)/√211 → (-1-j)/√210 → (1-j)/√2注意这里的 √2 归一化是为了让平均符号功率为 1。如果不归一化后续的增益控制会很难做。格雷码的好处在这个映射里体现得很明显相邻星座点之间只有 1 bit 不同。比如 00 和 01 相邻只差最低位01 和 11 相邻只差最高位。这样在接收端判决的时候即使因为噪声判到了相邻点也只会错 1 个 bit而不是 2 个 bit。在 GNU Radio 里你可以用Constellation QPSK模块直接做映射也可以自己写 Python Block。我建议先用现成模块跑通再考虑自己实现因为现成模块的归一化和映射规则已经调好了省得你在细节上浪费时间。3.3 RRC 成型滤波器的参数计算与实测调整RRC 滤波器的关键参数有两个滚降系数和符号跨度span。滚降系数我选了 0.35符号跨度我选了 8 个符号。这两个参数决定了滤波器的阶数和计算量。滤波器的阶数计算公式是阶数 span × samples_per_symbol。假设每个符号 4 个采样点span 是 8那阶数就是 32。这个阶数在 GNU Radio 里跑起来毫无压力但如果你把 samples_per_symbol 提到 16阶数就变成 128计算量会明显上升。实测下来samples_per_symbol 选 4 到 8 之间比较合适。太少了波形不够平滑成型效果差太多了计算量大而且对实际性能提升有限。我用的是 4配合 span8在频谱仪上看带外抑制已经足够好了。注意RRC 滤波器在发端和收端要成对使用。发端用一个 RRC收端再用一个匹配的 RRC两者卷积起来就是一个完整的升余弦响应这样才能实现无码间干扰。如果你只在发端做 RRC收端不做匹配滤波那接收端的符号间干扰会很严重。3.4 送数到 AD9361 TX 通道时的增益与采样率匹配发端最后一步是把基带信号送到 AD9361 的 TX 通道。这里有两个参数要匹配采样率和增益。采样率方面AD9361 的 TX 采样率要和 GNU Radio 流图的输出采样率一致。如果不一致要么在流图里做重采样要么在 AD9361 里配置对应的采样率。我一般是在 GNU Radio 里把采样率设成 AD9361 支持的某个值比如 1.92 MSPS 或者 3.84 MSPS这样不用额外做重采样。增益方面TX 增益不能设太大否则信号会失真星座图会发散也不能太小否则空口上信噪比不够。我的做法是先用一个较小的增益比如 -10 dB在频谱仪上看输出功率然后逐步增加直到输出功率合适且星座图不发散。这个过程需要反复试没有一劳永逸的值因为不同的板子、不同的天线、不同的距离都不一样。4. 收端同步让 QPSK 点簇从一团糊变成四个点4.1 接收链路的分层与同步顺序收端比发端复杂得多因为你要处理的是未知的信号。收端链路我分成五层射频接收层、下变频层、匹配滤波层、同步层、判决层。同步层是核心它又包含三个子步骤粗频偏估计与校正、细频偏估计与校正、定时同步。这三个步骤的顺序不能乱先粗频偏再细频偏最后定时。因为频偏会影响定时误差的估计如果先做定时再做频偏定时结果会被频偏带偏。为什么频偏这么重要因为 AD9361 的收发本振是独立的两个本振之间总有频率偏差再加上多普勒效应接收到的信号中心频率和发端不完全一致。QPSK 对频偏很敏感哪怕只有几度的相位旋转星座点就会开始糊。所以频偏校正是收端同步的第一要务。4.2 粗频偏估计用 FFT 找能量峰值粗频偏估计我用的是 FFT 方法。原理很简单把接收到的信号做 FFT找到能量峰值的位置和理论上的中心频率比较差值就是粗频偏。具体操作上我在 GNU Radio 里用一个FFT Sink观察接收信号的频谱手动找峰值然后算出差值。这个方法比较笨但胜在直观适合第一次调链路的时候用。等链路跑通了可以换成自动的频偏估计模块比如Polyphase Clock Sync配合Costas Loop。粗频偏的估计精度不需要太高因为它只是给细频偏提供一个初始值。一般粗频偏能把偏差压到几百 Hz 以内细频偏再把它压到几 Hz 以内就足够 QPSK 判决了。4.3 细频偏校正Costas 环的参数整定细频偏校正我用的是 Costas 环。Costas 环是一个锁相环专门用于抑制载波调制信号的载波恢复。它的关键参数是环路带宽和阻尼系数。环路带宽决定了 Costas 环跟踪频偏的速度和精度。带宽太宽跟踪快但噪声大带宽太窄噪声小但跟踪慢而且可能锁不住。我一般从环路带宽等于符号率的 1% 开始试比如符号率是 1 MSPS环路带宽就从 10 kHz 开始然后根据星座图的收敛情况调整。阻尼系数一般取 0.707这是巴特沃斯响应的标准值能在跟踪速度和稳定性之间取得比较好的平衡。如果你发现星座图在收敛过程中振荡可以适当增大阻尼系数如果收敛太慢可以适当减小。提示Costas 环的整定是个细活不要指望一次就调好。我的经验是先把环路带宽设大一点让星座图先收敛然后再逐步减小带宽观察星座点的聚拢程度。每次调整后等几秒钟让环路稳定下来再看效果。4.4 定时同步为什么 Gardner 算法在 QPSK 上很好用定时同步我用的是 Gardner 算法。这个算法在 QPSK 上特别好用因为它不需要知道载波相位对频偏和相位偏移不敏感可以在载波恢复之前或者同时进行。Gardner 算法的核心思想是利用相邻符号的过零点来估计定时误差。具体来说它计算当前符号和上一个符号的差值乘以中间采样点的值得到定时误差信号。这个误差信号经过环路滤波器后控制采样时刻的调整。在 GNU Radio 里Polyphase Clock Sync模块内部就实现了 Gardner 或者类似的定时同步算法。你只需要设置好samples per symbol和环路带宽两个参数。samples per symbol 要和发端一致环路带宽一般取符号率的 1% 到 5% 之间。实测下来Gardner 算法在 QPSK 上的收敛速度很快一般几百个符号之内就能锁定。锁定之后星座图上的四个点簇会明显聚拢眼图也会张开。5. 星座图与眼图怎么判断链路是真的通了5.1 星座图能看和好看之间的差距星座图能看出四个点簇说明链路基本通了。但能看和好看之间差距很大。能看的星座图四个点簇是糊的点与点之间有重叠好看的星座图四个点簇是紧致的点与点之间界限分明。影响星座图质量的因素很多频偏残余、相位噪声、定时误差、信噪比、非线性失真。排查的时候要一个一个排除。我的做法是先看星座图的整体形状如果四个点簇是旋转的说明有残余频偏如果点簇是发散的说明信噪比不够或者有非线性失真如果点簇是椭圆形的说明定时同步没做好。5.2 眼图张不开的三种典型原因眼图是判断符号间干扰的直观工具。眼图张得越开符号间干扰越小判决越可靠。眼图张不开一般有三种原因成型滤波器不匹配发端和收端的 RRC 滤波器参数不一致导致整体响应不是升余弦符号间干扰严重。检查两端的滚降系数和 span 是否一致。定时同步没锁采样时刻没有对准符号的最佳采样点眼图自然张不开。检查定时同步模块的环路带宽和收敛状态。频偏残余太大频偏会导致星座点旋转眼图上的线条会变粗看起来像张不开。检查 Costas 环的锁定状态。我遇到过一次眼图死活张不开的情况最后发现是收端的 RRC 滤波器滚降系数设成了 0.5而发端是 0.35。改成一致之后眼图立刻张开了。这种低级错误在调试初期很常见所以每次改参数都要两边一起改。5.3 从点簇质量反推链路问题的排查表我把常见的星座图问题和对应的排查方向整理成了一张表你可以直接对照星座图表现可能原因排查方向四个点簇旋转残余频偏Costas 环带宽、粗频偏估计点簇发散、模糊信噪比不足、非线性失真TX 增益、接收增益、滤波器点簇呈椭圆定时同步未锁Gardner 环路带宽、samples per symbol点簇偏移中心直流偏置基带直流消除、AD9361 配置只有两个点簇映射错误QPSK 映射规则、格雷码点簇完全糊成一团频偏太大、PLL 未锁射频初始化、参考时钟这张表是我调试过程中慢慢总结出来的每次遇到问题先查表能省不少时间。6. 几个让我卡了最久的坑与最终解法6.1 采样率不匹配导致的幽灵符号间干扰这个坑我卡了整整两天。现象是星座图上的点簇总是有点糊但眼图看起来又还行信噪比也不算差。我一开始怀疑是频偏没校正好反复调 Costas 环没用。后来怀疑是滤波器问题把 RRC 参数翻来覆去改也没用。最后发现是发端和收端的采样率不严格一致。发端 GNU Radio 流图的采样率设的是 1.92 MSPS但 AD9361 实际工作的采样率因为时钟分频的关系是 1.92 MSPS 的一个近似值两者之间有微小的偏差。这个偏差在短时间内看不出来但累积起来就会导致符号定时漂移产生幽灵符号间干扰。解法是让 GNU Radio 流图的采样率和 AD9361 的实际采样率严格对齐。具体做法是查 AD9361 的时钟配置算出实际采样率然后在 GNU Radio 里设成同一个值。如果实在对不齐可以在收端加一个重采样模块把采样率校正过来。6.2 直流偏置怎么悄悄毁掉你的星座图直流偏置是另一个隐蔽的坑。AD9361 的零中频架构天然会有直流偏置如果不在基带消除星座图会整体偏移中心。偏移不大的时候你可能只觉得星座图有点歪但判决的时候误码率会明显上升。我的解法是在收端加一个直流消除模块。GNU Radio 里有现成的DC Blocker模块直接拖进去就行。参数方面截止频率设得低一点比如符号率的 0.1%这样既能消除直流又不会影响有用的低频分量。注意直流消除要在匹配滤波之前做否则滤波器会把直流偏置扩散到整个频带更难消除。6.3 射频增益分配发端太大和收端太大都不行增益分配是个经验活。发端增益太大信号会进入 AD9361 的非线性区星座图会发散收端增益太大噪声也会被放大信噪比反而下降。我一开始把发端增益设得很大想着信号强一点总没错结果星座图糊得一塌糊涂。后来把发端增益降下来收端增益适当提高星座图立刻清晰了。我的经验是发端增益以输出信号刚好不进入非线性区为准收端增益以接收信号幅度接近 ADC 满量程的 70% 到 80% 为准。这个比例能在保证信噪比的同时留出足够的余量避免削顶。6.4 从能跑到跑得稳的最后一步链路能跑通之后下一步是让它跑得稳。我做了三件事加自动增益控制AGC手动设增益在实验室里没问题但实际环境里信号强度会变AGC 能自动调整增益保持接收信号幅度稳定。加频偏跟踪粗频偏和细频偏只能校正静态频偏如果收发本振有漂移还需要频偏跟踪。Costas 环本身有一定的跟踪能力但如果漂移太大需要额外的跟踪环路。加误码率统计在收端加一个误码率统计模块实时监控链路质量。误码率突然上升的时候能第一时间发现而不是等到星座图糊了才反应过来。这三件事做完之后链路才算真正跑得稳。我在实际测试中连续跑了几个小时误码率一直保持在 1e-5 以下星座图也没有明显退化。7. 写在最后一些个人体会这条链路从零到跑通前后花了大概两周时间其中大部分时间花在射频初始化和同步调试上。如果让我给后来者一句建议那就是先把射频前端伺候好再碰基带算法。我见过太多人一上来就调 Costas 环、调 Gardner结果射频根本没初始化好怎么调都是白费。另外GNU Radio 的流图不要一次搭完要分层搭、分层测。发端先单独测用频谱仪看输出收端先单独测用信号源灌已知信号两端都单独测通了再连起来联调。这样出问题的时候你能快速定位是哪一端的锅。最后星座图和眼图是两条链路的体检报告但不要只盯着它们看。频谱、时域波形、误码率这些都要结合起来看。有时候星座图看着还行但误码率很高那说明问题在判决逻辑或者编码上而不是在射频或者同步上。这套东西后续还可以扩展比如换成 16QAM 看看高阶调制的同步难度或者加个信道编码看看误码率能降到多少。但那是下一步的事了先把 QPSK 这条链路跑稳比什么都重要。

相关推荐

STM32入门到实战:三天搞定环境搭建与核心外设
STM32入门到实战:三天搞定环境搭建与核心外设

/* 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:58:54

STM32培训怎么选?四大死亡红线避坑指南
STM32培训怎么选?四大死亡红线避坑指南

/* 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:58:54

华为MDE岗位本质:架构翻译官与接口契约设计师
华为MDE岗位本质:架构翻译官与接口契约设计师

/* 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:58:54

react-native-skia 图像偏移过滤器 Offset 完全指南:属性、示例与底层实现
react-native-skia 图像偏移过滤器 Offset 完全指南:属性、示例与底层实现

图形学移动开发跨平台UI组件 【免费下载链接】react-native-skia High-performance React Native Graphics using Skia 项目地址: https://gitcode.com/gh_mirrors/re/react-native-skia 点击查看 免费下载 本文围绕 react-native-skia 提供的 Offset 图像过滤器展… · 2026/9/25 3:05:43

新春送福进一线:一场基层工会活动的策划与复盘
新春送福进一线:一场基层工会活动的策划与复盘

腊月下旬的北京,天亮得晚。活动室门口有人摸黑支桌子,红纸一卷一卷堆在墙角,砚台里的墨还没化开,凑近能闻到那股子墨香。常营地区总工会今年的"新春送福进一线"活动,就这么从一张桌子开始铺开了。说实话&… · 2026/9/25 3:05:43

easy-vibe 前端进阶教程:Figma 与 MasterGo 实战入门,从零创建网页原型
easy-vibe 前端进阶教程:Figma 与 MasterGo 实战入门,从零创建网页原型

教程文档 【免费下载链接】easy-vibe 从 0 到 1 学会 vibe coding,项目制学习 项目地址: https://gitcode.com/datawhalechina/easy-vibe 点击查看 免费下载 本文基于 easy-vibe 教程 Stage 2(初级-中级开发)前端方向的《Figma 与… · 2026/9/25 3:05:37

F´ 中的规则与场景驱动测试:基于 STest 的组件单元测试框架详解
F´ 中的规则与场景驱动测试:基于 STest 的组件单元测试框架详解

嵌入式系统编程 【免费下载链接】fprime F - A flight software and embedded systems framework 项目地址: https://gitcode.com/gh_mirrors/fpri/fprime 点击查看 免费下载 导读 STest 是 F(F Prime)飞行软件与嵌入式系统框架中内置的一个… · 2026/9/25 3:05:37

AI芯片架构选型指南:从GPU到TPU的实战对比
AI芯片架构选型指南:从GPU到TPU的实战对比

/* 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 3:05:37

Win10 LTSC 2019老电脑优化指南:稳定、轻量、十年支持
Win10 LTSC 2019老电脑优化指南:稳定、轻量、十年支持

1. 为什么老电脑需要LTSC?不是“精简版”,而是“去冗余的官方原生系统”你手边那台奔腾G3258配4GB内存、机械硬盘还在吱呀作响的办公机,或者那台被塞进收银台底下、连USB3.0都没有的POS终端——它们真就该被淘汰吗?我去年帮本地一… · 2026/9/25 3:05:37

数值优化(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

了解更多?预约专属演示

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

企业微信二维码