1.算法描述
最早的GPS包含L1和L2兩個頻段,其中L1上調(diào)制CA碼,P碼以及導(dǎo)航電文,L2上調(diào)制P碼和導(dǎo)航電文。在實際接收到的GPS信號中,我們除了能夠接受到CA碼和P碼外,還能檢測到L1和L2兩種載波信號。GPS雙頻發(fā)送器的基本構(gòu)架如下所示:

使用CA碼和P碼兩種碼來區(qū)分雙頻道中的兩種不同的頻道。但是P碼周期非常長,美國用P碼周期是140多天,而簡化后的民用版本也要7天多,我們無法在仿真或者實際測試的時候花那么多時間去驗證P碼的捕獲,所以這里,我們將P碼部分做了下簡化,使用偽隨機序列周期為2048bit,來代替P碼部分。
一般情況下,導(dǎo)航電文的頻率為50hz,CA碼的頻率為1M,P碼的頻率為10M。這里,為了測試的需要,我們需要降低頻率來進行測試。整個發(fā)送端,按如下的結(jié)構(gòu)設(shè)計:

通過捕獲模塊獲得初始的頻偏值,然后進行載波同步。與此同時,通過碼同步,完成相位的捕獲。最后進入跟蹤階段。
先介紹一下捕獲的基本原理:
本地碼生成器以C/A碼標(biāo)稱頻率產(chǎn)生C/A碼與接收到的采樣信號相關(guān)累加,一個積分周期(通常1個碼周期)后,相關(guān)峰與檢測門限比較,如果相關(guān)峰大于門限,則認(rèn)為捕獲成功,得到對應(yīng)的碼相位估計;如果相關(guān)峰小于門限,碼發(fā)生器自動將本地碼碼相位向前或向后跳動1/2或1/4個碼片,然后繼續(xù)相關(guān)累加檢測,最多在 或 個偽碼周期后找到與本地偽碼同步的輸入偽碼的相位狀態(tài)( 即為一個碼周期內(nèi)碼片的數(shù)目),以實現(xiàn)偽碼的捕獲。下面對步進相關(guān)法進行簡單介紹,其原理圖見圖1。

跟蹤部分:

其內(nèi)部詳細(xì)結(jié)構(gòu)如下所示:

2.仿真效果預(yù)覽
算法仿真:MATLAB 2010b
FPGA設(shè)計:ISE12.2
FPGA仿真:Modelsim6.5SE






導(dǎo)航電文和CA碼及P碼異或之后的信號。

導(dǎo)航電文和CA碼及P碼異或之后的信號,通過成型濾波器之后的效果。

這個最后發(fā)送出去的QPSK,BPSK以及相加之后的射頻信號。

最后捕獲跟蹤之后的信號,放大看如下所示:

一開始的逐漸變大的過程就是鎖定過程
3.MATLAB核心程序
timescale 1ns / 1ps
module GPS_Rec(
i_clk,
i_rst,
i_QPSK,
i_BPSK,
//Capture
o_Ca_index,
o_CA,
o_abs_addCA,
o_P_index,
o_P,
o_abs_addP,
o_fre_est_Ca,
o_fre_est_P,
//Tracking
o_I_L1,
o_Q_L1,
o_I_L2,
o_Q_L2,
o_Dwen_rec_L1,
o_Dwen_rec_L2
);
input ?????????????i_clk;
input ?????????????i_rst;
input signed[15:0] i_QPSK;
input signed[15:0] i_BPSK;
//Capture
output ??????[9:0] o_Ca_index;
output signed[1:0] o_CA;
output signed[21:0]o_abs_addCA;
output ??????[10:0]o_P_index;
output signed[1:0] o_P;
output signed[23:0]o_abs_addP;
output signed[23:0]o_fre_est_Ca;
output signed[23:0]o_fre_est_P;
//Tracking
output signed[15:0]o_I_L1;
output signed[15:0]o_Q_L1;
output signed[15:0]o_I_L2;
output signed[15:0]o_Q_L2;
output signed[1:0] o_Dwen_rec_L1;
output signed[1:0] o_Dwen_rec_L2;
wire clk_ca;
wire clk_ca_2code;
wire clk_p;
wire clk_p_2code;
//2 time ca clock
CLOCK_DCM2 CLOCK_DCM2_u(
.i_clk ?????????(i_clk),
.i_rst ?????????(i_rst),
.o_clk_dwen ????(),
.o_clk_ca ??????(clk_ca),
.o_clk_ca_2code (clk_ca_2code),
.o_clk_p ???????(clk_p),
.o_clk_p_2code ?(clk_p_2code)
);
//CAPTURE
//CAPTURE
//frequency capture
wire signed[9:0] o_Ca_index;
wire signed[1:0] o_CA;
wire signed[21:0]o_abs_addCA;
frequency_capture_channel1 frequency_capture_channel1_u(
.i_clk ?????????(i_clk),
.i_clk_ca ??????(clk_ca),
.i_clk_ca2times (clk_ca_2code),
.i_rst ?????????(i_rst),
.i_QPSK ????????(i_QPSK),
.o_fre_est ?????(o_fre_est_Ca),
.o_I_filter ????(),
.o_Q_filter ????(),
.o_Ca_index ????(o_Ca_index),
.o_CA ??????????(o_CA),
.o_abs_addIQ ???(o_abs_addCA)
);
wire signed[10:0] o_p_index;
wire signed[1:0] ?o_p;
wire signed[23:0] o_abs_addP;
frequency_capture_channel2 frequency_capture_channel2_u (
.i_clk ?????????(i_clk),
.i_clk_p ???????(clk_p),
.i_clk_p2times ?(clk_p_2code),
.i_rst ?????????(i_rst),
.i_BPSK ????????(i_BPSK),
.o_fre_est ?????(o_fre_est_P),
.o_I_filter ????(),
.o_Q_filter ????(),
.o_p_index ?????(o_P_index),
.o_p ???????????(o_P),
.o_abs_addIQ ???(o_abs_addP)
);
//TRACKING
//TRACKING
wire signed[15:0]o_I_filter1;
wire signed[15:0]o_Q_filter1;
wire signed[15:0]o_I_filter2;
wire signed[15:0]o_Q_filter2;
Frequency_track_tops Frequency_track_tops_u(
.i_clk ??????(i_clk),
.i_rst ??????(i_rst),
.i_QPSK ?????(i_QPSK),
.i_BPSK ?????(i_BPSK),
.i_FRE_index1(o_fre_est_Ca),
.i_FRE_index2(o_fre_est_P),
.o_I_filter1 (o_I_L1),
.o_Q_filter1 (o_Q_L1),
.o_I_filter2 (o_I_L2),
.o_Q_filter2 (o_Q_L2)
);
//CA capture
wire signed[1:0]Dwen_rec_L1;
CA_early_late_track_tops CA_early_late_track_tops_u(
.i_clk ?????(clk_ca_2code),
.i_clk_ca ??(clk_ca),
.i_rst ?????(i_rst),
.i_CA_index (o_Ca_index+1),
.i_Idin ????(o_I_L1),
.i_Qdin ????(o_Q_L1),
.o_dout ????(o_Dwen_rec_L1)
);
//P capture
wire signed[1:0]Dwen_rec_L2;
P_early_late_track_tops P_early_late_track_tops_u (
.i_clk ????(clk_p_2code),
.i_clk_p ??(clk_p),
.i_rst ????(i_rst),
.i_P_index (o_P_index+1),
.i_Idin ???(o_I_L2),
.i_Qdin ???(o_Q_L2),
.o_dout ???(o_Dwen_rec_L2)
);
endmodule
01_118m