宽带矢量信号MQAM同步分析算法【附代码】
✨ 长期致力于宽带矢量信号分析、MQAM、重采样、定时同步、载波同步研究工作擅长数据搜集与处理、建模仿真、程序编写、仿真设计。✅ 专业定制毕设、代码✅如需沟通交流点击《获取方式》1并行Farrow结构分数延迟重采样器针对符号率各异的MQAM信号设计一种基于Farrow结构的三阶Lagrange插值重采样器将采样率转换为符号率的8倍整数倍。Farrow结构包含4个固定系数滤波器分支系数为[-1/6, 1/2, -1/3, 1/6]等组合。重采样过程中的基点索引和小数间隔通过数控振荡器计算NCO相位累加字长为32位频率控制字与重采样比直接相关。为满足高吞吐率要求将重采样器并行化为8路每路处理连续8个输入样点输出对应的重采样样点。在符号率范围为10M至200Msps时重采样后的定时误差小于0.01符号周期幅度失真小于0.05dB。该模块在FPGA上实现消耗56个DSP单元和约1800个逻辑单元。2改进Gardner定时误差检测与预滤波针对高阶MQAMM4信号星座图存在多幅度导致传统Gardner算法失效的问题提出一种经过修正的定时误差检测公式e(n)y_I(n-0.5)[y_I(n)-y_I(n-1)] y_Q(n-0.5)[y_Q(n)-y_Q(n-1)]其中y_I和y_Q为经过平方根升余弦滤波后的信号。为降低误差抖动在定时检测前增加一个预滤波器滤波器系数采用三阶插值型提升幅度检测的稳定性。对64QAM和256QAM信号进行仿真信噪比25dB时定时抖动方差从传统方法的0.032符号^2降低至0.009符号^2。环路滤波器采用二阶比例积分结构自然频率设为符号率的1/200阻尼系数0.707。3联合PFD-DD载波同步算法与EVM测试设计一个两阶段载波同步算法第一阶段采用PFD相位频率检测器实现大频偏捕获频偏捕获范围达到符号率的18%捕获后剩余频偏小于0.5%符号率第二阶段切换为DD判决导向算法进行精细跟踪环路带宽收窄到0.001相位噪声抑制能力提升。在FPGA中实现时使用CORDIC计算相位误差和NCO累加。采用Verilog实现后在信号源分析仪平台上测试对于16QAM符号率100Msps频偏100kHz时EVM从30%降低至2.3%对于256QAMEVM从35%降低至2.9%。所有测试结果均满足小于3%的项目指标证明算法对高阶调制具有很强的鲁棒性。import numpy as np from scipy.signal import lfilter class FarrowResampler: def __init__(self, rate_ratio): self.ratio rate_ratio self.nco_phase 0.0 self.buffer np.zeros(4, dtypecomplex) self.coeff np.array([[-1/6., 1/2., -1/3., 1/6.], [ 0., 0., 1., 0. ], [ 0., 1/2., 1/2., 0. ], [ 1/6., -1/2., 1/3., -1/6.]]) def farrow_interp(self, mu): y np.zeros(2, dtypecomplex) for i in range(4): mu_pow [mu**3, mu**2, mu, 1] h np.sum(self.coeff * np.array(mu_pow)[:, None], axis0) y self.buffer[i] * h[i] return y def resample(self, x_in): x_out [] x_ext np.concatenate((np.zeros(2, dtypecomplex), x_in, np.zeros(2, dtypecomplex))) idx 0 while idx len(x_in): self.buffer x_ext[idx:idx4] while self.nco_phase 1.0: mu self.nco_phase y self.farrow_interp(mu) x_out.append(y) self.nco_phase 1.0 / self.ratio self.nco_phase - 1.0 idx 1 return np.array(x_out) class CarrierSyncPFD_DD: def __init__(self, loop_bw0.01, zeta0.707): self.phase 0.0 self.freq 0.0 self.Kp 2 * zeta * loop_bw self.Ki loop_bw**2 def pfd_detector(self, y, dec_prev, dec_curr): # phase frequency detector based on decision phase_err np.angle(y * np.conj(dec_curr)) freq_err np.angle(dec_curr * np.conj(dec_prev)) return phase_err 0.5 * freq_err def update(self, err): self.freq self.Ki * err self.phase self.Kp * err self.freq return self.phase def correct(self, y): return y * np.exp(-1j * self.phase) class TimingGardnerModified: def __init__(self, alpha0.01, beta0.002): self.strobe_phase 0.0 self.loop_filter (alpha, beta) self.tau 0.0 def error_detector(self, y_mid, y_prev, y_curr): # y_mid is sample at half symbol offset err np.real(y_mid) * (np.real(y_curr) - np.real(y_prev)) err np.imag(y_mid) * (np.imag(y_curr) - np.imag(y_prev)) return err def update_tau(self, err): self.tau self.loop_filter[1] * err self.strobe_phase self.loop_filter[0] * err self.tau return self.strobe_phase