FPGA数字信号处理(23)FSK解调技术(包络检波法)

上一篇介绍了数字通信系统中FSK调制技术的FPGA实现。调制信号经过DAC、可选的带通滤波器、功率放大器、天线发送出去后,在接收端收到FSK信号后需要对其解调,提取出包含的信息(基带信号)。


FSK解调

由上一篇可知,FSK调制信号可以视作两路ASK调制信号的合成,因此可以得到与ASK解调原理相似的FSK解调方法(ASK解调在第11篇中有讨论)。对应的包络检波法(非相干解调)的系统框图如下:
这里写图片描述
带通滤波器用于分出两路ASK调制信号,使用ASK解调方法解调,得到两路ASK信号的包络,加法器将两路保罗信号相减,再进行判决。假设f1代表1,f2代表0,则减法结果大于0则表示对应的基带信息为1;减法结果小于0则表示对应的基带信息为0。

包络检波法对FSK信号的相位特征没有要求,因此可用于FSK和CPFSK信号解调。但该方法只有在频移指数h>2时才有较好的性能,因为当h较小时,两个频率成分之间间隔较小,两路ASK信号之间频谱混叠和干扰严重,会影响到解调性能。
实际应用中多采用非相干解调,因为:

  • 提取FSK信号中的相干载波比较困难;
  • 码率相同时,非相干解调所需的信噪比只比相干解调高1~2dB。

除了本文将讨论的包络检波法外,非相干解调还有FFT分析法、自适应滤波解调法、差分检波算法、AFC环解调法、过零检测法等多种方法,会在以后的文章中详述。


MATLAB设计

MATLAB中可以设计程序仿真在使用包络检波法时,不同的h对检波效果的影响,验证上述结果。当h>2时,带通滤波才能得到区分度明显的ASK信号,解调得到的包络波也更规则,解调性能更好。解调关键代码如下:

%对FSK信号进行带通滤波
Wnf1=[(fc-m*ps)*2/Fs fc*2/Fs];
Wnf2=[fc*2/Fs (fc+m*ps)*2/Fs];
b1=fir1(60,Wnf1);
b2=fir1(60,Wnf2);
bs1_fsk=filter(b1,1,fsk);
bs2_fsk=filter(b2,1,fsk);
%对带通滤波后的数据进行全波整流
abs1_fsk=abs(bs1_fsk);
abs2_fsk=abs(bs2_fsk);
%对整流后的数据进行低通滤波
Lb=fir1(60,ps*2/Fs);
Lpf1_fsk=filter(Lb,1,abs1_fsk);
Lpf2_fsk=filter(Lb,1,abs2_fsk);
%对低通滤波后的两路信号相减,形成基带信号波形
Demod_fsk=Lpf1_fsk-Lpf2_fsk;

带通滤波器分别筛选两路ASK信号。以上一篇中的系统参数为例:系统时钟32Mhz,码元速率1Mhz,载波频率6Mhz,频移指数h=3.5,f1=4.25Mhz,f2=7.75MHz。带通滤波器通带可分别选为(6Mhz-h*1Mhz)~6Mhz和6Mhz~(6MHz+h*1Mhz)。

低通滤波器用于提取出基带信号包络,截止频率设置为码元速率即可。所有的滤波器系数经过量化后存储为txt(coe)文件,在FPGA设计中调用。


FPGA设计

采用包络检波法,在Vivado开发环境下完成2FSK解调技术的设计并进行仿真(调制信号参数与上节相同)。模块接口如下:

