基于802.11n物理层的OFDM通信链路simulink仿真,包括FEC编码、插入导频、OFDM成帧、STBC编码

发布时间 2023-03-23 13:35:13作者: 我爱C编程

1.算法描述

        5G的推广和下一代无线通信系统的兴盛,怎样应对现有频谱资源的紧缺与改善信息传输的质量成了迫在眉睫的难题,对重要技术的开发利用提出了更高的要求。其中,以MIMO多入多处技术与OFDM正交频分复用技术的结合效果最为突出。通过子载波的正交性以及多天线传输的优势,在不需要额外地增加带宽的情况下极大地提高了通信系统地性能,目前此技术已经成为了无线通信系统的主流。

 

        在通信系统中,信道所能提供的带宽通常比传送一路信号所需的带宽要宽得多。如果一个信道只传送一路信号是非常浪费的,为了能够充分利用信道的带宽,就可以采用频分复用的方法。OFDM主要思想是:将信道分成若干正交子信道,将高速数据信号转换成并行的低速子数据流,调制到在每个子信道上进行传输。正交信号可以通过在接收端采用相关技术来分开,这样可以减少子信道之间的相互干扰(ISI) 。每个子信道上的信号带宽小于信道的相关带宽,因此每个子信道上可以看成平坦性衰落,从而可以消除码间串扰,而且由于每个子信道的带宽仅仅是原信道带宽的一小部分,信道均衡变得相对容易。

 

         OFDM中的各个载波是相互正交的,每个载波在一个符号时间内有整数个载波周期,每个载波的频谱零点和相邻载波的零点重叠,这样便减小了载波间的干扰。由于载波间有部分重叠,所以它比传统的FDMA提高了频带利用率。在OFDM传播过程中,高速信息数据流通过串并变换,分配到速率相对较低的若干子信道中传输,每个子信道中的符号周期相对增加,这样可减少因无线信道多径时延扩展所产生的时间弥散性对系统造成的码间干扰。另外,由于引入保护间隔,在保护间隔大于最大多径时延扩展的情况下,可以最大限度地消除多径带来的符号间干扰。如果用循环前缀作为保护间隔,还可避免多径带来的信道间干扰。

 

       OFDM技术将高速的宽带信号变换为窄带信号,再调制到并行的子载波上进行传输。这样的使得之前的频率选择性信道变为了平坦的子信道,且因为其码元周期较长,它的抗码间干扰能力也较强。其中,OFDM的正交性可以从频域和时域的角度解释如下图所示:

 

 

 

 

        一个OFDM符号的时域信号和频域信号。其中时域信号图3-2中每个子载波在一个OFDM 符号周期内都包含整数倍的周期,而且各个相邻子载波之间相差1个周期,各子载波信号之间满足交性。 信号在经过无线信道传输后,有效信息会和一些干扰的噪声信息信息叠加在一起,这会大大影响整个通信系统的准确性,因此需要信号检测技术将有用的信息分离出来,来保证接收到收到信息的可靠性。常见的信号检测有线性检测和非线性检测,此次设计采用的是线性检测中的MMSE算法,通过加权矩阵使接收到的信号分离成互不相关的信号从而可以得到有效的信息。

 

        由于无线通信系统的不确定性,数据在传输过程中时常会出现误码、丢包的情况,导致整个通信系统性能恶化。所以设计合理的信道编码方式,可以有效提高系统的抗干扰能力。FEC前向纠错码是指通过在传输列中加入冗余码进行纠错,此次设计的前向纠错码采用的是卷积编码。它在发送的信息比特时会加入冗余的纠错比特,纠错比特能够在接收端接收到信息后对信息进行判断,找到错误的信息比特并进行纠错。其中,纠错的比特不仅会与自身所在的码元有关,还会与前后码元有关,使得他的纠错能力会更好,提高整个系统发送信息的准确性。但是通过引入冗余数据,降低了传输的数据的效率,所以在设计FEC码时也应考虑冗余的位数。

 

      总体设计思路如图3所示:

 

 

 

 

       与以前的协议相比,802.11n协议具有较大的性能提升,主要是因为其采用MIMO技术和OFDM技术的结合,以及大量优化系统的算法,从而凸显其优越性。MIMO OFDM[6]可以有效解决带宽效率和多径干扰问题,通过其子载波正交及其循环前缀的优势能够有效提高系统的抗干扰能力,MIMO则通过多天线技术可以实现多个数据流的传输。两者的结合结合,既能实现高速率传输,又能通过分编码实现很强的可靠性。本章对此次设计中的重要技术及其相关算法作相关研究,并对其TGn信道进行研究学习。

 

