实验二GPS信号捕获
一、实验目的
1. 熟悉GPS信号捕获基本概念;
2. 掌握串行搜索算法、并行频率搜索算法和并行码相位搜索捕获算法的基本思想、特点及算法流程;
3. 训练在实际当中分析问题、解决问题的能力。
二、实验内容
1. 编写GPS信号捕获子程序,算法自选。
2. 将实验一最终生成的信号延迟 时间,并加上大小为
f的多普勒频移,使用
D
以上编写的信号捕获子程序对该信号进行捕获。
3. 画出三维捕获结果图(要求至少画出两幅,一幅对应信号成功捕获,一幅对应未捕获到信号)。
三、实验结果
成功捕获
未成功捕获
四、总结与反思
在实验一的基础之上进行本次试验,感觉有了新的理解和领悟。但是在实验过程中还是遇到了很多的问题,通过上网搜索、询问教员、和同学探讨等方式最终做了出来。虽然程序代码多是网上搜索得来的,但在读程序的过程中还是收获一些知识。
五、程序代码
clear all;
clc;
%发射端
%设置是否有信号
TxCodeOnOff = 1;%1 - On, 0 - Off
%设置仿真时间
TxTotalTime = 1e-3;%1ms
%设置伪码频率
TxCodeFrequency = 1.023e6;%1.023MHz
%设置载波频率
TxCarrierFrequency = 2 * 1.023e6;%2.046MHz
%设置采样频率
TxSampleFrequency = 16 * 1.023e6;%MHz
%发射端产生伪码并计算码长
TxGoldSequence0 = dyc_gold_gen_v3();
TxGoldSequence0Len = length(TxGoldSequence0);
%用载波调制
TxTemp1 = TxSampleFrequency / TxCodeFrequency;
%将伪码序列扩展
TxGoldSequence1 = repmat(TxGoldSequence0, TxTemp1, 1);
TxGoldSequence1 = reshape(TxGoldSequence1, 1, TxTemp1 * TxGoldSequence0Len);
TxGoldSequence2 = TxCodeOnOff * TxGoldSequence1;
TxTiming = 0 : (1 / TxSampleFrequency) : (TxTotalTime - 1 / TxSampleFrequency);
TxSignalSequence = sin(2 * pi * TxCarrierFrequency * TxTiming + TxGoldSequence2 * pi);
%信道
%设置多普勒频移
ChDiffFrequency = -15000;%Hz
%设置信噪比
ChSN = -20;%dB
%设置码相移
ChDelayValue = 800;%码片相移量
ChDelay = ChDelayValue * TxTemp1;%此值为采样结果的码相移,是伪码相移的 TxTemp1 倍
%将序列进行移位(需要先移位在加多普勒频移,否则的话移位操作会影响多普勒频移)
ChGoldSequence = circshift(TxGoldSequence2, [0, ChDelay]);
%生成带有多普勒频移的序列
ChTiming = TxTiming;
ChSignalSequence1 = sin(2 * pi * (TxCarrierFrequency + ChDiffFrequency) * ChTiming + ChGoldSequence * pi);
%加入噪声
ChSingalSequence3 = awgn(ChSignalSequence1, ChSN,
'measured');%(此函数还可添加更多参数)
%接收端
%设置频率搜索步长
RxCarrierFrequencyDelta = 500;%Hz
%设置频率搜索范围
RxDiffFrequencyMax = 20 * RxCarrierFrequencyDelta;%Hz
%设置码相位搜索步长
RxDelayDelta = 10;
%设采样率和码速率之比与发送端一致
RxDelayRatio = TxTemp1;
%设接收端采样率与发送端一致
RxTiming = TxTiming;
%计算接收端频率搜索次数
RxFrequencySearchTimes = fix(2 * RxDiffFrequencyMax / RxCarrierFrequencyDelta) + 1;%(可能有误)
%计算码相位搜索次数
RxGoldLen = TxGoldSequence0Len;
RxGoldSearchTimes = ceil(RxGoldLen / RxDelayDelta);
RxSignalAmplitude = zeros(RxGoldSearchTimes, RxFrequencySearchTimes);
for RxTemp11 = 1 : RxGoldSearchTimes
display(['Processing... ' num2str(RxTemp11 / RxGoldSearchTimes * 100, '%.2f') '%']);
RxTemp12 = RxTemp11 - 1;
%产生接收伪码
RxGoldSequence1 = TxGoldSequence1;
RxGoldSequence2 = circshift(RxGoldSequence1, [0, RxTemp12 * RxDelayDelta * RxDelayRatio]);%移动码相位
RxGoldSequence3 = RxGoldSequence2 .* 2 - 1;%
%计算码相关
RxSignalSequence1 = ChSingalSequence3 .* RxGoldSequence3;
RxCarrierFrequency1 = TxCarrierFrequency - RxDiffFrequencyMax;
for RxTemp21 = 1 : RxFrequencySearchTimes
RxTemp22 = RxTemp21 - 1;
%产生接收载波
RxCarrierFrequency = RxCarrierFrequency1 + RxTemp22 * RxCarrierFrequencyDelta;
RxCarrierSequenceI = cos(2 * pi * RxCarrierFrequency * RxTiming);
RxCarrierSequenceQ = sin(2 * pi * RxCarrierFrequency * RxTiming);
%I/Q两路分别与接收载波做相关
RxSignalXcorr2I = RxSignalSequence1 *
RxCarrierSequenceI';
RxSignalXcorr2Q = RxSignalSequence1 *
RxCarrierSequenceQ';
%幅度检波(平方相加再开根号)
RxSignalAmplitude(RxTemp11, RxTemp21) =
sqrt(RxSignalXcorr2I ^ 2 + RxSignalXcorr2Q ^ 2);
end
end
%生成坐标轴
%纵坐标(行)
RxLabelCode = ((1 : RxGoldSearchTimes) - 1) * RxDelayDelta; %横坐标(列)
RxLabelFrequency = ((1 : RxFrequencySearchTimes) - 1) * RxCarrierFrequencyDelta - RxDiffFrequencyMax;
%生成三维捕捉结果
figure(31);
mesh(RxLabelFrequency, RxLabelCode, RxSignalAmplitude);
RxSignalAmplitude1 = RxSignalAmplitude(:);%(将结果转化为一维向量便于后续计算)
%计算捕捉到的最大幅度
RxSignalResMax = max(RxSignalAmplitude1);
%计算捕捉结果的平均幅度
RxSignalResAverage = mean(RxSignalAmplitude1);
%
RxSignalResDeviation = std(RxSignalAmplitude1);
%判断是否捕获
%设置门限
RxCatchThreshold = RxSignalResAverage + 5 * RxSignalResDeviation;
%
if RxSignalResMax > RxCatchThreshold
%捕获成功
display('Success!!!');
%查找最大值对应的坐标
[RxResRow RxResColumn] = find(RxSignalAmplitude == RxSignalResMax);%(此方法仅限二位数组)
display(['Doppler Frequency: '
num2str(RxLabelFrequency(RxResColumn), '%.0f') 'Hz']);
display(['Code Phase: ' num2str(RxLabelCode(RxResRow), '%.0f')]);
else
%捕获失败
display('Fail!!!');
End
附录B
function [GoldSeq] = dyc_gold_gen_v3()
M_base = 8;
M1 = [2 0 1 1];
M2 = [2 4 1 5];
Mfb_len = 11;
Mfinal_len = 1023;
M1origin_len = length(M1);
M2origin_len = length(M2);
Mfb_ratio = log2(M_base);
M1fb_raw_len = M1origin_len * Mfb_ratio;
M1fb_raw = zeros(1, M1fb_raw_len);
for M1fb_reg_i = 1 : M1origin_len
for M1fb_bit_i = 1 : Mfb_ratio
M1fb_raw((M1fb_reg_i - 1) * Mfb_ratio + M1fb_bit_i) = mod(fix(M1(M1fb_reg_i) / (2 ^ (Mfb_ratio - M1fb_bit_i))), 2);
end
end
M1fb = M1fb_raw((M1fb_raw_len - Mfb_len + 1) : M1fb_raw_len);
M2fb_raw_len = M2origin_len * Mfb_ratio;
M2fb_raw = zeros(1, M2fb_raw_len);
for M2fb_reg_i = 1 : M2origin_len
for M2fb_bit_i = 1 : Mfb_ratio
M2fb_raw((M2fb_reg_i - 1) * Mfb_ratio + M2fb_bit_i) = mod(fix(M2(M2fb_reg_i) / (2 ^ (Mfb_ratio - M2fb_bit_i))), 2);
end
end
M2fb = M2fb_raw((M2fb_raw_len - Mfb_len + 1) : M2fb_raw_len);
M1regs_len = length(M1fb);
M2regs_len = length(M2fb);
M1len_period = Mfinal_len;
M2len_period = Mfinal_len;
M1regs_s = zeros(1, M1regs_len);
M1regs_s(M1regs_len) = 1;
M2regs_s = zeros(1, M2regs_len);
M2regs_s(M2regs_len) = 1;
M1regs_m1 = M1regs_s;
M1regs_m2 = zeros(1, M1regs_len);
M2regs_m1 = M2regs_s;
M2regs_m2 = zeros(1, M2regs_len);
M1regs_e = zeros(1, M1len_period);
M2regs_e = zeros(1, M2len_period);
M1regs_e(1) = M1regs_s(M1regs_len);
for M1_ri = 2 : M1len_period
M1regs_m2(1) = mod(sum(M1fb .* M1regs_m1), 2);
M1regs_m2(2 : M1regs_len) = M1regs_m1(1 : (M1regs_len - 1)); M1regs_m1 = M1regs_m2;
M1regs_e(M1_ri) = M1regs_m1(M1regs_len);
end
M2regs_e(1) = M2regs_s(M2regs_len);
for M2_ri = 2 : M2len_period
M2regs_m2(1) = mod(sum(M2fb .* M2regs_m1), 2);
M2regs_m2(2 : M2regs_len) = M2regs_m1(1 : (M2regs_len - 1)); M2regs_m1 = M2regs_m2;
M2regs_e(M2_ri) = M2regs_m1(M2regs_len);
end
GoldSeq = mod((M1regs_e + M2regs_e), 2);