`timescale 1ns / 1ps
//--------------------------------------------------------
//   包络检波法(非相干解调)实现FSK信号解调
//--------------------------------------------------------
module FSKdem_EnvelopeDet
(
    input clk,          //32MHz系统时钟
    input rst,
    input din,          //基带信号输入,码元速率1MHz
    output [15:0] dout  //FSK解调数据输出
);

//-----------------------------------------------------
//   CPFSK调制,连续相位,h=3.5
//-----------------------------------------------------
wire [15:0] fsk;

CPFSK_liuqi fskmod
(
    .clk  (clk),     
    .rst  (rst),  
    .din  (din),     
    .dout (fsk)
);

这里实例化一个上一篇设计的FSK调制模块,用来产生FSK调制信号,简化后面的仿真及testbench的编写。接下来实例化两个带通滤波器模块,提取出两路ASK信号:

//--------------------------------------------------------
//   带通滤波器分为两路ASK信号
//--------------------------------------------------------
wire signed [31:0] data1, data2;
wire signed [15:0] bpf1 = data1[29:14]; 
wire signed [15:0] bpf2 = data2[29:14]; 

bpf1_fir fir1 (
  .aclk(clk),                           
  .s_axis_data_tvalid(1'b1), 
  .s_axis_data_tready(),
  .s_axis_data_tdata(fsk),  
  .m_axis_data_tvalid(),  
  .m_axis_data_tdata(data1)    
);
bpf2_fir fir2 (
  .aclk(clk),                           
  .s_axis_data_tvalid(1'b1), 
  .s_axis_data_tready(),
  .s_axis_data_tdata(fsk),  
  .m_axis_data_tvalid(),  
  .m_axis_data_tdata(data2)    
);      

带通滤波器及后面的低通滤波器都使用Vivado提供的FIR Compiler IP核,滤波器系数使用MATLAB生成的coe文件,具体使用方法可参考https://blog.csdn.net/fpgadesigner/article/details/80621411

接下来便是分别对两路ASK信号进行解调(方法见第11篇)代码如下:

//--------------------------------------------------------
//    整流,即求绝对值
//--------------------------------------------------------
reg signed [15:0] bpf1_abs, bpf2_abs;

always @ (posedge clk or posedge rst)
    if (rst) begin bpf1_abs <= 'd0; bpf2_abs <= 'd0; end
    else begin
        if (bpf1[15]) bpf1_abs <= -bpf1;
        else bpf1_abs <= bpf1;

        if (bpf2[15]) bpf2_abs <= -bpf2;
        else bpf2_abs <= bpf2;
    end

//--------------------------------------------------------
//    低通滤波得到基带信号包络
//--------------------------------------------------------
wire signed [31:0] lpf1, lpf2;

lpf_fir fir3 (
  .aclk(clk),                           
  .s_axis_data_tvalid(1'b1), 
  .s_axis_data_tready(),
  .s_axis_data_tdata(bpf1_abs),  
  .m_axis_data_tvalid(),  
  .m_axis_data_tdata(lpf1)    
);

lpf_fir fir4 (
  .aclk(clk),                           
  .s_axis_data_tvalid(1'b1), 
  .s_axis_data_tready(),
  .s_axis_data_tdata(bpf2_abs),  
  .m_axis_data_tvalid(),  
  .m_axis_data_tdata(lpf2)    
);

滤波器的输出便是两路ASK信号的包络,将两路信号相减:

//--------------------------------------------------------
//    减法得到解调信号
//--------------------------------------------------------
reg signed [15:0] sub;

always @ (posedge clk or posedge rst)
    if (rst) sub <= 'd0;
    else sub <= lpf1[29:14] - lpf2[29:14];

assign dout = sub;

减法器结果即为解调后信号,对此信号进行判决输出即可恢复出原始基带数据。需要注意,从下面的仿真中可以看出2FSK解调信号中不含直流分量,因此判决门限直接设置为0即可。判决门限及锁相环位同步技术在本系列12、13篇中有记录。


仿真测试

编写testbench,生成一个矩形脉冲周期信号,模拟二进制基带数据,设计中有模块调制产生FSK调制信号,再解调,仿真结果如下:
这里写图片描述
经过带通滤波后,bpf1和bpf2都只保留了一路ASK信号;整流及低通滤波后得到ASK的基带信号包络lpf1和lpf2。两者相减的结果dout即为解调信号。注意,虽然看起来dout与lpf1很像,但根据前面文章对ASK调制解调的讨论,基带包络lpf1是一个含直流分量的信号(所有值都大于0);而dout中有正有负,不含直流分量。

猜你喜欢

转载自blog.csdn.net/FPGADesigner/article/details/81170928