2.仿真效果预览

matlab2022a仿真结果如下:

 

 

 

 

 

 

 

 

3.MATLAB核心程序

 

 

 

 

         通过Matlab/Simulink仿真平台搭建基于802.11n的无线通信系统,分别从发送端、信道和接收端进行模块设计,其中发射端包括信源、FEC编码、调制,插入导频、OFDM成帧、STBC编码、插入循环前缀、IFFT等,信道设计采用的是TGn室内信道模型,接收端对照发射端有着相应的信号处理,其主要的分析模块有信道估计、MIMO信号检测,SNR估计。

 

function [dataout] = MMSE(ch_and_rx)
global PER_snr snr_idx;
% Initialize vectors
STBC = ch_and_rx(1);
Nss  = ch_and_rx(2);
Nsts = Nss + STBC;
Nltf = Nsts;
if (Nsts==3) % use 4 TRN symbols for NSTS=3
   Nltf = 4;
end
 
Nrx  = ch_and_rx(3);
ch_est  = ch_and_rx(3+(1:16*56));
rx_data = ch_and_rx((4+16*56+4*56*(Nltf)):end);
 
%%%% Form channel matrix构建信道矩阵 y = ha + r,由信号的冲激响应构成
idx = 0;
H = zeros(4,4,56);
for c=1:4
    for r=1:4
        H(r,c,:) = ch_est(idx+(1:56));
        idx=idx+56;
    end
end
H = H(1:Nrx,1:Nsts,:);  %% channel matrix is Nrx x Nst 构建相应的发射端接收端的信道矩阵
 
%%%% Rx data symbols...构造接收信号矩阵
idx = 0;
nsymdata = (length(rx_data)/4/56);%接收符号的数目
rdata = zeros(4,56,nsymdata);
for n=1:nsymdata
    for m=1:Nrx
        rdata(m,:,n) = rx_data(idx+(m-1)*56+(1:56));
    end
    idx=idx+4*56;
end
 
%%%%
%%%% STBC or MMSE...进行STBC解码或者MMSE信号检测
%%%%
if (STBC)    
    %%%% Form space-time decoding matrices 构造空时解码矩阵
    for k=1:56
        if (STBC==1 && Nss==1)
            % 加权矩阵 假设用两个符号来表示状态信息
            Heff(:,:,k) = [      H(1,1,k)      -H(1,2,k); ...  
                            conj(H(1,2,k)) conj(H(1,1,k)) ];  
        elseif (STBC==1 && Nss==2)
            Heff(:,:,k) = [      H(1,1,k)      -H(1,2,k)       H(1,3,k)              0;  ...  
                            conj(H(1,2,k)) conj(H(1,1,k))             0  conj(H(1,3,k)); ...  
                                 H(2,1,k)      -H(2,2,k)       H(2,3,k)              0;  ...
                            conj(H(2,2,k)) conj(H(2,1,k))             0  conj(H(2,3,k)) ];  
        elseif (STBC==1 && Nss==3)
            Heff(:,:,k) = [      H(1,1,k)      -H(1,2,k)       H(1,3,k)              0        H(1,4,k)              0;  ...  
                            conj(H(1,2,k)) conj(H(1,1,k))             0  conj(H(1,3,k))              0  conj(H(1,4,k)); ...  
                                 H(2,1,k)      -H(2,2,k)       H(2,3,k)              0        H(2,4,k)              0;  ...
                            conj(H(2,2,k)) conj(H(2,1,k))             0  conj(H(2,3,k))              0  conj(H(2,4,k)); ...  
                                 H(3,1,k)      -H(3,2,k)       H(3,3,k)              0        H(3,4,k)              0;  ...
                            conj(H(3,2,k)) conj(H(3,1,k))             0  conj(H(3,3,k))              0  conj(H(3,4,k)) ];  
        elseif (STBC==2 && Nss==2)
            Heff(:,:,k) = [      H(1,1,k)      -H(1,2,k)       H(1,3,k)      -H(1,4,k);  ...  
                            conj(H(1,2,k)) conj(H(1,1,k)) conj(H(1,4,k)) conj(H(1,3,k)); ...
                                 H(2,1,k)      -H(2,2,k)       H(2,3,k)      -H(2,4,k);  ...
                            conj(H(2,2,k)) conj(H(2,1,k)) conj(H(2,4,k)) conj(H(2,3,k)) ];  
        end
    end
