手把手用Python仿真通信原理考题:从匹配滤波器到MQAM星座图旋转

张开发
2026/4/21 17:26:43 15 分钟阅读

分享文章

手把手用Python仿真通信原理考题:从匹配滤波器到MQAM星座图旋转
手把手用Python仿真通信原理考题从匹配滤波器到MQAM星座图旋转通信原理作为电子信息工程的核心课程其理论抽象性常常让学习者感到困惑。当公式从黑板转移到代码编辑器那些看似晦涩的概念会突然变得清晰可触。本文将以Python为实验台带您用NumPy和Matplotlib重现经典考题中的关键场景——您将亲手绘制出匹配滤波器的脉冲响应观察相位误差如何扭曲MQAM星座图并通过蒙特卡洛仿真验证不同调制方式的误码率差异。1. 环境配置与基础工具链在开始前确保已安装Python 3.8环境并执行以下命令安装必要库pip install numpy matplotlib scipy ipython我们特别推荐使用Jupyter Notebook进行交互式实验它能实时显示图形化结果。基础工具函数库应包含以下核心组件import numpy as np import matplotlib.pyplot as plt from scipy import signal from ipywidgets import interact # 用于创建交互式控件 plt.style.use(seaborn) # 提升图形显示质量 np.random.seed(2023) # 固定随机种子保证结果可复现信号生成工具箱是后续实验的基础这里先实现几个关键函数def generate_symbols(M, schemeqam): 生成M进制的调制符号 if scheme psk: return np.exp(1j * 2 * np.pi * np.arange(M) / M) elif scheme qam: m int(np.sqrt(M)) return (np.arange(m) - (m-1)/2) 1j*(np.arange(m) - (m-1)/2)2. 匹配滤波器的时频域仿真考试中关于匹配滤波器的三个经典问题可以通过以下代码直观验证输出信号长度输入信号s(t)时长Ts经过冲激响应h(t)s(Ts-t)的匹配滤波器后输出时长应为2Ts-1峰值位置最大输出出现在tTs时刻判决时刻输出与输入信号能量成正比让我们用矩形脉冲演示这一过程Ts 1e-6 # 码元周期 fs 100e6 # 采样率 t np.arange(0, Ts, 1/fs) s_t np.ones_like(t) # 矩形脉冲 # 构建匹配滤波器 h_t s_t[::-1] # 时间反转 output np.convolve(s_t, h_t) # 可视化 plt.figure(figsize(10,4)) plt.plot(np.linspace(0, 2*Ts, len(output)), output) plt.axvline(Ts, colorr, linestyle--, label峰值时刻) plt.title(匹配滤波器输出信号) plt.xlabel(时间(s)); plt.ylabel(幅度); plt.legend()运行后会清晰看到输出信号总长度为199个采样点2Tsfs-1红色虚线标记的位置正是理论预测的峰值时刻峰值幅度等于原始信号能量面积的积分3. MQAM星座图旋转的动态演示相位误差φ对MQAM系统的影响是高频考点我们可以创建交互式演示def plot_constellation(M16, phi0): symbols generate_symbols(M, qam).flatten() rotated symbols * np.exp(1j * phi) plt.figure(figsize(6,6)) plt.scatter(np.real(symbols), np.imag(symbols), label理想星座) plt.scatter(np.real(rotated), np.imag(rotated), markerx, label旋转后) plt.axhline(0, colorgray, linestyle:) plt.axvline(0, colorgray, linestyle:) plt.title(f16QAM星座图旋转 (φ{phi:.2f}rad)) plt.xlabel(I路); plt.ylabel(Q路); plt.legend() plt.grid(True) interact(plot_constellation, M[4,16,64], phi(-np.pi/4, np.pi/4, 0.05))拖动滑块观察当φ0时星座图逆时针旋转导致相邻星座点距离减小当φ0时顺时针旋转同样会降低判决裕量极端情况下相邻点可能重叠造成误码率急剧上升4. 调制方式性能对比实验考试常要求比较MPSK与MQAM的误码性能我们通过蒙特卡洛仿真实现def monte_carlo_ser(EbN0_dB, M, scheme, trials1e5): EbN0 10**(EbN0_dB/10) EsN0 EbN0 * np.log2(M) symbols generate_symbols(M, scheme) norm_factor np.sqrt(np.mean(np.abs(symbols)**2)) symbols / norm_factor # 能量归一化 tx_symbols np.random.choice(symbols, trials) noise_power 1/(2*EsN0) noise np.sqrt(noise_power)*(np.random.randn(trials) 1j*np.random.randn(trials)) rx_symbols tx_symbols noise # 判决过程 if scheme psk: phase np.angle(rx_symbols) decision np.exp(1j * (np.round(phase*M/(2*np.pi)) * (2*np.pi/M))) else: # qam decision np.round(np.real(rx_symbols)) 1j*np.round(np.imag(rx_symbols)) return np.mean(decision ! tx_symbols) # 测试不同信噪比下的误码率 EbN0_range np.arange(0, 16, 2) ser_psk [monte_carlo_ser(x, 16, psk) for x in EbN0_range] ser_qam [monte_carlo_ser(x, 16, qam) for x in EbN0_range] plt.semilogy(EbN0_range, ser_psk, o-, label16PSK) plt.semilogy(EbN0_range, ser_qam, s-, label16QAM) plt.xlabel(Eb/N0 (dB)); plt.ylabel(误码率) plt.title(不同调制方式性能对比); plt.grid(True); plt.legend()实验结果验证了两个重要结论在相同M值时MQAM的功率效率高于MPSK随着M增大MQAM的优势更加明显可尝试修改M64对比5. 眼图生成与码间串扰分析针对考题中关于眼图的描述我们可以模拟不同滚降系数下的眼图变化def plot_eye_diagram(alpha0.5, M4): bits np.random.randint(0, M, 1000) symbols 2*bits - (M-1) # PAM调制 t_symbol np.linspace(-3, 3, 600) h_rc np.sinc(t_symbol) * np.cos(np.pi*alpha*t_symbol) / (1 - (2*alpha*t_symbol)**2) h_rc[np.abs(t_symbol) 1/(2*alpha)] (np.pi/4)*np.sinc(1/(2*alpha)) # 处理奇异点 # 脉冲成型 t_total np.arange(0, 1000*600) signal_up np.zeros(1000*600) signal_up[::600] symbols signal_out np.convolve(signal_up, h_rc, modesame) # 绘制眼图 plt.figure(figsize(10,6)) for i in range(10, 30): segment signal_out[i*600 : (i2)*600] plt.plot(np.linspace(0,2,600), segment, b-, alpha0.3) plt.title(fM{M} PAM眼图 (α{alpha})) plt.xlabel(归一化时间); plt.ylabel(幅度) plt.grid(True) interact(plot_eye_diagram, alpha(0, 1, 0.1), M[2,4,8])通过调整滚降系数α可以观察到α0时理想低通眼图张开度最大但对定时误差敏感α增大时系统对定时误差的容忍度提高但带宽需求增加M增大时眼图中可见的眼睛数量确实为M-1个6. 载波同步中的相位模糊问题最后我们验证QPSK系统中4次方环法的相位模糊概率。通过跟踪环路的稳态相位可以统计def phase_ambiguity_test(trials1000): results [] for _ in range(trials): theta np.random.uniform(0, 2*np.pi) # 初始相位 # 4次方环稳态相位 theta_hat (np.round(4*theta/(2*np.pi)) % 4) * (2*np.pi/4) results.append(theta_hat - theta) unique_errors np.unique(np.round(results, 3)) print(出现的相位误差:, unique_errors) print(相位模糊概率:, np.sum(np.abs(results) 1e-3)/trials) phase_ambiguity_test()多次运行统计可验证可能的稳态相位误差确实只有0、π/2、π、3π/2四种情况出现相位模糊即非零误差的概率稳定在3/4左右这与考题中的选项完全吻合

更多文章