十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

从正交解调理解IQ信号:数字下变频与复数采样的核心原理

从正交解调理解IQ信号:数字下变频与复数采样的核心原理 简介这份PDF从正交解调的角度系统讲解IQ信号的产生与处理方法面向通信、雷达及信号处理领域的初学者和工程师帮助读者理清解析信号、同相分量与正交分量的物理含义。内容从基带实信号的解析变换出发说明为何实信号的正频率分量对应一个复信号并自然引出IQ信号的定义。资源以直接数字混频法为主线结合I/Q两路混频、低通滤波等公式推导演示中频信号如何转换为基带解析信号同时对比FFT法、希尔伯特变换法、数字内插法等常见正交解调方式的适用性与优缺点并附有FFT去负频谱并IFFT恢复解析信号的示例代码片段便于理解实现思路。包内为1个PDF文档大小264KB内容精炼、可编辑适合快速查阅与随手修改笔记。已有270人学习下载可作为信号处理课程或项目实践中的入门参考与复习资料。1. 正交解调是理解 IQ 信号的必经之路拿到一本标题叫《从正交解调来理解 IQ 信号》的资料最容易被绕进去的不是复指数公式而是为什么一个本来连续的实信号偏要拆成 I、Q 两条路来存。因为直接用 ADC 采出来的电压波形是实信号频谱左右对称搬完中频以后只剩余弦分量目标在本振上边还是下边单靠它是分不清的IQ 信号把两路分别写成复数的实部和虚部正交解调用两路 90° 相差的本振分别混频最后得到一组带频率方向的复数基带。搞懂这个过程软件无线电里那些复数采样率、频谱仪的 IQ 导出、镜像抑制校准就都能串起来了。后面的篇幅按频谱 → 数字下变频 → 实际参数 → 瞬时频率测量的顺序展开正适合你一边看资料一边手边还有一块能抓 IQ 的板卡。2. 由实变复IQ 信号的正负频率与双路采样2.1 实频谱的左右对称是相位丢失的根源任何一个实数信号对它做傅里叶变换频谱的实部是偶对称的所以你在屏幕上总能同时看到正频率和负频率两个峰。取一个最普通的余弦x(t) cos(2πfc t)它的频域表示是0.5δ(f − fc) 0.5δ(f fc)。这意味着当我们只能得到实电压样本时观察者连“信号究竟是 −fc 还是 fc”都区分不开只能看到两个等幅的峰。这种对称性放进混频里就变成了现实问题。设本振频率为 fLO一个真正的硬件乘法器计算的是x(t)·cos(2πfLO t)它在频域里把原信号的频谱同时向左右搬移fc和−fc各自产生两个镜像副本。如果目标信号低于本振 1 MHz混频产物是cos(2π·1M·t)如果目标信号高于本振 1 MHz混频产物还是cos(2π·1M·t)。输出波形完全相同你根本无法判断原始信号在本振的哪一侧。这正是单路采样丢失相位信息的表现。要对信号做正交解调第一个要接受的事实是想要分辨正负频率接收链路就必须具备“两路正交样本”一路是 I一路是 Q合起来是一个复数。复数样本的频谱不必对称正负频率可以携带完全不同的分量方向信息因此在基带保留下来。2.2 本振两路相差 90°解调输出才带相位方向正交解调的经典结构并不复杂。本振同时产生两路信号一路是cos(ωLO t)另一路是相位滞后 90° 的−sin(ωLO t)。输入射频信号分别与这两路相乘再各过一个低通滤波器得到I(t) LPF{ x(t) · 2cos(ωLO t) }Q(t) LPF{ x(t) · (−2sin(ωLO t)) }把这两路合成复数基带z(t) I(t) jQ(t)可以得到一个非常干净的形式z(t) A(t) e^{j(φ(t) Δω t)}。其中Δω ωsignal − ωLO它的正负直接决定复平面上矢量的旋转方向。Δω为正时复数序列绕着单位圆逆时针旋转为负时顺时针旋转。有了这个旋转方向我们就比单路下变频多拿到了“目标在本振之上还是之下”的信息。同样重要的是图像抑制。单路实混频会产生镜频而正交结构在数学上等价于把输入信号乘上一个复指数e^{−jωLO t}。这个复指数只包含负频率频谱搬移只有单边和实混频的双边搬移有本质区别。镜像不是靠滤波器压掉的而是在正交结构里被复数运算抵消掉了。理解这一点再看后面厂商文档里写“镜像抑制 60 dB”“I/Q 不平衡校准”就知道他们校准的对象是两条模拟链路的增益、相位误差而不是某个模拟滤波器。2.3 数字 IQ 序列是交错的不是两个独立采样通道从 ADC 或数字中频板读出来的 IQ 数据绝大多数不是两个分离的缓冲区而是按采样点交错排列的一段连续整数流先一个 I 样本再一个 Q 样本接着再一个 I 样本如此反复。软件无线电里常见的 16-bit 交错 IQ 格式在文件里看起来就像一堆无规律的 int16但它的真实结构是复数的实部虚部交替出现。把交错数据还原成可用复数序列一个干净的 NumPy 做法是import numpy as np raw np.fromfile(capture.iq, dtypenp.int16) # 丢弃末尾不成对的采样点 raw raw[: len(raw) // 2 * 2] iq raw.reshape(-1, 2).astype(np.float32) samples (iq[:, 0] 1j * iq[:, 1]) / 32768.0这段代码先把原始字节流按两个数一组切开第一列是 I第二列是 Q然后重新组合成复数数组。除以 32768 是把 16-bit 满量程归一化到 ±1.0方便后续做 FFT 和幅度计算。注意reshape(-1,2)的顺序如果文件里实际是“Q 在前、I 在后”的格式频谱会左右翻转这正是调试中最容易看走眼的地方。这里有一个表格式的理解方式值得反复对照存储形态代表的数学含义频谱效果一路实数 ADC 样本只有实部频谱必然左右对称I、Q 两路交错序列复数的实部与虚部正负频率可携带不同内容I、Q 分开两个文件同一复数序列的两次导出还原后与本表第一行等价还要注意采样率的表述。对实信号采样奈奎斯特界限是fs/2对 IQ 复数序列采样正负频率各占一边可用带宽实际上是从−fs/2到fs/2的整个fs。很多工程师把“复数采样率是 2 MHz”理解成“只能容纳 1 MHz 带宽”这是把实采样的习惯套到了复数头上。后面第 4 章会专门展开这个问题。3. 用 Python 实现正交解调一份可跑的最小数字下变频3.1 构造一条实中频信号并做复数混频理解正交解调最快的路径是把一条模拟链路里的“模拟本振混频 低通”在 Python 里用数字方式重做一遍。这个过程在 FPGA 里叫数字下变频在仪器里叫 I/Q 解调数学内核是同一个复数乘法。先构造一条 20 MHz 采样率下的实信号里面有两个载波分量一个在 2.62 MHz另一个在 1.72 MHz。它们被合进同一条电压曲线模拟从射频前端送来的中频信号import numpy as np from scipy.signal import butter, lfilter fs 20e6 # 采样率 20 MHz n 4096 # 捕获点数 t np.arange(n) / fs # 两条载波一个高于本振一个低于本振 x (0.8 * np.cos(2 * np.pi * 2.62e6 * t) 0.4 * np.cos(2 * np.pi * 1.72e6 * t)) f_lo 1.92e6 # 数字本振频率 # 复数混频相当于乘上 e^{-j * 2π * f_lo * t} z x * np.exp(-2j * np.pi * f_lo * t)乘法器的指数部分是-2j对应的物理含义是把整段频谱向左搬移 1.92 MHz。搬完之后2.62 MHz 分量落在700 kHz1.72 MHz 分量落在−200 kHz。两个原始频率在本振一高一低混频后分别在基带的正频率和负频率出现方向信息被完整保留。如果这里把指数符号写成2j频谱就会向右搬移I、Q 的旋转方向翻转等于把上下边带对调。3.2 低通滤波和抽取把复数信号瘦下来混频后的z仍然带着 2.62 MHz 1.92 MHz附近的和频分量这些不需要的高频分量要滤掉。正交解调里的低通一般由两部分组成前面一级可以用 CIC 做粗抽取后面补偿均衡用 FIR。在 Python 里验证原理直接用一阶 Butterworth 就够了重点看滤波和抽取的关系# 截止频率 900 kHz换算成归一化频率 cut 900_000 / (fs / 2) b, a butter(4, cut) # 先滤波后抽取抽取因子 10 z_lp lfilter(b, a, z) z_iq z_lp[::10] # 输出采样率 2 MHz这样处理后输出的z_iq就是标准的 I/Q 复数基带序列采样率从 20 MHz 降到 2 MHz。抽取因子 10 不是随便定的它要求降采样后的采样率仍然大于基带信号带宽的两倍不过对复数信号这个带宽是从−fs/2到fs/2的整段fs。滤波器的截止频率应当压住不需要的镜像带和邻道同时保留有用信号。几个关键参数的权衡关系用表格列出来比较清楚参数示例值作用设错的表现本振频率 f_lo1.92 MHz决定把哪段频带搬到基带目标频率落出滤波通带信号消失在底噪里低通截止频率900 kHz滤除混频和频分量和镜像带截止过低会削掉信号边带过高会带入邻道干扰抽取因子 D10把 20 MHz 降为 2 MHzD 过大时有用信号反折混叠频谱变得杂乱在真实板上抽取通常会拆成多级避免单级抽取的抗混叠滤波器阶数过高。软件里跑这一版只是为了把“正交解调到底在算什么”看清楚混频把频谱搬正低通把不要的复本滤掉抽取把冗余采样点去掉。3.3 从复数谱判断目标在本振上还是下滤波抽取后的复数序列FFT 之后会同时出现700 kHz和−200 kHz两个峰。有人看到负频率峰会本能地认为它是正频率峰的镜像这是对 IQ 数据最常见的误读。这两个峰分别来自最初构造信号里的两个真实载波它们的符号不同恰好说明复数谱有方向分辨能力。验证方法很简单对z_iq做一次加窗 FFT观察峰值位置。若峰值在正频率说明原始载波高于本振若在负频率说明原始载波低于本振。正负频率可以同时存在有意义的分量这正是 IQ 信号带来的额外维度。做正交解调时我习惯先把这行验证跑通再去看自动增益控制、直流偏置这些二阶问题。from numpy.fft import fft, fftfreq win np.hanning(len(z_iq)) sp fft(z_iq * win, n2048) freq fftfreq(2048, 1 / 2e6) # 2 MHz 采样率 peak_idx np.argsort(np.abs(sp))[-3:] print(freq[peak_idx] / 1e3) # 单位 kHz看到结果里一个接近 700、一个接近 −200就说明整个正交解调链路方向正确、符号约定也没有被翻转。如果两个峰都出现在同一边或者 700 kHz 峰消失优先检查复数混频的指数符号和存储文件的 I/Q 排列顺序。4. 把 IQ 搬到真实处境复数带宽、失衡校正和文件校验4.1 复数采样率下可用带宽是 fs 而不是 fs/2接收机把一个宽带信号下变频到基带后输出的复数序列每个采样点含两个实数I 和 Q。因为复数信号的频谱不必对称正频率和负频率都可以独立承载信息所以理论可用带宽是从−fs/2到fs/2总宽度为fs。这是 IQ 数据与实采样数据最容易被混淆的地方。举个例子某频谱仪用 200 MHz 的复数采样率导出 IQ 数据你可以在频谱上同时看到 −100 MHz 到 100 MHz 的完整范围。若把同样长度的数据当作“普通实采样”去理解有人会认为带宽只有 100 MHz并把这 100 MHz 解释成对称镜像。实际上IQ 流里负半轴是独立的边带不是正半轴的倒影。这个特性让数字中频板可以用较低采样率覆盖整个信道带宽而不像实采样那样被迫把采样率抬到两倍以上。采样类型每个样本字节数可表示带宽镜像特性实信号采样1 个实数0 到 fs/2正负频率必然对称I/Q 复数采样2 个实数−fs/2 到 fs/2正负频率互相独立在配置接收链路时我一般先看是“复数带宽”还是“实带宽”再决定 DDC 的抽取率。很多采购和联调冲突最后都归到这一条厂商标称 20 MHz 带宽通常指的是复数采样后的总带宽实际基带范围是 ±10 MHz而不是 0 到 20 MHz。4.2 I/Q 不平衡镜频残留的实测来源理想情况下I、Q 两路增益完全一致、相位差精确为 90°但模拟链路总会存在误差。增益误差让两路幅度不等相位误差让 Q 路不是严格的 90°直流偏置则会在零频处产生一个尖峰。这些误差的直接后果是镜像抑制指标下降本应被抵消的镜像频率没有完全消掉在频谱上出现在信号关于本振对称的位置。对于窄带信号可以用一个简单的最小均方校正来补偿增益和相位误差。假设从采集里先估计出归一化系数再对 Q 路做修正g np.sqrt(np.mean(q * q) / np.mean(i * i)) phi -np.mean(i * q) / np.mean(i * i) i_c i.copy() q_c (q - phi * i) / gg是两路功率差的平方根补偿增益phi把 Q 里与 I 相关的泄漏分量剔除掉补偿相位。这个公式只适合窄带场景宽带接收机的不平衡是随频率变化的真正的商用方案会做频率相关校准。但验证一个采集系统是否正常这个小修正常常能把由布线不对称引入的镜像峰压掉十几 dB。校准效果怎么看注入一个已知单音例如高于本振 1 MHz然后看−1 MHz处的残余电平。它相对于主信号的 dB 差就是当前链路的镜像抑制。做这项测试时注意信号源要接在接收机前端之前不能拿接收机自己生成的校准源凑合否则校准环路里没有包含真正的模拟失配。4.3 未知 IQ 捕获文件先判断交错格式调试现场经常遇到打开文件发现一堆乱码的情况。拿到未知格式的 IQ 数据我通常先做两件事第一确认它是 8-bit、16-bit、32-bit 还是浮点第二确认 I、Q 是交错存储还是分文件存储。数值类型的判断可以看文件大小与理论捕获时长的比例交错顺序则只能靠还原后看频谱的特征来反推。前面第 2 章已经给出过一个还原代码这里补一个更稳妥的版本顺带说明字节序raw np.fromfile(capture.iq, dtypei2) # 小端 int16 raw raw[: len(raw) // 2 * 2] iq raw.reshape(-1, 2).astype(np.float32) iq (iq[:, 0] 1j * iq[:, 1]) / 32768.0把 dtype 写成i2是明确要求小端序。多数 x86 平台默认就是小端但遇到嵌入式采集设备时对方可能输出大端这时频谱会变成镜像翻转。如果 FFT 结果在某个频率附近出现两条等距谱线并且间隔正好是信号频率的两倍那大概率就是 I/Q 顺序颠倒而不是信号真的有两个边带。做一个简单的判断把 I、Q 交换即1j * iq[:,0] iq[:,1]再重新观察频谱若镜像峰消失说明文件顺序恰好相反。5. 从 IQ 信号求瞬时频率一趟走得通的解调自检5.1 用 unwrap 和差分恢复瞬时频率正交解调之后的复数序列幅度包络和瞬时相位都被保留下来。幅度可以直接取模相位则要对复数取角度再解开跳变才能进一步求瞬时频率。下面是常用的一组操作phase np.unwrap(np.angle(z_iq)) inst_f np.diff(phase) * fs_out / (2 * np.pi)np.angle返回的是[−π, π]区间的主值相位在跨过 ±π 时会发生跳变直接做差分会看到尖刺所以必须先unwrap把相位展平。差分之后每个点代表相邻两个采样之间的相位增量再乘以fs_out / 2π就换成了赫兹。注意diff会让结果比原序列短一个点使用时要对齐时间轴。5.2 用瞬时频率判断边带方向一个收尾技巧瞬时频率最大的价值不是替代 FFT而是解决 FFT 只能看“有没有”不能看“怎么变”的问题。实测中我常用它来快速验证本振摆放位置是否正确对一个已知载波做解调算出inst_f的均值均值是正数说明信号原本在本振之上负数则在本振之下。对 IQ 文件做校验时这个判断比盯着频谱图数峰更直接尤其面对的是窄带突发信号时瞬时频率曲线能明确标出开始和结束时刻。另一个实用场景是频率调制信号。FM 信号的 IQ 解调结果瞬时频率就是基带调制波形的直接映射。你不需要再做任何载波恢复或锁相环直接从解调后的相位差分里把调制信息读出来。过程中要注意unwrap引入的累积误差如果信号信噪比很低相位噪声会让瞬时频率大幅抖动这时可以加一个短窗平滑但不要用过低的截止频率否则会把合法的频率调制也削掉。这套流程走通之后“正交解调理解 IQ 信号”就不再停留在公式层面拿到一段 IQ 文件混频、滤波、抽取、看相位差分一个标准的下变频测量链路就搭起来了。本文还有配套的精品资源点击获取
返回列表