%%%% Compute noise power...
    N_o = 0;
    for k=1:56
        He = Heff(:,:,k);
        N_o = N_o + (1/56)*sum(sum(He.*conj(He)))/Nrx;     % Signal power
    end
    snr_val = PER_snr(snr_idx);
    N_o = N_o * 10^(-snr_val/10);     
    
    %%%% Compute space-time detector coeff's
    C = zeros(Nss*2,Nss*2,56);
    for k=1:56
        %%%% MMSE coeff's
        He = Heff(:,:,k);
        C(:,:,k) = inv(He'*He + N_o*eye(Nss*2))*He';
        %C(:,:,k) = inv(He'*He)*He';
    end
    
    %%%% Compute space-time decoding outputs
    idx = 0;
    detout = zeros(4*56*nsymdata,1);
   
    for n=1:2:nsymdata
        for k=1:56
            if (STBC==1 && Nss==1)
                % MMSE_det outputs
                detset = C(:,:,k) * [ rdata(1,k,n); ...
                                      conj(rdata(1,k,n+1)) ];
                detout(k+idx+0*56) = detset(1);         % first symbol in time, ss1
                detout(k+idx+4*56) = conj(detset(2));   % second symbol in time, ss1
               
            elseif (STBC==1 && Nss==2)
                % MMSE_det outputs
                detset = C(:,:,k) * [ rdata(1,k,n); ...
                                      conj(rdata(1,k,n+1)); ...
                                      rdata(2,k,n); ...
                                      conj(rdata(2,k,n+1)) ];
                detout(k+idx+0*56) = detset(1);         % first symbol in time, ss1
                detout(k+idx+4*56) = conj(detset(2));   % second symbol in time, ss1
                detout(k+idx+1*56) = detset(3);         % first symbol in time, ss2
                detout(k+idx+5*56) = conj(detset(4));   % second symbol in time, ss2
                
            elseif (STBC==1 && Nss==3)
                % MMSE_det outputs
                detset = C(:,:,k) * [ rdata(1,k,n); ...
                                      conj(rdata(1,k,n+1)); ...
                                      rdata(2,k,n); ...
                                      conj(rdata(2,k,n+1)); ...
                                      rdata(3,k,n); ...
                                      conj(rdata(3,k,n+1)) ];
                detout(k+idx+0*56) = detset(1);         % first symbol in time, ss1
                detout(k+idx+4*56) = conj(detset(2));   % second symbol in time, ss1
                detout(k+idx+1*56) = detset(3);         % first symbol in time, ss2
                detout(k+idx+5*56) = conj(detset(4));   % second symbol in time, ss2
                detout(k+idx+2*56) = detset(5);         % first symbol in time, ss3
                detout(k+idx+6*56) = conj(detset(6));   % second symbol in time, ss3
                
            elseif (STBC==2 && Nss==2)
                % MMSE_det outputs
                detset = C(:,:,k) * [ rdata(1,k,n); ...
                                      conj(rdata(1,k,n+1)); ...
                                      rdata(2,k,n); ...
                                      conj(rdata(2,k,n+1)) ];
                detout(k+idx+0*56) = detset(1);         % first symbol in time, ss1
                detout(k+idx+4*56) = conj(detset(2));   % second symbol in time, ss1
                detout(k+idx+1*56) = detset(3);         % first symbol in time, ss2
                detout(k+idx+5*56) = conj(detset(4));   % second symbol in time, ss2
              
            end
        end
        idx=idx+8*56;
    end
 
else
 
    %%%% Compute noise power...
    N_o = 0;
    for k=1:56
        He = H(:,:,k);
        N_o = N_o + (1/56)*sum(sum(He.*conj(He)))/Nrx;     % Signal power
    end
    snr_val = PER_snr(snr_idx);
    N_o = N_o * 10^(-snr_val/10);       
    
    %%%%% MMSE linear detector (no STBC)
    C = zeros(Nsts,Nrx,56);
    for k=1:56
        %%%% MMSE coeff's
        He = H(:,:,k);
        C(:,:,k) = inv(He'*He + N_o*eye(Nrx)) * He'; 
        %C(:,:,k) = inv(He'*He) * He';
    end
    %%%% MMSE_det outputs
    idx = 0;
    detset = zeros(4,1);
    detout = zeros(4*56*nsymdata,1);
    
    for n=1:nsymdata
        for k=1:56
            % MMSE_det outputs
            detset(1:Nsts) = C(:,:,k)*rdata(1:Nrx,k,n);
            detout(k+idx+0*56) = detset(1);
            detout(k+idx+1*56) = detset(2);
            detout(k+idx+2*56) = detset(3);
            detout(k+idx+3*56) = detset(4);
           
        end
        idx=idx+4*56;
    end
    
end
% MMSE_det module output
dataout = detout;