m低信噪比下GPS信号的捕获算法研究,分别使用matlab和FPGA对算法进行仿真和硬件实现

145 阅读3分钟

1.算法概述

      GPS卫星发送的信号一般由3个分量组成:载波、伪码和导航电文,其中伪码和导航电文采用BPSK技术去调制载波。GPS使用的两个L波段两种载频:

 

1.png

 

       为了跟踪GPS信号,首先要捕获到GPS信号。将捕获到的GPS信号的数据传递给跟踪过程,再通过跟踪过程便可得到卫星的导航电文。传统的GPS捕获方法有:串行搜索捕获、滑动相关法、循环相关法、PMF算法。 采用分段FFT的方法进行运算,算法基本结构如图1所示。

 

2.png

 

       这里分段数目为K,那么每个相关器的相关时间为TCA/K。每个相关器处理的C/A码长度为,然后再对处理后的数据进行FFT变换。由于每个FFT对应的点数仅仅为原来的,故其硬件资源较直接的并行FFT算法要节约。

 

       当接收机处于遮挡比较严重的环境如隧道,高楼林立的市区 GPS信号将变得非常微弱。根据经验,这种情况下,GPS信号的载噪比一般只有44dBhz,甚至更低。在这种情况下,获得的信号频谱非常差,甚至难以搜索到其峰值,因此,我们在检测信号最大值的时候,需要通过如下的运算,这里我们仍假设将信号分为K段进行FFT变化。

 

3.png

        然后对得到的结果取模。当获得超过门限的峰值,则说明此时信号已经捕获,就得到对码相位和多普勒频移估计值,这样做的有点是可以获得峰值更为明显的谱线。

 

2.仿真效果预览

matlab2022a,ise10.1仿真

 

 

4.jpeg

5.jpeg

6.png

 

 

3.MATLAB/FPGA部分代码预览 `timescale 1ns / 1ps

module tops(

           i_clk,

  i_rst,

  o_CA,

  o_sin,

  o_cos,

  o_ca_cos,

  o_ca_som,

  o_sum1,

  o_sum2,

  o_ca_cos2,

  o_ca_som2,

  fft_in1,

  fft_in2,

  

  fft_out1,

  fft_out2

  

        );

 

input              i_clk;

input              i_rst;

output signed[1:0] o_CA;

output signed[7:0] o_sin;

output signed[7:0] o_cos;

output signed[9:0] o_ca_cos;

output signed[9:0] o_ca_som;

output signed[13:0]o_sum1;

output signed[13:0]o_sum2;

output signed[9:0] o_ca_cos2;

output signed[9:0] o_ca_som2;

output signed[23:0]fft_in1;

output signed[23:0]fft_in2;

 

output signed[27:0]fft_out1;

output signed[27:0]fft_out2;

 

 

CA_carrier_module CA_carrier_module_u(

 .i_clk     (i_clk),

 .i_rst     (i_rst),

 .o_CA      (),

 .o_sin     (),

 .o_cos     (),

 .o_ca_cos  (o_ca_cos),

 .o_ca_sin  (o_ca_sin)

 );

 

 

wire signed[13:0]o_sum1;

wire signed[13:0]o_sum2;

 

delay_1ms delay_1ms_u1(

 .i_clk    (i_clk),

 .i_rst    (i_rst),

 .i_data   (o_ca_cos),

 .o_data1  (),

 .o_data2  (),

 .o_data3  (),

 .o_data4  (),

 .o_data5  (),

 .o_data6  (),

 .o_data7  (),

 .o_data8  (),

 .o_data9  (),

 .o_data10 (),

 .o_sum    (o_sum1)

 );

 

 

delay_1ms delay_1ms_u2(

 .i_clk    (i_clk),

 .i_rst    (i_rst),

 .i_data   (o_ca_sin),

 .o_data1  (),

 .o_data2  (),

 .o_data3  (),

 .o_data4  (),

 .o_data5  (),

 .o_data6  (),

 .o_data7  (),

 .o_data8  (),

 .o_data9  (),

 .o_data10 (),

 .o_sum    (o_sum2)

 );

 

 

 

reg[1:0]cnt1 = 2'b00;

wire    clk2;

 

always @(posedge i_clk or posedge i_rst)

begin

     if(i_rst)

  cnt1 <= 2'b00;

else begin

     cnt1 <= cnt1 + 1'b1;

     end

end

 

assign clk2 = cnt1[1];

CA_gen CA_gen_u(

   .i_clk (clk2),

   .i_rst (i_rst),

   .o_CA  (o_CA)

   );

 

 

 

ncos ncos_u(

         .reg_select (1'b0),

.clk        (i_clk),

.we         (1'b1),

.data       (26'd16777216),

.sine       (o_sin),

.cosine     (o_cos)

         );

 

multer multer_u1(

                .clk (i_clk),

 .a   (o_cos),

 .b   (o_CA),

 .p   (o_ca_cos2)

                );

 

multer multer_u2(

                .clk (i_clk),

 .a   (o_sin),

 .b   (o_CA),

 .p   (o_ca_sin2)

                );  

 

wire [23:0]fft_in1;

wire [23:0]fft_in2;

multer2 multer2_u1(

                   .clk (i_clk),

 .a   (o_sum1),

 .b   (o_ca_cos2),

 .p   (fft_in1)

                   );

 

multer2 multer2_u2(

                   .clk (i_clk),

 .a   (o_sum2),

 .b   (o_ca_sin2),

 .p   (fft_in2)

                   );

 

//==============fft==========================

ffts ffts_u1(

            .sclr        (i_rst),

.fd_in       (1'b1),

.fd_out      (),

.forward     (1'b1),//1;fft;0:ifft

.clk         (i_clk),

.rffd        (),

.data_valid  (),

.dout        (fft_out1),

.din         (fft_in1),

.size        (6'd31)

            );

 

 

ffts ffts_u2(

            .sclr        (i_rst),

.fd_in       (1'b1),

.fd_out      (),

.forward     (1'b1),//1;fft;0:ifft

.clk         (i_clk),

.rffd        (),

.data_valid  (),

.dout        (fft_out2),

.din         (fft_in2),

.size        (6'd31)

            );

  

  

wire signed[13:0]omax1;

wire       [9:0]index;  

reg signed[13:0]o_power_average=14'd550;

reg signed[22:0]r_power_average=23'd281600;

 

 

always @(posedge i_clk or posedge i_rst)

begin

     if(i_rst)

  begin

  o_power_average <= 14'd550;

  r_power_average <= 23'd281600;

  end

else begin

 if(omax1[13] == 1'b1 | omax1==14'd0)

 o_power_average <= 14'd550;

 else  begin

       r_power_average <= 172*omax1;

 o_power_average <= r_power_average[22:9];

 end

     end

end

 

 

find_max find_max_u(

    .clk    (i_clk),

    .rst    (i_rst),            //同步复位

    .idata  (o_fadd),

    .iTh1   (o_power_average),

    .omax1  (omax1),

    .oindex1(index),

    .omax2  (),

    .oindex2(),

    .omax3  (),

    .oindex3(),

    .oen    (),

    .oen1   (),

    .start  ()

    );

 

endmodule

01_026_m`