m基于FPGA的全数字OQPSK调制解调器,包括成形滤波器、NCO模型、costas载波恢复

102 阅读6分钟

1.算法描述

       OQPSK也称为偏移四相相移键控(offset-QPSK),是QPSK的改进型。它与QPSK有同样的相位关系,也是把输入码流分成两路,然后进行正交调制。不同点在于它将同相和正交两支路的码流在时间上错开了半个码元周期。由于两支路码元半周期的偏移,每次只有一路可能发生极性翻转,不会发生两支路码元极性同时翻转的现象。因此,OQPSK信号相位只能跳变0°、±90°,不会出现180°的相位跳变。

 

  OQPSK信号可采用正交相干解调方式解调,其原理如图5-49所示。由图看出,它与QPSK信号的解调原理基本相同,其差别仅在于对Q支路信号抽样判决时间比I支路延迟了/2,这是因为在调制时Q支路信号在时间上偏移了/2,所以抽样判决时刻也应偏移/2,以保证对两支路交错抽样。

 

  OQPSK克服了QPSK的l80°的相位跳变,信号通过BPF后包络起伏小,性能得到了改善,因此受到了广泛重视。但是,当码元转换时,相位变化不连续,存在90°的相位跳变,因而高频滚降慢,频带仍然较宽。

 

       采用非归零码直接进行调制所得的QPSK信号的幅度非常恒定,但其信号频谱较大。然而,当QPSK进行波形成形时,它们将失去恒包络的性质。偶尔发生的弧度为π的相移,会导致信号的包络在瞬间通过零点。任何一种在过零点的硬限幅或非线性放大都会引起旁瓣再生和频谱扩展,必须使用效率较低的线性放大器放大QPSK信号,这将使放大器的效率受到限制,进而影响到终端的小型化。

      为了克服QPSK对信道的线性度要求很高,交错QPSK(OQPSK)或参差QPSK虽然在非线性环境下也会产生频谱扩展,但对此已不那么敏感,因此能支持更高效率的放大器。

 

OQPSK复基带信号可以表示为:

 

1.png

 

       在OQPSK调制解调器设计中成形滤波、数字下变频、载波恢复和定时恢复是实现OQPSK调制解调器的难点和重点。

 

      在数字通信系统中,由于基带码元采用矩形波表示,其频谱是无限宽,当信号通过实际带限信道,频域截短,时域变为无限,产生码间串扰,为了克服码间串扰,需要对码元进行成形滤波。实际应用中,大多采用升余弦滤波器作为成形滤波器。

 

      具有滚降系数α的升余弦滚降特性H(ω)可表示为:

2.png

 

 

而相应的h( t)为:

 

3.png

 

        升余弦滚降信号在前后抽样值处的码间串扰为0,满足抽样值无失真传输条件,滚降系数α越小,则波形的振荡起伏就越大,但传输频带减小,对接收端的定时要求增加;反之,α越大,则波形振荡起伏越小,但频带增加。α=0时,升余弦滤波器变成了理想低通滤波器,此时信号的频带最窄;α=1时,升余弦滤波器的频带最宽,为理想低通滤波器的2倍。所以,升余弦滚降滤波器是以频带的增加来换取码间干扰的减少。

 

       从工作原理上讲,数字下变频与模拟下变频是一样的,就是输入信号与一个本地振荡信号的乘法运算。与模拟下变频相比,数字下变频的运算速度受DSP处理速度的限制,同时,其运算速度决定了其输入信号的数据流可达到最高速率,相应地也限定了ADC的最高采样速率;另外,数字下变频的数据精度和运算速度也影响着接收机的性能,所以,数字下变频器必须进行优化设计。

 

2.仿真效果预览

matlab2022a

 

ise10.1

 

Modelsim SE-64 10.1c

 

4.png

5.png

6.png

 

