clc;
clear;
%% 设置基本参数
middle_freq = 15.42e+6;%数字中频频率(下变频后频率)
L1_frequency = 1575.42e6;
dup_freq = 1000;%多普勒频率
sample_freq = 60e+6;%采样频率
code_freq = 10.23e+6;%CB1码率
code_length = 1023;%伪码周期
snr = 37;%载噪比
FLL_bandwidth = 30;
PLL_bandwidth = 18;%PLL噪声带宽
DDLL_bandwidth = 30;%码环滤波噪声带宽
nco_Length = 32;%载波NCO及码NCO位宽
noise_std = 1;
sample_t = 1/sample_freq;%采样频率
K = 1;%环路增益
transfer_coef = (2^nco_Length)/sample_freq;%频率字转换系数
middle_freq_nco = middle_freq*transfer_coef;%中频对应的频率字
Ncoh = (sample_freq / code_freq)*code_length;%一个积分清除时间内的采样点数
Tcoh = Ncoh *sample_t;%积分清除时间
dot_length = [1:Ncoh];%一个积分清除时间内的采样点数
code_word = code_freq * transfer_coef;%码环控制字
FLL_DLL_rate = 1/154;%码环动态与载波动态比率系数(码率/载波频率)
fd_code = dup_freq*FLL_DLL_rate*transfer_coef;%添加在信号源的码多普勒,体现在码NCO上
% fd_code = 0;%添加在信号源的码上的多普勒,体现在码NCO上
e_code_original_phase = (2^nco_Length)/2;%本地超前码的初相位,相当于提前了1/2个码片
modulate_code_bias_phsae = (2^nco_Length)/2;%输入信号源初相位,相当于提前了1/2个码片
signal_phase = 0;
local_phase = 0;
fll_nco_adder = 0;
carrier_nco_sum = 0;%本地载波初始相位
pll_nco_adder = 0;%锁相环产生的载波频率调整控制字
code_nco_sum = 0;
code_nco_adder = 0;%码环码相位调整控制字
n = 3;
n_IQ = 2;
I_P_final(1:n_IQ) = 0;
Q_P_final(1:n_IQ) = 0;
output_fll(2:3) = 0;
output_filter_fll(1:3) = 0;%初始化锁频环环路滤波器输出
output_filter_pll(1:3) = 0;%初始化锁相环环路滤波器输出
output_pll(2:3) = 0;
output_filter_ddll(1:3) = 0;%初始化码环环路滤波器输出
pll_after_filter = 0;
signal_input_all = [];%记录所有的输入信号并写入外部文档
loop_count = 0;
%% 设置环路滤波器参数
WnP = 1.27 * PLL_bandwidth; %锁相环路的自然频率
WnD = 1.89 * DDLL_bandwidth; %码环环路滤波器的自然角频率
WnF = 1.89 * FLL_bandwidth;%锁频环路的自然频率
carrier_k=0.25;%载波增益
cofeone_PLL = (2*WnP+2*WnP^2*Tcoh+WnP^3*Tcoh^2)/carrier_k;
cofetwo_PLL = -(4*WnP+2*WnP^2*Tcoh)/carrier_k;
cofethree_PLL = 2*WnP/carrier_k;
cofeone_DDLL = (sqrt(2)*WnD+WnD^2*Tcoh)/K;
cofetwo_DDLL = -sqrt(2)*WnD/K;
cofeone_FLL = (sqrt(2)*WnF*Tcoh+WnF^2*Tcoh^2)/carrier_k;
cofetwo_FLL = -(sqrt(2)*WnF*Tcoh)/carrier_k;
PLL_flag = 0;
%% 下变频滤波器
fd = [3190000 5190000 25650000 27650000]; %过渡带
mag = [0 1 0];
dev = [0.05 0.015 0.05];
[n2,wn,beta,ftype] = kaiserord(fd,mag,dev,sample_freq);
b = fir1(n2,wn,ftype,kaiser(n2+1,beta));
%% 产生GOLD码表
G1 = ones(1,10); %G1初始值
G2 =ones(1,10); %G2初始值
c_out = []; %C/A码
c_out(1:10) = [1 0 0 1 0 1 1 0 1 1]; %PRN号码为5的C/A码前十个比特
for i = 1:1023
if(i>10)
c_out(i) = mod((G1(10) + G2(1) + G2(9)),2); %PRN为5号,抽头选择1xor9
end
temp = xor(G1(3),G1(10)); %G1多项式
G1(2:10) = G1(1:9);
G1(1) = temp;
temp = mod((G2(2)+G2(3)+G2(6)+G2(8)+G2(9)+G2(10)),2); %G2多项式
G2(2:10) = G2(1:9);
G2(1) = temp;
end
% fid=fopen('D:\Xilinx\Vivado\vivado_results\GPS_tracking\ca_table.coe','w');
% fprintf(fid,'memory_initialization_radix=10;\n');
% fprintf(fid,'memory_initialization_vector=\n');
% for i = 1 : 1022
% fprintf(fid, '%d,\n', c_out(i));
% end
% fprintf(fid, '%d;', c_out(1023));
% fclose(fid);
code_table=(c_out-0.5)*2;%变成正负1的电平模式
%% 初始提前码
early_code_temp=[];
early_code_nco = e_code_original_phase;
for init=1:Ncoh
early_code_nco = early_code_nco+ code_word ;
early_code_nco = mod(early_code_nco,2^32*1023);
index=1+fix(early_code_nco/2^32);
c=code_table(index);
early_code_temp=[early_code_temp,c];
end
local_early_code_last=early_code_temp;
%% 跟踪
for loop_num = 1 : 1000
dot_length = dot_length+Ncoh;
fd_plot(loop_num) = dup_freq;%真实多普勒频偏
fd_code_dup(loop_num) = fd_code/transfer_coef;
flag(loop_num) = PLL_flag;
%% 产生输入码信号
signal_modulate_code=[];
modulate_code_nco = modulate_code_bias_phsae;%输入码信号初始相位
for i=1:Ncoh
modulate_code_nco = modulate_code_nco + code_word + fd_code;%码频率字 + 多普勒频率字
modulate_code_nco = mod(modulate_code_nco,2^32*1023);%不超过一个码周期,2^32 代表一个码片,1023码片是一个周期
index = 1+fix(modulate_code_nco/2^32);%当超过2^32,进位到下个码片
c = code_table(index);%查码表
signal_modulate_code = [signal_modulate_code,c];
if 1 == i
signal_phase = modulate_code_nco/2^32*360;
end
end
%% 码信号与载波相乘作为输入信号
signal_original = cos(2*pi*(L1_frequency + dup_freq )*dot_length*sample_t);%初始载波信号
signal_amplitude = sqrt(10^(snr/10)*(noise_std^2*2));%根据信噪比扩大幅值
noise = noise_std*rand(1,Ncoh);%噪声
receive_signal = signal_amplitude*signal_modulate_code.* signal_original + noise;%将C/A码调制在载波上并添加信道噪声
receive_signal = receive_signal/(max(abs(receive_signal)));%将输入数据归一化
% receive_signal = filter(b,1,receive_signal);
signal_input_all = [signal_input_all,receive_signal];%记录输入信号并导出
%% 产生本地载波
for demond_num = 1:Ncoh
local_cos(demond_num) = cos(2*pi*carrier_nco_sum/2^nco_Length);%本地cos
local_sin(demond_num) = -sin(2*pi*carrier_nco_sum/2^nco_Length);%本地sin
carrier_nco_sum = carrier_nco_sum + middle_freq_nco + pll_nco_adder + fll_nco_adder;%本地载波NCO控制字
end
%% 产生本地码
code_nco_sum = code_nco_adder + code_word + fll_nco_adder*FLL_DLL_rate; %本地码环NCO控制字
%产生本地超前,即时,滞后码
code_temp = [];
for local_init=1:Ncoh
early_code_nco = early_code_nco + code_nco_sum;
early_code_nco = mod(early_code_nco,2^32*1023);
index = 1 + fix(early_code_nco/2^32);
c = code_table(index);
code_temp = [code_temp,c];
if 1 == local_init
local_phase = early_code_nco/2^32*360;
end
end
local_early_code = code_temp;
local_prompt_code = [local_early_code_last(Ncoh-2:Ncoh),local_early_code(1:Ncoh-3)];
local_late_code = [local_early_code_last(Ncoh-4:Ncoh),local_early_code(1:Ncoh-5)];
local_early_code_last = local_early_code;
%% 载波解调与信号解码
%载波解调
I_demon_carrier = local_cos.*receive_signal;
Q_demon_carrier = local_sin.*receive_signal;
%信号解码并积分清除
I_E_final = sum(I_demon_carrier.*local_early_code);
Q_E_final = sum(Q_demon_carrier.*local_early_code);
I_P_final(n_IQ) = sum(I_demon_carrier.*local_prompt_code);
Q_P_final(n_IQ) = sum(Q_demon_carrier.*local_prompt_code);
I_L_final = sum(I_demon_carrier.*local_late_code);
Q_L_final = sum(Q_demon_carrier.*local_late_code);
% if 1 == loop_num
% I_P_final(n_IQ - 1) = I_P_final(n_IQ);
% Q_P_final(n_IQ - 1) = Q_P_final(n_IQ);
% end
%% 锁频环
dot_fll = I_P_final(n_IQ - 1) * I_P_final(n_IQ) + Q_P_final(n_IQ - 1) * Q_P_final(n_IQ);
cross_fll = I_P_final(n_IQ - 1) * Q_P_final(n_IQ) - I_P_final(n_IQ) * Q_P_final(n_IQ - 1);
output_fll(n) = atan2(cross_fll,dot_fll)/(Tcoh*2*pi);
result_discriminator_Fll(loop_num) = output_fll(n);
output_filter_fll(n) = (cofeone_FLL * output_fll(n)) + (cofetwo_FLL * output_fll(n - 1)) + (2 * output_filter_fll(n - 1)) - output_filter_fll(n - 2);
fll_after_filter(loop_num) = output_filter_fll(n);%记录锁频环环路滤波器输出
fll_nco_adder = output_filter_fll(n) * transfer_coef ; %频率字转换
output_fll(n - 1)=output_fll(n);
output_filter_fll(n - 2)=output_filter_fll(n - 1);
output_filter_fll(n - 1)=output_filter_fll(n);
%% 是否启动锁相环
PLL_flag = 1;
% if 0 == PLL_flag && abs(output_fll(n))<50 %本地频差小于100启动锁相环
% loop_count = loop_count + 1;
% if loop_count>100
% PLL_flag = 1;
% end
% elseif 1 == PLL_flag && abs(output_fll(n))>50 %