文章目录
1 接收机扩频码捕获及跟踪
1.1 捕获跟踪原理
(1)问题描述
直扩通信系统中,接收机开机后并不知道接收信号的起始位置,因此需要进行扩频码的同步,通常利用扩频码良好的自相关特性来遍历各相位,通过本地扩频码相位与接收信号对准,实现接收信号的捕获,进而持续跟踪。
下图为接收信号与本地扩频码相偏示意图,当存在相偏时,由于扩频码的自相关仅在延迟为0时达到峰值、其他延迟处始终保持很低的水平,因此无法对接收信号进行正确解调,必须通过调整本地码的相位来实现相偏纠正。
图 1-15接收信号与本地扩频码相偏示意图
通常伪码同步流程描述如图 1-16所示。首先进行扩频码捕获,捕获上后进入跟踪阶段,持续对扩频码相位进行调整,并判断是否失步,如果失步则重新搜索。
图 1-16 伪码同步流程图
(2)扩频码捕获
扩频码自同步捕获法主要有三种方式:串行搜索捕获法、并行搜索捕获法和匹配滤波器捕获法。
①串行搜索捕获法
图 1-17 串行搜索捕获框图
即滑动相关法,将接收的扩频信号与本地产生的扩频码序列在一个扩频码周期内进行自相关运算。若积分器的输出信号幅度很小,说明本地扩频码序列与接收的扩频码序列尚未同步,这时控制本地扩频码发生器,将扩频码相位移动1/2个码片;若积分器出现峰值并大于预设的阈值,此时本地扩频码序列与接收序列相位差小于1/2个扩频码码片,捕获成功。
②并行搜索捕获法
图 1-18 串行搜索捕获框图
并行搜索捕获法是在本地产生 2N 个不同相位的扩频码序列,每一个扩频码序 列比前一个序列的相位滞后Tc/2。2N个相关器使用本地扩频码序列的不同相位,这样只做一次相关运算就能穷尽接收扩频码序列的相位,且自相关值最大的一路即为接收扩频码的初始相位。
③匹配滤波器捕获法
匹配滤波器捕获更为高效,它具有编程灵活等优点,并且满足数字通信系统低功耗、高性能的要求,因此获得了较多的应用。基带数字匹配滤波器多应用于经过高放、混频器以及载波解调处理后的基带信号的扩频码捕获,它由移位寄存器组、乘法器和加法器组成。基带扩频信号被送入N级移位寄存器,与周期为N的扩频序列进行匹配。基带数字匹配滤波器的结构框图如下图所示。
图 1-19 基带匹配滤波器捕获法框图
表 1 4 扩频信号3种捕获方法比较
捕获方法 | 串行搜索 | 并行搜索 | 匹配滤波 |
捕获速度 | 最小同步时间 N T c NT_c NTc 最大同步时间 2 N 2 T c 2N^2T_c 2N2Tc | N T c NT_c NTc | N T c NT_c NTc |
硬件复杂度 | 1个相关器 | 2 N N N个相关器 | N N N级FIR滤波器 |
表 1 4给出扩频信号3种捕获方法的捕获速度及意见复杂度比较(针对IQ双路)。由上表可知,串行搜索捕获速度最慢,并行搜索和匹配滤波速度最快(匹配滤波速度与装载扩频信号到N级移位寄存器所需时间有关),硬件复杂度上串行搜索复杂度最低,并行搜索复杂度最高,匹配滤波复杂度适中。 |
(3)扩频码跟踪
当伪码捕获完成后,通常本地伪码与接收信号之间相位误差在1个码元之内。但这一误差通常会随着外界环境干扰发生变化,还需要时刻进行相位对其,确保相位误差始终在很小范围内,保证后续解调正确。通常采用延迟锁相环跟踪法进行调整。
图 1-20 非相干延迟锁相环结构框图
1.2 仿真实验
(1)扩频码捕获
仿真在基带进行,假设不存在频偏、多普勒等。
表 1 5 DS-BPSK信号扩频码捕获仿真参数表
数据速率 | 20 KHz |
扩频因子 | 500 |
仿真时间 | 10 ms |
信噪比 | 10 dB |
接收信号初始相偏 | 5 chip |
本地码相位调整精度 | 1 chip |
捕获门限 | 250 |
①串行搜索捕获法
滑动相关本地扩频码,当未达到捕获门限时,码相位增加,直至在第5个符号结尾处达超过捕获门限,完成捕获。
②并行搜索捕获法
由N个循环移位的扩频码组成N个相关器,同时对接收信号进行相关,输出最大相关值对应的扩频码相位。在1个符号周期即完成捕获并输出本地码相位为5。
③匹配滤波器捕获法
通过阶数为500的FIR滤波器,系数为扩频码的转置。得到输出结果,在码片位置为505处输出超过捕获门限的值,也即得到相位偏移为5 chip。
④3种捕获方法比较
串行搜索在第5个符号结束处输出峰值,并行搜索在第1个符号处即输出峰值,匹配滤波在第505个Chip处(约为1个符号周期)输出峰值。显然在实验中,串行搜索速度最慢,并行搜索和匹配滤波速度最快。
扩频码跟踪
仿真在基带进行,假设不存在频偏、多普勒等。假设接收信号4倍过采样,捕获阶段相位调整精度为1/2个码片,跟踪阶段相位调整精度为1/4个码片。
表 1 6 DS-BPSK信号扩频码捕获仿真参数表
数据速率 | 20 KHz |
扩频因子 | 500 |
仿真时间 | 10 ms |
信噪比 | 10 dB |
接收信号AD采样精度 | 1/4 chip |
接收信号初始相偏 | 123/4 chip |
捕获阶段本地码相位调整精度 | 1/2 chip |
跟踪阶段本地码相位调整精度 | 1/4 chip |
捕获门限 | 250 |
根据同步逻辑,首先进行粗同步,也即捕获。采用滑动相关法,经过61个符号周期达到捕获门限,输出捕获标志位,同时得到初始相位估计为122/4,与123/4的相偏相差1/4个码片,转入跟踪环路进行精同步。
精同步采用非相干延迟锁相环结构,由捕获阶段输出的相位作为本地扩频码生成的起始相位,分别向后偏移1/4个码片得到超前支路扩频码,向前偏移1/4个码片得到滞后支路扩频码,分别与接收信号相关,得到超前支路积分和滞后支路积分,两者作差后进行判断,当超前支路积分绝对值大于滞后支路绝对值,则相位加1,反之减1,当两者积分相等,则相位保持不变。结果如图 1 26所示,相位很快收敛到123/4个码片并保持稳定,与初始的接收信号相对相偏一致。实时调整的本地码相位控制本地码生成器,与接收信号相关,得到稳定输出的积分结果,即为解扩结果。
另外,通过超前支路与滞后支路与扩频码相关结果及作差,得到图 1 27中所示鉴相曲线,可以发现当鉴相曲线取值为0时对应的延迟值即为初始相偏123/4 chip。
2 代码
2.1 扩频码捕获
clear;close all;
%-------------------------基带扩频系统参数设置-------------------------------%
rb = 20000; %扩频前的数据速率/bit/s 20k
SF = 500; %扩频倍数
Rb = rb*SF; %扩频后的码片速率/Mc/s
Tsum = 10; %仿真时间/ms
bits_num = rb*Tsum/1000;
SNR = 10; %仿真信噪比/dB
%% 发射机部分
%----------------------------m 序列产生模块---------------------------------%
%产生m序列
load Coef.mat
n = floor(log2(SF))+2;%m序列的长度
fx = (de2bi(base2dec(Coef.Ci(n-2),8),n+1,2));
fx = fliplr(fx(1:end-1));
reg = [zeros(1,n-1) 1]; %移位寄存器的初始状态
mseq = zeros(n,1);
mseq(1)= reg(n);
N = 2^(n-1)-1;
for i = 2:N
regTemp = zeros(1,n);
regTemp(1)= mod(sum(fx.*reg),2);
for j = 2:n
regTemp(j)= reg(j-1);
end
reg = regTemp; %移位后的寄存器
mseq(i) = reg(n); %新的寄存器输出
end
mseq = 1-2*mseq(1:SF);% 1->-1 0->1
mseq_rp = reshape(repmat(mseq',bits_num,1)',bits_num*SF,1);
% figure;subplot(211);stairs(mseq);subplot(212);stairs(mseq_rp);
% figure;xc = xcorr(mseq);plot(xc);
%------------------------------BPSK编码-----------------------------------%
bits = randi(2,bits_num,1); %仿真比特数据 0 1
CFdata = 2*bits-3;%bpsk 调制 2->1 1->-1
%-------------------------------扩频:1 扩 SF--------------------------------%
CFdata_os = reshape(repmat(CFdata',SF,1),length(CFdata)*SF,1);
DS_data = CFdata_os' .* mseq_rp'; %信道部分,只仿真到中频,不考虑射频部分
%% 接收机部分
CodePhaseShift = 5; % 码相位偏移
DS_data_rx = [2*randi(2,1,CodePhaseShift)-3,DS_data(1:end - CodePhaseShift)];% 偏移位置前扩充随机信号
DS_data_rx = awgn(DS_data_rx,20,'measured'); % AWGN信道
mseq_rec = mseq;% 本地扩频码
%------------------------------串行搜索-----------------------------------%
Inte = zeros(bits_num,1);
flagCapture = zeros(bits_num,1);
CodePhaseShiftLocal = 0;
CodPhaseShiftRec = zeros(bits_num,1);
for i = 1:bits_num
CodPhaseShiftRec(i) = CodePhaseShiftLocal;
mseq_local = [mseq_rec(SF-CodePhaseShiftLocal+1:SF);mseq_rec(1:SF-CodePhaseShiftLocal)];
Inte(i) = abs(DS_data_rx((i-1)*SF+1:i*SF)*mseq_local);
if abs(Inte(i))>=250
flagCapture(i) = 1;
else
CodePhaseShiftLocal = CodePhaseShiftLocal+1;
end
end
figure;set(gcf,'Color','w','Position',[400 300 400 400]);
subplot(311);stairs(Inte,'b','LineWidth',0.7);ylim([-50 1.2*SF]);xlim([0,15]);xticks([0 5 10 15]);
title('\fontname{宋体}串行搜索积分');ylabel('\fontname{宋体}自相关值');
subplot(312);stairs(CodPhaseShiftRec,'b','LineWidth',0.7);ylim([-1,CodePhaseShift+1]);xlim([0,15]);
title('\fontname{宋体}串行搜索相位偏移');ylabel('\fontname{宋体}相位偏移');
subplot(313);stairs(flagCapture,'b','LineWidth',0.7);ylim([-0.2,1.2]);xlim([0,15]);
title('\fontname{宋体}捕获标志位');xlabel('\it{i}')
%------------------------------并行搜索-----------------------------------%
mseq_local_Array = zeros(SF,SF);
for j = 1:SF
shift = j-1;
mseq_local_Array(:,j) = [mseq_rec(SF-shift+1:SF);mseq_rec(1:SF-shift)];
end
IntePar = zeros(bits_num,SF);
InteMax = zeros(bits_num,1);
flagCapturePar = zeros(bits_num,1);
PhaseRec = zeros(bits_num,1);
for i = 1:bits_num
for j = 1:SF
IntePar(i,j) = abs(DS_data_rx((i-1)*SF+1:i*SF)*mseq_local_Array(:,j));
end
InteMax(i) = max(abs(IntePar(i,:)));
PhaseRec(i) = find(abs(IntePar(i,:)) == InteMax(i)) - 1; % 初始相偏0
if abs(InteMax(i))>=250
flagCapturePar(i) = 1;
end
end
figure;set(gcf,'Color','w','Position',[400 300 400 400]);
subplot(311);stairs(InteMax,'b','LineWidth',0.7);ylim([-50 1.2*SF]);xlim([0,15]);xticks([0 5 10 15]);
title('\fontname{宋体}并行搜索积分');ylabel('\fontname{宋体}自相关值');
subplot(312);stairs(PhaseRec,'b','LineWidth',0.7);ylim([-1,CodePhaseShift+2]);xlim([0,15]);
title('\fontname{宋体}并行搜索相位偏移');ylabel('\fontname{宋体}相位偏移');
subplot(313);stairs(flagCapturePar,'b','LineWidth',0.7);ylim([-0.2,1.2]);xlim([0,15]);
title('\fontname{宋体}捕获标志位');xlabel('\it{i}')
%------------------------------MF 搜索-----------------------------------%
MFout = filter(fliplr(mseq_rec'),1,DS_data_rx);
MFlen = 1:length(MFout);
flagCaptureMF = zeros(length(MFout),1);
for i = 1:length(MFout)
if abs(MFout(i))>=SF/2
flagCaptureMF(i) = 1;
end
end
figure;set(gcf,'Color','w','Position',[400 300 400 250]);
subplot(211);stairs(MFlen,abs(MFout),'b','LineWidth',0.7);ylim([-50 1.2*SF]);
xlim(SF*[0,5]);xticks(SF*[0 2 4 6]);
title('\fontname{宋体}匹配滤波输出');
subplot(212);stairs(MFlen,flagCaptureMF,'b','LineWidth',0.7);ylim([-0.2,1.2]);
xlim(SF*[0,5]);xticks(SF*[0 2 4 6]);
title('\fontname{宋体}捕获标志位');xlabel('\it{i}')
%------------------------------3种捕获方法比较-----------------------------------%
figure;set(gcf,'Color','w','Position',[400 300 400 400]);
subplot(311);stairs(abs(Inte),'b','LineWidth',0.7);ylim([-50 1.2*SF]);xlim([0,15]);xticks([0 5 10 15]);
title('\fontname{宋体}串行搜索');ylabel('\fontname{宋体}自相关值');
subplot(312);stairs(abs(InteMax),'b','LineWidth',0.7);ylim([0 1.2*SF]);xlim([0,15]);xticks([0 5 10 15]);
title('\fontname{宋体}并行搜索');ylabel('\fontname{宋体}自相关值');
subplot(313);stairs(MFlen/SF,abs(MFout),'b','LineWidth',0.7);ylim([0 1.2*SF]);xlim([0,15]);xticks([0 5 10 15]);
title('\fontname{宋体}匹配滤波搜索');ylabel('\fontname{宋体}自相关值');
xlabel('\it{i}');
2.2 扩频码跟踪
clear;close all;
%---------------------------扩频系统参数设置-------------------------------%
rb = 20000; %扩频前的数据速率/bit/s 20k
SF = 500; %扩频倍数
Rb = rb*SF; %扩频后的码片速率/Mc/s
Tsum = 10; %仿真时间/ms
bits_num = rb*Tsum/1000;
SNR = 10; %仿真信噪比/dB
%% 发射机部分
%----------------------------m 序列产生模块---------------------------------%
%产生m序列
load Coef.mat
n = floor(log2(500))+2;%m序列的长度
fx = (de2bi(base2dec(Coef.Ci(n-2),8),n+1,2));
fx = fliplr(fx(1:end-1));
% fx = (de2bi(primpoly(n-1,'max'),n,2));
reg = [zeros(1,n-1) 1]; %移位寄存器的初始状态
mseq = zeros(n,1);
mseq(1)= reg(n);
N = 2^(n-1)-1;
for i = 2:N
regTemp = zeros(1,n);
regTemp(1)= mod(sum(fx.*reg),2);
for j = 2:n
regTemp(j)= reg(j-1);
end
reg = regTemp; %移位后的寄存器
mseq(i) = reg(n); %新的寄存器输出
end
mseq = 1-2*mseq(1:SF);% 1->-1 0->1
mseq_rp = reshape(repmat(mseq',bits_num,1)',bits_num*SF,1);
% figure;subplot(211);stairs(mseq);subplot(212);stairs(mseq_rp);
% figure;xc = xcorr(mseq);plot(xc);
%------------------------------BPSK编码-----------------------------------%
bits = randi(2,bits_num,1); %仿真比特数据 0 1
CFdata = 2*bits-3;%bpsk 调制 2->1 1->-1
%-------------------------------扩频:1 扩 SF--------------------------------%
CFdata_os = reshape(repmat(CFdata',SF,1),length(CFdata)*SF,1);
DS_data = CFdata_os' .* mseq_rp'; %信道部分,只仿真到中频,不考虑射频部分
%% 接收机部分
%-------------------------------接收信号AD--------------------------------%
US = 4; % AD 4倍过采样
DS_data_os = reshape(repmat(DS_data,US,1),length(DS_data)*US,1);
CodePhaseShift =123; % 码相位偏移
DS_data_rx = [2*randi(2,1,CodePhaseShift)-3,DS_data_os(1:end - CodePhaseShift)'];% 偏移位置前扩充随机信号
DS_data_rx = awgn(DS_data_rx,100,'measured'); % AWGN信号噪声
%-------------------------------捕获阶段--------------------------------%
mseq_rec = reshape(repmat(mseq',US,1),SF*US,1); % 本地扩频码 过采样
disp('----------捕获开始----------');
IntCap = zeros(bits_num,1);
flagCapture = zeros(bits_num,1);
CPhShiftLocalRec = zeros(bits_num,1);
CPhShiftLocal = 0; % 本地码初始相偏
step = US/2; % 捕获阶段 粗捕获 相位移动为1/2个码片
% 串行搜索
for i = 1:bits_num
mseq_local = circshift(mseq_rec,CPhShiftLocal);% 循环移位
IntCap(i) = abs(DS_data_rx((i-1)*SF*US+1:step:i*SF*US)*mseq_local(1:step:end)); % coarse
if (IntCap(i))>= step*SF/2 % 捕获门限
flagCapture(i) = 1;
disp('----------捕获成功!----------');
break;
else
CPhShiftLocal = CPhShiftLocal+step; % 相位控制字 调整相偏
end
CPhShiftLocalRec(i) = CPhShiftLocal;
end
figure;set(gcf,'Color','w','Position',[100 100 400 350]);
subplot(311);stairs(IntCap,'b','LineWidth',0.7);ylim([0 1.2*step*SF]);title('\fontname{宋体}捕获阶段积分结果');
subplot(312);stairs(CPhShiftLocalRec,'b','LineWidth',0.7);title('\fontname{宋体}捕获阶段本地码相位');
subplot(313);stairs(flagCapture,'b','LineWidth',0.7);ylim([-0.2,1.2]);xlabel('i');title('\fontname{宋体}捕获标志位');
%-------------------------------跟踪阶段--------------------------------%
CapStarter = i+1;
IntE = zeros(bits_num,1);
IntL = zeros(bits_num,1);
IntDS = zeros(bits_num,1);
CPhShiftLocalRec = zeros(bits_num,1);
CPhShiftLocalRec(CapStarter -1) = CPhShiftLocal;
step = 1; % 相位移动为1/US 个码片
disp('----------跟踪阶段----------');
for i = CapStarter:bits_num
mseqE = circshift(mseq_rec,CPhShiftLocal+1); % 超前码
mseqL = circshift(mseq_rec,CPhShiftLocal-1); % 滞后码
IntE(i) = abs(DS_data_rx((i-1)*SF*US+1:step:i*SF*US)*mseqE(1:step:end)); % 超前码积分
IntL(i) = abs(DS_data_rx((i-1)*SF*US+1:step:i*SF*US)*mseqL(1:step:end)); % 滞后码积分
if abs(IntE(i) - IntL(i)) <= step
CPhShiftLocal = CPhShiftLocal;
elseif IntE(i) > IntL(i)
CPhShiftLocal = CPhShiftLocal+step;% 超前支路>滞后支路 调整相偏右移
else
CPhShiftLocal = CPhShiftLocal-step; % 超前支路<滞后支路 调整相偏右移
end
CPhShiftLocalRec(i) = CPhShiftLocal;
mseqDS = circshift(mseq_rec,CPhShiftLocal);
IntDS(i) = (DS_data_rx((i-1)*SF*US+1:step:i*SF*US)*mseqDS(1:step:end)); % 本地码积分
end
figure;set(gcf,'Color','w','Position',[100 100 400 450]);
subplot(411);stairs(IntE,'b','LineWidth',0.7);
xlim([CapStarter-2,bits_num]);ylim([-5 1.2*SF*US]);title('\fontname{宋体}超前支路积分');
subplot(412);stairs(IntL,'b','LineWidth',0.7);
xlim([CapStarter-2,bits_num]);ylim([-5 1.2*SF*US]);title('\fontname{宋体}滞后支路积分');
subplot(413);
plot(CodePhaseShift*ones(bits_num,1),'--r','LineWidth',0.8);hold on;
stairs(CPhShiftLocalRec,'b','LineWidth',0.7);hold off;title('\fontname{宋体}本地码相位');
xlim([CapStarter-2,bits_num]);ylim([CodePhaseShift-US CodePhaseShift+US]);
subplot(414);stairs(IntDS,'b','LineWidth',0.7);
xlim([CapStarter-2,bits_num]);ylim([-1.2*SF*US 1.2*SF*US]);title('\fontname{宋体}本地码积分');xlabel('\it{i}');
%-------------------------------鉴相曲线--------------------------------%
mseqE = circshift(mseq_rec,1);
mseqL = circshift(mseq_rec,-1);
i=20;
[r1,lags] = xcorr(DS_data_rx((i-1)*SF*US+1:i*SF*US),mseqE);
[r2,~] = xcorr(DS_data_rx((i-1)*SF*US+1:i*SF*US),mseqL);
figure;set(gcf,'Color','w','Position',[100 100 400 250]);
subplot(211);plot(lags,r2,'r','LineWidth',0.6);hold on;
plot(lags,r1,'b','LineWidth',0.6);hold off;
legend('\fontname{宋体}超前支路','\fontname{宋体}滞后支路');
xlim([-CodePhaseShift-20*US,CodePhaseShift+20*US]);ylim([-1.2*SF*US,1.2*SF*US]);
xlabel('$\tau$','Interpreter','latex');
subplot(212);plot(lags,r2-r1,'color',[0,104,107]/255,'LineWidth',0.6);
xlim([-CodePhaseShift-20*US,CodePhaseShift+20*US]);ylim([-1.2*SF*US/2,1.2*SF*US/2]);
xlabel('$\tau$','Interpreter','latex');