3.MATLAB核心程序 `clc;

clear;

N=200;      

I_data=zeros(1,N); %I支路符号

Q_data=zeros(1,N); %Q支路符号

 

for n1=1:N

    bits(n1)=binornd(1,0.5,1,1);%信源比特流

end

for no=1:(N/2)             

    I_bits(no)=bits(2*no-1);   %I支路比特流

end

for ne=1:(N/2)

    Q_bits(ne)=bits(2*ne);     %Q支路比特流

end

 

 

 

Flag=1;

%I支路符号

for no=1:N

    Flag=-Flag;

    if  Flag==1

         I_data(no)=1;

    elseif  Flag==-1

         I_data(no)=-1;

     end

end

%Q支路符号

for no=1:N

    Flag=-Flag;

    if  Flag==1

         Q_data(no)=1;

    elseif  Flag==-1

         Q_data(no)=-1;

     end

 end

 

 

figure(1)

subplot(211),stairs(I_data);

axis([0,length(Q_bits),-2,2]);

subplot(212),stairs(Q_data);

axis([0,length(Q_bits),-2,2]);

 

 

fc=4;           %载波频率

fs=40;          %采样频率

 

T=1;             

samples=T*fs;  %每符号内的采样点数

 

t=0:T/samples:(T-T/samples);

 

sin_c=sin(2pifc*t);

cos_c=cos(2pifc*t);

windows=ones(1,length(cos_c)); %矩形窗

 

%生成调制信号I支路调制信号

 

for n1=1:length(I_data)

    data_number((samples*(n1-1)+1):(samples*(n1-1)+samples))=(I_data(n1)*sin_c).*windows;

end

 

figure(2)

Sit=data_number;

subplot(211),plot(Sit);

title('I支路');

axis([0,length(data_number),-2,2]);

%生成Q支路调制信号

 

for n1=1:length(I_data)

    data_number((samples*(n1-1)+1):(samples*(n1-1)+samples))=(Q_data(n1)*cos_c).*windows;

end

 

Sqt=data_number;

subplot(212),plot(Sqt);

title('Q支路');

axis([0,length(data_number),-2,2]);

St=Sit+Sqt;

 

figure(3)

plot(St)

title('OQPSK仿真波形图');

axis([0,length(St),-4,4]);

 

 

 

%========================信号解调=====================

 

for n1=1:200

  I_data_number((samples*(n1-1)+1):(samples*(n1-1)+samples))=(St((samples*(n1-1)+1):(samples*(n1-1)+samples)).*sin_c(1:samples));  

end

%

for n1=1:200

  Q_data_number((samples*(n1-1)+1):(samples*(n1-1)+samples))=(St((samples*(n1-1)+1):(samples*(n1-1)+samples)).*cos_c(1:samples));

end

%

figure(4)

subplot(211),plot(I_data_number);

subplot(212),plot(Q_data_number);

 

%======================信号滤波=======================================

Ts=1/1000  ;%设置采样频率

N=128;      %设置阶数

n=[0:(N-1)];

Wn=0.2;     %设置截止频率

t=0:Ts:3*pi;

x=win(0,N-1,0,N-1);

x=(0.5-0.5cos(2pi*n/(N-1))).*x;                

 

[B,A]=fir1(N,Wn,'low',hann(N+1)); I_data_number_Win=filter(B,A, I_data_number);

[B,A]=fir1(N,Wn,'low',hann(N+1)); Q_data_number_Win=filter(B,A, Q_data_number);

 

 

figure(5)

subplot(211),plot(I_data_number_Win);

subplot(212),plot(Q_data_number_Win);

 

 

 

 

%=====================符号判决==============================================

for i=1:8000

      if I_data_number_Win(i)>=0

          I_r(i)=1;

      end

      if I_data_number_Win(i)<0

          I_r(i)=-1;

      end

end

 

for i=1:8000

      if Q_data_number_Win(i)>=0

          Q_r(i)=1;

      end

      if Q_data_number_Win(i)<0

          Q_r(i)=-1;

      end

end

 

figure(6)

subplot(211),plot(I_r);axis([0,length(I_r),-2,2]);

subplot(212),plot(Q_r);axis([0,length(Q_r),-2,2]);

 

`timescale 1ns / 1ps

//

//

module qpsk(

            clk,

rst,

I,

Q,

cos1,

sin1,

I_cos,

Q_sin,

r,

cos2,

sin2,

I_cos2,

Q_sin2

         );

input clk;

input rst;

output I;

output Q;

output signed[7:0]cos1;

output signed[7:0]sin1;

output signed[9:0]I_cos;

output signed[9:0]Q_sin;

output signed[9:0]r;

 

output signed[7:0]cos2;

output signed[7:0]sin2;

 

output signed[15:0]I_cos2;

output signed[15:0]Q_sin2;

 

IQ IQ_u(

       .clk(clk),

       .rst(rst),

       .pni(I),

       .pnq(Q)

       );

 

 

qpsk_fa qpsk_fa_u(

                 //input

  .clk   (clk),               //8m

  .rst   (rst),

  .I     (I),

  .Q     (Q),

    .cos   (cos1),

  .sin   (sin1),

     .I_cos (I_cos),

  .Q_sin (Q_sin),

    .r     (r)

                 );

 

 

costas costas_u(

               //input

   .clk  (clk),

   .rst  (rst),

   .IO   (r),

   .QO   (r),

   //output

   .sin2 (sin2),

   .cos2 (cos2),

   .I_cos(I_cos2),

   .Q_sin(Q_sin2)   

               );

 

endmodule

01_112m`