
做WiFi接收机尤其做OFDM物理层的时候“时频同步”这四个字几乎就是第一道门槛。不管你是写嵌入式平台上的协议栈还是在FPGA里写RTL还是在PC上搭软件无线电原型只要信号从天线进来接收机要做的第一件事就是把“这个帧从哪儿开始”和“载波频率偏了多少”这两件事搞清楚。而这两件事的答案其实都藏在802.11的帧结构里准确地说是藏在每一帧最前面那几十个微秒的前导码中。今天这篇东西我想从帧结构入手把WiFi时频同步这件事彻底讲透。适合的读者是做通信物理层开发的工程师、打算入门无线通信的学生以及那些想搞明白OFDM接收机到底怎么工作的朋友。我尽量用“干活”的语言讲不整教科书式的委婉。1. 为什么要从帧结构讲起1.1 接收机拿到信号时到底不知道什么一个802.11发射机把数据调制成OFDM符号再上变频到2.4G或者5G的射频载波上发出去。接收机天线拿到的是混合了噪声、多径、干扰的信号这时候它面临三个未知。第一信号到底什么时候来的。空口上可能安静了很久突然一个帧就冒出来了。接收机不知道自己应该在哪个时刻开始采样、哪个时刻开始做FFT。第二载波频率到底偏了多少。发射机的本地振荡器和接收机的本地振荡器都是晶体产生的晶体的初始精度和温漂不可能完全一致再加上多普勒效应接收信号的载波跟接收机本振之间一定有个偏差。这个偏差轻则导致星座图旋转重则直接让OFDM的子载波正交性被破坏。第三采样时钟偏了多少。发射机和接收机的ADC采样时钟同样存在偏差这个偏差会影响符号时长导致FFT窗口滑移。这三件事业界统称为时频同步。注意时同步和频同步其实是两个维度但它们的解决思路高度依赖同一个东西——帧结构。后面你会看到802.11的帧结构在最前面专门设计了一段训练序列就是为了让接收机把这三个未知量一个一个解出来。1.2 帧结构为什么是理解同步的钥匙802.11从诞生那天开始就是在时域上有限长的帧结构。每个帧的前面有一段设计好的、具有周期重复性的训练序列这段序列既要让接收机能“发现”信号来了又要能“度量”频率偏移和符号边界。我经常跟人打一个比方同步问题就像你在乌漆嘛黑的山里找一座桥帧结构就是桥头那盏每隔100米闪一次、总共闪10次的信号灯。你通过灯光的闪烁周期知道了距离在变化通过灯光第一次亮起的位置知道了桥头在哪儿。STF和LTF就是这两组灯。所以不理解帧结构就很难真正理解WiFi的同步算法。反过来一旦你看懂了帧结构里那些训练序列的长度、周期和摆放位置同步算法的每一步都像是提前写好的剧本。这个项目标题挂在“从帧结构讲起”我觉得是特别聪明的切入点比直接丢一堆自相关公式更有体系感。2. 802.11帧结构里的同步基因2.1 从802.11a说起STF、LTF、SIG三位一体802.11a定义了OFDM物理层的基本帧结构。仅看前导码部分它是这样的L-STFLegacy Short Training Field占用8us由10个短训练符号组成每个短训练符号0.8us。L-LTFLegacy Long Training Field占用8us由保护间隔1.6us加两个3.2us的长训练符号组成。L-SIGLegacy Signal Field占用4us携带速率和长度信息。之后才是数据部分以4us为一个OFDM符号。这个结构在802.11g、802.11n、802.11ac、802.11ax里一直作为“传统前导码”被保留下来新标准都是在它后面追加新的训练字段。为什么这么设计因为不同制式的设备要能在同一个信道上共处老设备至少要能识别出“有一个OFDM帧来了”这个过程靠的就是传统前导码。用术语说这叫后向兼容。2.2 从HT到HE前导码在变长同步逻辑没变到了802.11n的HT模式前导码变成这样L-STF → L-LTF → L-SIG → HT-SIG → HT-STF → HT-LTF → 数据802.11ac的VHT模式是L-STF → L-LTF → L-SIG → VHT-SIG-A → VHT-STF → VHT-LTF → VHT-SIG-B → 数据802.11ax的HE模式是L-STF → L-LTF → L-SIG → RL-SIG → HE-SIG-A → HE-STF → HE-LTF → 数据你有没有发现无论后面加了什么最前面那两个“老演员”——L-STF和L-LTF——从来没动过。原因很简单所有同步的“地基”都埋在这一段里面。后面的HT-STF、VHT-STF、HE-STF存在的意义主要是帮助接收机重新做AGC自动增益控制同时给MIMO信道估计提供参考属于“加分项”不是“必备项”。而HE-LTF、VHT-LTF这些字段是给信道估计和MIMO检测用的同步阶段一般用不到它们。我做了一个简化对比表方便你快速看各家制式的前导码差异制式前导码结构同步相关部分加粗总前导码时间802.11a/gL-STF L-LTF L-SIG20us802.11n (HT)L-STF L-LTF L-SIG HT-SIG HT-STF HT-LTF28us以上802.11ac (VHT)L-STF L-LTF L-SIG VHT-SIG-A VHT-STF VHT-LTF36us以上802.11ax (HE)L-STF L-LTF L-SIG RL-SIG HE-SIG-A HE-STF HE-LTF44us以上这里有个很容易被忽略的点L-STF和L-LTF的总时长在最老的802.11a里就是16us到了802.11ax还是16us一个字都没改。所以你在任何一台WiFi设备上抓空口包前16us的波形长得几乎一模一样。这也是为什么WiFi设备的“帧检测”和“初始同步”模块可以做成通用硬件不管后面跑的是WiFi 5还是WiFi 6。2.3 为什么长短训练序列要“一短一长”这里有个特别值得琢磨的地方为什么同步训练序列要分短和长两组原因是估计精度和估计范围之间存在矛盾。短训练符号周期短用自相关算法估算频率偏移时相位还不至于卷绕所以能估计的范围大但周期短也意味着噪声被平均得不够精度有限。长训练符号周期长同样的相位偏移对应更大的相位差精度高但周期太长时相位容易卷绕可估计的范围就小了。工程上最常用的做法就是“先粗后精”用STF估计一个粗频偏把频率拉回到较小的残差范围再用LTF做精频偏估计把残差进一步压小。这也就是为什么这两组训练序列总是成对出现。理解了这一层后面看算法公式就顺畅多了。3. 时间同步从“信号来了”到“符号边界在哪”3.1 分组检测怎么发现一帧信号来了接收机首先要解决的是“信号来了没有”的问题。在空闲信道上接收机拿到的只有高斯白噪声。如果噪声也触发后续处理那整条链路都会浪费在虚假检测上。最常见的做法是延迟自相关。利用STF的周期重复特性接收机把当前接收信号和延迟D个采样点后的信号做共轭相关累加一个滑动窗口再跟信号能量做归一化。具体公式长这样P(d) Σ_{m0}^{L-1} r*(dm) * r(dmD)R(d) Σ_{m0}^{L-1} |r(dmD)|^2M(d) |P(d)|^2 / R(d)^2当M(d)超过某个阈值比如0.5就判定有信号来了。这个算法叫延迟相关算法它不依赖具体的载波频偏大小对频偏有比较好的容忍度所以被广泛用在粗同步阶段。在802.11a的参数下20MHz带宽、64点FFTSTF一个短训练符号是16个采样点。延迟相关里的D就取16滑动窗口长度L取16或者32通常都行。窗口越长越稳但计算量越大而且对信号的多径扩展越敏感。这里我要插一句工程心得。阈值的选择很关键定太高了容易漏检帧头没抓到后面全白搭定太低了容易虚检把噪声当成信号。我在调试时习惯先用仿真扫一条“阈值—检测概率”曲线再在实际环境里微调。比如在办公室这种多径明显、干扰源多的环境下0.5的阈值就偏激进我一般会提到0.6以上。3.2 从粗定时到精定时符号边界怎么定检测到分组以后还要找到OFDM符号的边界。STF本身是周期信号自相关的峰值平台很宽没法直接给出边界。工程上先用STF自相关的峰值平台估一个粗定时点这个点大概在STF和LTF交界附近。然后进入精定时阶段。这里最常用的参考是LTF。做法有两种一种是接收信号跟本地已知的LTF序列做互相关。互相关的优点是在多径信道下有一个尖锐的相关峰峰值位置可以对应到最强路径或者首达路径。首达路径第一径这个点对符号定时的意义尤其重要后面我会仔细说。另一种是直接利用LTF内部的重复结构做自相关。这种方法不需要本地序列实现更简单但是相关峰不如互相关那么尖锐定时精度相对差一些。在实际芯片里两者经常配合使用先做粗定时把搜索范围缩小再做精定时确定到样本级别。精定时得到的采样点就是数据部分第一个OFDM符号的起始位置。从此之后接收机以64个采样点为周期逐个切出OFDM符号去掉循环前缀再做FFT。3.3 多径信道下的定时坑与保护这一节是坑最多的部分。很多初学者以为符号定时就是找相关峰的最大值实际根本不是。多径信道的冲激响应可能拖出几百纳秒如果定时点选在最强径上那么最早到达的那一径带来的能量就会被切到FFT窗口外面造成符号间干扰。正确的做法是找到“第一径”的到达时刻也就是信道冲激响应中最早的那个峰值。工程上常用两种手段一是做信道估计之后反推冲激响应找第一个显著的抽头二是利用循环前缀的特性做最大似然定时估计。802.11里的做法通常更省事因为OFDM的GI保护间隔有0.8us定时偏差只要落在GI范围内对解调的影响就很小。所以很多商用芯片也并没有追求极限而是把定时误差控制在一个采样点以内剩下的靠均衡去扛。我自己在实际调试中踩过一个坑在办公室这种多径环境里分组检测的峰值平台非常宽粗定时点要是选得太靠后后边的精定时互相关峰值就会受影响导致整体定时偏晚星座图的误差向量幅度EVM变得很差。后来我们把粗定时点往前挪了半个STF符号整套系统立刻稳定了很多。这个经验的原理是粗定时的目的是给精定时提供一个足够宽的搜索窗而不是给出最终答案所以宁可偏早不可偏晚。偏早了精定时还能把窗口拉回来偏晚了窗口直接切掉了LTF的一部分互相关峰值就废了。4. 频率同步把“跑偏”的载波拉回来4.1 载波频率偏移从哪里来载波频率偏移CFO的来源有两个一是收发两端晶体振荡器的频率不一致这是最主要的来源。便宜的晶振精度可能是±20ppm在2.4GHz频段上20ppm对应的频偏就是48kHz。对于子载波间隔只有312.5kHz的OFDM系统来说这已经是一个不可忽视的数字。CFO会造成什么后果简单说它会让接收信号在频域上发生子载波间的相互干扰ICI同时让调制符号产生相位旋转。如果不校正高阶QAM的星座图直接转成一片混沌64QAM基本没法解调。我顺手算一笔账2.4GHz下如果晶振精度是±20ppm那么最大频偏是2.4e9 × 20e-6 48kHz。如果是5GHz频段同样20ppm就是100kHz。而OFDM的子载波间隔只有312.5kHz意味着100kHz的频偏已经占了将近三分之一个子载波间隔。这种量级的频偏必须靠STF这种大范围估计算法先压下来再谈后续精调。4.2 STF粗频偏估计STF的短训练符号周期是0.8us对应16个采样点。延迟自相关的相位差可以写为Δφ_STF angle( Σ r*(n) r(nD) )CFO估计值就是Δf_STF Δφ_STF / (2π D Ts)其中Ts是采样周期。在20MHz采样率下Ts50nsD16所以分母2π×16×50ns2π×800ns2π×0.8us也就是整段STF的重复周期。STF频偏估计的可测范围是多少相位angle()的取值范围是[-π, π]换算成频率就是[-1/(2×0.8us), 1/(2×0.8us)]也就是±625kHz。这个范围覆盖了20ppm晶振在2.4GHz下产生的±48kHz频偏绰绰有余。即便在5GHz下面对±100kHz的频偏也毫无压力。频偏估计的精度跟信噪比和参与平均的符号数有关。STF有10个短符号自相关算法一般取中间的8个来做平均可以有效地压低噪声影响。这里有个小细节两端的短符号通常不用因为开头几个符号可能还在AGC收敛过程中幅度和相位都不够稳定取进来反而拉低估计质量。4.3 LTF精频偏估计STF估计完以后接收机先做一次频偏补偿把残差缩小到比如±10kHz以内。然后用到LTF来精估计。LTF的两个长训练符号结构完整重复周期是3.2us对应64个采样点。同样地Δf_LTF angle( Σ r*(n) r(nD) ) / (2π D Ts)此时D64分母2π×64×50ns2π×3.2us。可测范围就缩到了±156.25kHz。如果前面没有粗估计打底直接用LTF做估计一旦真实频偏超过±156.25kHz相位差就会卷绕估计值直接错误。但有了STF先把频偏拉回到小范围LTF就能在精度上发挥作用。为什么LTF精度高因为公式里分母大同样的相位量化误差换算成频率误差时分母在变大相对误差就小了。这个和“用长尺子量长距离误差占比更小”是同一个道理。我把STF和LTF的参数放在一起做个表方便你对比参数STFLTF重复周期0.8us16样本3.2us64样本频偏估计范围±625kHz±156.25kHz频偏估计精度较低用于粗估较高用于精估主要用途分组检测、AGC、粗频偏精定时、精频偏、信道估计5. 工程实现同步链路应该怎么搭5.1 接收机基带同步链路的基本流水线有了前面这些理论我们可以把一条典型的WiFi接收机同步流水线串起来射频前端下变频到基带ADC采样得到复数基带信号。分组检测用STF延迟自相关判断信号是否到来同时触发AGC收敛。粗频偏估计用STF估计CFO做一次频偏补偿。粗定时找到STF/LTF边界的大致位置。精频偏估计用LTF估计残余CFO再做一次精细补偿。精定时用LTF互相关或信道估计找到首径位置确定FFT窗口起点。去循环前缀FFT变换到频域。用LTF做信道估计后续数据符号做均衡、解调。这8步里第2、3步和第5、6步是时频同步的核心环节。实际芯片里分组检测和AGC往往是联动处理的因为信号到来瞬间接收增益可能不合适需要在一两个微秒内调整到合适电平。如果AGC收敛太慢STF后段的信号幅度还没稳定分组检测和粗频偏估计的质量都会下降。5.2 硬件实现里容易忽略的几个点在FPGA或者ASIC实现的时候有一些细节是仿真阶段发现不了、上板才能暴露的。第一点是定点精度。自相关累加器的位宽如果不够信噪比高的时候反而会出现截断噪声导致估计方差变大。我通常会把累加器的位宽比理论值多留4到6个比特反正FPGA里查找表资源没那么紧张。定点化以后的仿真必须做别偷懒尤其要把输入信号幅度拉到最大观察累加器有没有溢出。第二点是流水线延迟。分组检测到粗频偏估计之间是有时间差的你的频偏补偿模块必须知道自己补偿的是哪一段数据。很多新手在这里把数据对齐搞错结果频偏补偿做了个寂寞。正确做法是给数据通路上打上时间戳或者帧同步信号让补偿模块知道“当前输出的样本是帧内的第几个样本”。第三点是AGC引起的相位跳变。AGC在STF阶段可能会调整增益增益切换瞬间会带来相位突变这会破掉延迟自相关的连续性。所以高增益切换之后需要让估计模块暂时复位或者专门设计保护逻辑。你可以想象一下正在做相关累加突然中间插入一个相位跳变累加值直接偏掉。第四点是DC偏置。零中频接收机的DC偏置会严重干扰自相关结果。工程上一般会在分组检测前做高通滤波或者DC估计扣除这种问题在仿真里经常被忽略因为仿真模型里DC偏置往往是0。上了真机才发现一开机接收机看到一个巨大的直流量分组检测阈值直接被顶穿。5.3 调试技巧用星座图反向定位同步问题调同步算法最直观的方式就是把FFT之后的星座图画出来看。我有个百试百灵的经验你可以收藏一下。如果星座图整体旋转而且旋转速度基本恒定那多半是残余频偏没有估干净。你可以在星座图上量一下一个OFDM符号时间内旋转了多少角度反推频偏大小。公式很简单旋转角度除以符号时间就得到频偏。比如64QAM下4us的符号时间内星座图转了5度那频偏大概是5除以(360×4us)约等于3.47kHz这个数可以作为修正系数直接喂给补偿模块。如果星座图出现“云团”每颗星座点都糊成一团但没有明显旋转那就更可能是定时偏差或相位噪声问题这时候优先检查FFT窗口起点。试着把定时点前后挪几个样本看看EVM变化就能确认是不是定时偏了。如果星座图呈现出子载波间的串扰特征外边一圈星座点向外扩散考虑是不是残余频偏超出了允许范围或者定时偏差超出GI。这种问题通常会伴随明显的误码率抬升。如果只有特定子载波特别差那大概率是信道估计或者滤波的问题跟同步关系不大。我把这些现象整理成速查表方便你在调试时对照现象可能原因优先检查项星座图整体旋转残余CFO未补偿干净STF/LTF频偏估计结果、补偿精度星座点成团模糊定时偏差、相位噪声FFT窗口起点、本振相噪外圈星座点扩散ICI、定时超出GI残余频偏量、GI长度配置特定子载波异常信道估计/滤波问题LTF信道估计结果、接收滤波器6. 同步之后还要盯紧的那些环节6.1 采样时钟偏移的跟踪前面讲的时频同步主要解决帧头处的同步。但一个帧可能长达几百微秒甚至几毫秒采样时钟偏移SCO会随时间累积导致FFT窗口慢慢滑出GI范围同时每个符号内的相位偏移也在累积。所以真正商用的WiFi接收机都有跟踪环路。一种常见做法是在频域利用导频子载波的相位差来估计采样时钟偏移然后用内插滤波器对时域信号做重采样校正或者直接在频域做相位旋转校正。这个环节属于“同步的维护阶段”工程上和后端的载波跟踪联合在一起做。这里有个容易忽略的点SCO和CFO会同时存在而且表现类似都是随符号索引累积的相位旋转。但两者的物理来源不同对子载波索引的依赖也不同。CFO导致的相位旋转对所有子载波是一致的SCO导致的相位旋转则随子载波索引线性变化。工程上可以同时观测多个导频子载波的相位做线性拟合就能把这两个量分开。关于这一点我在实际调试中得出一个经验如果你发现导频相位在不同子载波上呈现明显的线性梯度那就是SCO在作怪不是CFO。用单频补偿去硬拉永远拉不干净。6.2 同步误差对系统性能的直接影响最后说一个系统层面的东西。时频同步的每一个误差最终都会折算到信噪比或者EVM上。粗略量化一下残余频偏每增加1kHz64QAM下的EVM会恶化接近1个dB左右定时偏差每增加0.1us在强多径下的性能损失也相当可观。所以同步做得好不好直接决定了一个WiFi芯片在弱信号和多径环境下的上限。别忘了WiFi还不只是点对点通信AP是广播的同一个信道里可能有多个终端。接收机每切换一个发送者前面的同步流程就要重来一次。所以前导码那几十个微秒真的是整个协议栈里最不能出错的部分。6.3 一个容易踩的整机坑长帧场景下的同步保持有一次我把一个短帧环境里调好的同步链路直接拿去跑长帧吞吐测试结果发现误码率在帧尾明显上升。排查了半天发现是SCO跟踪环路的收敛时间太长导致帧长超过几百us之后FFT窗口已经滑出了GI。后来把导频跟踪的带宽加大同时增加了重采样校正问题才解决。这种问题在短帧测试里完全暴露不出来因为帧长不够长误差还没累积到能看到的程度。所以做WiFi物理层的人一定记住短帧调同步是“初始同步”长帧考验的是“跟踪能力”。两者都要单独测缺一不可。我这几年调过不少WiFi相关的软硬件最深的一个体会是不管上层协议多复杂物理层的同步永远是最基础的“1”后面所有漂亮算法都是“0”。帧结构里的那段前导码看起来简简单单实际上把发射机和接收机之间所有需要协同的关键信息都编码在里面了。你越是把帧结构吃透越会发现同步算法的每一步都有据可循调试的时候也不会两眼一抹黑。希望这篇从帧结构讲起的梳理能帮你把这条链路真正走通。