微信公众号:EW Frontier
关注可了解更多的雷达、通信、人工智能相关代码。问题或建议,请公众号留言;
如果你觉得EW Frontier对你有帮助,欢迎加入我的知识星球或面包多,更多代码等你来学
知识星球:https://wx.zsxq.com/dweb2/index/group/15552518881412
面包多:https://mbd.pub/o/author-a2mYl2tsbA==/workQQ交流群:729981694
如有侵权请联系删除~
QPSK系统简介
图1 QPSK调制框图
图2 QPSK系统解调框图
定时同步
接收机要想解调出原始的发射信号,关键在于载波同步和定时同步。载波同步主要 是用来提取出载波相位差,通过不断反馈调整,得到与接收信号无频差与相差的本地相干载波信号[ 30],定时同步是用来提取出位定时信号,通过内部不断调节,找到最佳采样 点,实现重采样信号与接收模拟信号的同步。本文将介绍定时同步的设计原理。
一般有以下几种定时同步方法。
图3 定时同步的实现方法
插入导频法虽然容易实现但在数字通信系统中应用较少,这种方法还需要对导频信 号做额外的处理,增加了发送功率和频谱间的干扰,既浪费了一定的频谱资源,也浪费 了一定的功率。直接法在数字通信系统中应用较多,该类方法直接可以从接收到的基带 信号中来获得定时信息,因此直接法不需要占用频谱资源和功率,但位定时信号的提取 对于电路和算法的性能要求比较高。
早期的直接法通常采用滤波法。滤波法的原理框图如图3所示。滤波法把接收到 的基带信号进行非线性变换,使得经过变换处理的数字信号中具有一个等于符号率的离 散频率分量,然后再通过滤波器滤波、移相处理,从而获得定时信息。这个波形对应于符号速率,通常很窄,而且变换以及滤波操作都会带来延迟,因此在滤波之后还需要 进行移相操作,波形在检测过零点后,将其中任意一个过零点作为接收信号的采样定时依据,从而实现定时同步。这种方法操作较为复杂,滤波和移相的运算难度较大,而且 通常需要减小滤波器的带宽来降低噪声对信号的影响,反而会使时间暂态加大,从而影 响定时同步的性能,严重时还会出现丢失定时同步信号。
图4 滤波法原理图
另外一种直接法是比相法,比相法是直接法中应用较为广泛的一种方法,它有2个功能,一个是相位比较功能,另一个是调整功能,通过不断调整本地采样时钟的频率和 相位,来消除本地采样时钟和发送端的频偏,使信号始终保持在最佳采样时刻。根据处 理方式的不同,又可以分为2种方法。如图4所示为锁相法的结构图,锁相法是一种 直接通过改变本地时钟的频率和相位来实现定时同步的方法,在实际应用中利用反馈的 方式来调整本地时钟的频率和相位,根据定时误差检测电路来计算定时误差,将定时误 差信号送入环路滤波器滤除高频分量后,调整压控振荡器的频率和相位,以此来调整的 采样时钟的频率和相位,从而找到最佳采样时刻。锁相法的优势是可靠性较好,能使 ADC的采样时钟与接收符号在频率和相位上完全同步。但是其NCO产生的相位噪声比 较大,使得采样时钟的精度差,而且定时捕获时间较长。
图5 锁相法原理框图
内插法与锁相法的区别便在于内插法不需要改变本地时钟,ADC通过以固定的采 样率对输入信号进行采样,通过插值算法来调整内插时刻,来获取最佳采样时刻。这类 方法主要是对于滤波器的研究,下面我们主要介绍2种内插方法。
图6所示的定时同步的内插法是根据多相滤波器的,其原理是该结构有M个不 同延时的子滤波器,输入信号进入多相滤波器后,会有M种不同的相位,然后计算每个子通道的定时误差信息,通过比较M个子通道的定时误差信息,选出与最佳采样 时刻最接近的一路子滤波器的输出。该类方法通过牺牲系统的资源来换取定时同步的性 能,但性能越好也就意味着子滤波器的个数越多,整个系统的计算量也会增大,结构也 越复杂。
图6 多相滤波器的原理框图
值滤波器的定时同步方法的原理框图如图 7所示,插值滤波器的定时同步方 法包括插值滤波器、定时误差检测器(TED)、环路滤波器(LF)和数控振荡器(NCO)。
该定时同步方法的实现过程为:该闭环系统通过TED来计算定时误差,送入LF滤除误 差信号的高频分量和噪声信号,得到更新后的步长,然后进入NCO来改变内插基点, 控制内插滤波器获得最佳采样时刻,如此重复进行工作,不断进行调整,从而得到最佳 的内插点,实现重采样信号与接收模拟信号的同步。插值滤波器的定时同步方法不需要 提供额外的高频时钟,硬件资源消耗量较少,实现较为简单,定时精度相对较高,且该 方法还可以实现分数倍采样率变换,因此该方法在定时同步中应用较为广泛,本文也 是用该方法来实现定时同步的。
图7 插值滤波器的原理框图
Gardner定时误差估计算法
定时误差检测的作用类似于锁相环中的鉴相器,主要是根据内插点计算相应的位定 时误差。在Gardner算法提出之前,Mueller中提出了基于一个符号一个采样点的定时误 差检测算法,这是一种面向判决信息反馈的算法,这种算法在判决器出现解调错误时, 性能会陡然下降。Gardner定时误差估计算法是由Gardner于二十世纪八十年代提出的 一种用在BPSK和QPSK信号的定时误差信号的检测算法,后来在一些学者的改进下也 可以用在QAM中[ 53]。Gardner定时误差估计算法不需要判决信息反馈,每一个码元的 定时误差检测只需要两个采样点,其中一个出现在数据的峰值时刻,另一个出现在2个 数据峰值的中间时刻。Gardner定时误差估计算法的优点是可以独立于未知载波相位的 情况下计算定时误差,实现定时同步,并且其结构简单,因此在解调算法中得到了广泛的应用。
MATLAB代码示例
clear
clc
close all
dt = 1/88;
pi2 = 2*pi;
fid = fopen('rand_data.m','r');
source = fread(fid)';
fclose(fid);
source1 = [source zeros(1,100)];
Qpsk_sig(1,:) = 2*source1(1:2:end)-1;
Qpsk_sig(2,:) = 2*source1(2:2:end)-1;
Expand_sig = zeros(2,size(Qpsk_sig,2)*8);
Expand_sig(1,1:8:end) = Qpsk_sig(1,:);
Expand_sig(2,1:8:end) = Qpsk_sig(2,:);
coeff_5 = firrcos(28,5.5,0.25,88,'rolloff','sqrt');
Filter_sig(1,:) = conv(Expand_sig(1,:),coeff_5);
Filter_sig(2,:) = conv(Expand_sig(2,:),coeff_5);
t = [0:dt:(size(Filter_sig,2)-1)*dt];
Md_sig_c = Filter_sig(1,:).*cos(pi2*22*t) + Filter_sig(2,:).*sin(pi2*22*t);
Md_sig_s = -Filter_sig(1,:).*sin(pi2*22*t) + Filter_sig(2,:).*cos(pi2*22*t); % 与希尔伯特变换等效,
clear Filter_sig;
clear Expand_sig;
clear Qpsk_sig;
sig_stor_c = resample(Md_sig_c,8802,8800);
sig_stor_s = resample(Md_sig_s,8802,8800);
dt1 = 1/88.02;
t = [0:dt1:(length(sig_stor_s)-1)*dt1];
sig_ave_pow = (norm(sig_stor_c)^2+norm(sig_stor_s)^2)/(length(sig_stor_s));
dc_rig = zeros(1,29);
ds_rig = zeros(1,29);
decode = zeros(2,2);
count = -28;
count1 = 0;
decode_out = [];
store = [];
for i = 1:length(sig_stor_c)
count = count+1;
Md_sig_c = sig_stor_c ;
Md_sig_s = sig_stor_s;
Md_sig = Md_sig_c + Md_sig_s;
dc = Md_sig_c(i)*cos(pi2*22*t(i)) - Md_sig_s(i)*sin(pi2*22*t(i));
ds = Md_sig_c(i)*sin(pi2*22*t(i)) + Md_sig_s(i)*cos(pi2*22*t(i));
dc_rig(2:end) = dc_rig(1:end-1);
ds_rig(2:end) = ds_rig(1:end-1);
dc_rig(1) = dc;
ds_rig(1) = ds;
d_convert_c = dc_rig*coeff_5';
d_convert_s = ds_rig*coeff_5';
if mod(count,4)==1 & count>0
count1 = count1+1;
decode(1,2) = decode(1,1);
decode(2,2) = decode(2,1);
decode(1,1) = d_convert_c;
decode(2,1) = d_convert_s;
if mod(count1,2)==0
store = [store decode(1,1)];
tempt1 = decode(1,1) + decode(1,2);
tempt2 = decode(2,1) + decode(2,2);
if tempt1>0 & tempt2>0
decode_out = [decode_out 1 1];
elseif tempt1>0 & tempt2<0
decode_out = [decode_out 1 0];
elseif tempt1<0 & tempt2>0
decode_out = [decode_out 0 1];
else
decode_out = [decode_out 0 0];
end
end
end
end
err_num = 0;
err_bit = zeros(1,length(source));
for i = 1:length(source)
if decode_out(i)~=source(i)
err_num = err_num+1;
err_bit(i) = 1;
end
end
err_rate = err_num/length(source)