%基于FFT,使用tong检测器的并行码相位捕获
clc;
clear;
fs=4.092e6; %采样率
ts=1/fs;
N=fs/1000; %1ms所采的点数
fi=1.5e6; %中频
fd=-500; %多普勒频移
codeoffset=5; %码相位偏移
SNR=-20; %信噪比
Threshold=6e4; %捕获门限 ???
Accume_Times=5; %非相干累加次数
Detec_num=30; %在同一频点的最多检测次数
result2=0;
A_Max_account=10; %唐检测的计数器最大值
%产生本地伪码%%%%%
code=gold_gen; %产生长度为1023的GOLD码
local_code=code;
nn=0:N-1;
tc=1023/4092; %一个采样点对应的码片数
m=floor(nn*tc); %采样点索引
local_code_samp2=local_code(m+1); %本地伪码采样
for i=1:Accume_Times;
Local_code_sampe(:,i)=local_code_samp2;
end
K=ones(1,21);
%对各频点开始捕获
for kk=1:21
for Det_time=1:Detec_num
%产生GPS信号
Code_Received=code;
Code_Received=[code(codeoffset:end),code(1:codeoffset-1)]; %延时(1023-codeoffset+1)*N/1023个点
Code_sampe=reshape( Code_Received(m+1),1,N); %%接收伪码采样
for ll=1:Accume_Times % 产生接收伪码,取Accume_Times(非相参积累次数)个周期
receive_code_samp(:,ll)= Code_sampe;
end
mm=0:Accume_Times*N-1;
Carryer=cos(2*pi*(fi+fd)*ts*mm); %载波
Carryer=reshape( Carryer,N,Accume_Times); %%变为有 非相干累加次数 列的信号 , 行为每秒采样点数
Noise=randn(N,Accume_Times); %得到相应长度的高斯白噪声
Noise_NB_std=sum(std(Noise))/Accume_Times; %%%噪声功率
A=(Noise_NB_std^2)*sqrt(2*10^(SNR/10)); %%%根据信噪比求信号幅度
signal=A*receive_code_samp.* Carryer+Noise; %%%接收信号
fr=fi-5500+kk*500; %频率搜索范围-5K~5K,搜索步进为500Hz
%%载波NCO
NCO_I=cos(2*pi*fr*ts*mm);
NCO_I=reshape(NCO_I,N,Accume_Times);
NCO_Q=sin(2*pi*fr*ts*mm);
NCO_Q=reshape(NCO_Q,N,Accume_Times);
Signal_ddc=signal.*NCO_I+i*signal.*NCO_Q; %%%正交两路
%FFT
%平方检波
signal_ddc_fft=fft(Signal_ddc); % 与本地载波相关后的信号 做FFT
local_code_sample_fft=fft(Local_code_sampe); %本地码做FFT
local_code_sample_fft_conj=conj(local_code_sample_fft); % 取共轭
signal_multi=signal_ddc_fft.*local_code_sample_fft_conj; %FFT后对应系数相乘
%做ifft变换
signal_multi_ifft=ifft(signal_multi); %IFFT变换
signal_multi_ifft_abs=abs(signal_multi_ifft); %取模
signal2=signal_multi_ifft_abs.^2; %平方检波
result_sum=sum(signal2,2); %非相干累加
result(kk,:)=result_sum; %行为频点,列为相应频点对应的码片,值为非相干累加结果
codephase1(kk,Det_time)=find(result(kk,:)==max(result(kk,:))); %每个频点的相关峰值所在码片
%Tong判决,如果在同一频点上相邻两次检测的相关峰值所在码片相差不超过1且峰值大于门限,则计数器加一,反之减一;计数器加至A_Max_account时捕获成功,
%减至0时捕获失败,跳至下一频点捕获,在0和A_Max_account之间时继续在同一频点上捕获
if Det_time>1
if (abs(codephase1(kk,Det_time)-codephase1(kk,Det_time-1))<=1)&&(result(kk,codephase1(kk,Det_time))>Threshold)
K(kk)=K(kk)+1;
else
K(kk)=K(kk)-1;
end
end
if K(kk)==A_Max_account
freq1=kk;
codephase2=codephase1(kk,Det_time);
Frequence=-5500+kk*500
Codephase=ceil((N-codephase1(kk,Det_time))/(N/1023)+1)
break
elseif K(kk)==0
break
else
continue
end
end
if K(kk)==A_Max_account
break
end
end