第7章:OFDM 信道估计与均衡(1)

第7章(1)内容如下:

本人最近搞懂了OFDM的一些知识,便给本章取名为第7章——OFDM信道估计、均衡。本文所有代码下载地址是:123kevin456/OFDM-

一、OFDM相关书籍

OFDM书籍随便一查有非常多,缺少均衡、同步相关的代码实现,便难体会一些通信过程。我最近正在看的两本OFDM书籍,都是理论+代码结合来讲解,推荐给你。

1、《MIMO-OFDM无线通信技术及MATLAB实现》

此书最大特点便是有MATLAB源代码下载!下载!!下载!!!但由于代码版本可能老旧,因此需要偶尔改改代码适应新的MATLAB版本才可以正常运行。我试过OFDM的几个代码,结果还是不错的。

2、《Simulation and Software Radio for Mobile Communications》

此书我目前还没有发现中文版本,因此直接看的英文版本。这本书介绍了PSK调制、OFDM、CDMA、多址接入协议等内容的仿真,均有MATLAB源代码。

就OFDM来说,第1本书比第2本书,难度更大,且在均衡、同步,比如载波同步、位定时同步等内容,讲得更加详细。由于难度太大,我已琢磨许久,偶有所得,便在此更新

因此,本次文章后面分享的MATLAB可运行代码主要参考是第2本书。

二、OFDM基本原理

关于OFDM原理的基本介绍,知乎上的 @子木在其《OFDM完整仿真过程及解释(MATLAB)》 已经介绍非常清楚了,本系列文章主要是作为补充,尤其是将OFDM经过瑞利信道时的误码率性能仿真,以及如何通过信道估计来对信道进行补偿(compensation)

第7章:OFDM 信道估计与均衡(1)

图1 OFDM仿真系统框图

在这次的OFDM仿真中,为方便调试程序,首先做如下假设:
(1)调制:采用QPSK调制,可自己编写,也可以使用系统自带的pskmod函数;

(2)信道编码:一般采用(2,1,7)卷积码,本次仿真无编码;

(3)没有上载波与下载波过程,同时也没有发送端的上采样,接收端的匹配滤波,寻找最佳采样点过程;

待最基本的程序仿真正确后,再对其加入相应模块,以做完善。

三、OFDM经过高斯白噪声信道的误码率分析

本次仿真主要集中在将OFDM信号经过瑞利信道,是否有均衡,来观察误码率情况。

当然,在经过瑞利信道之前,不妨先测试一下OFDM在高斯白噪声信道下的传输。代码无误后,再将信道改成瑞利衰落信道。

先给出主要代码,各个函数的代码附在最后:

%%%%%%%%%%%%%%%%%%%%% OFDM仿真 %%%%%%%%%
%%%%%%%%%%%%%%%%%%%%% ofdm.m  %%%%%%%%%
%%%%%%%%%  date:2020年10月11日  author:飞蓬大将军 %%%%%%%%%%


%%%%%程序说明
%%%高斯白噪声信道下OFDM传输

%%%%    仿真环境
%软件版本:MATLAB R2019a

%********************** 程序主体 ************%

%%%%%%%%%%%%%%%%%%%%%  参数设置   %%%%%%%%%%%%%%%%%%%
para = 128;   %Number of parallel channel to transmit
fftlen = 128;  %FFT length
noc = 128;    %Number of carrier 
nd = 6;  %Number of information OFDM symbol for one loop
ml = 2;   %Modulation:QPSK
sr = 250000;  %Symbol rate 符号速率
br = sr.*ml;  %Bit rate per carrier
gilen = 32; %length of guard interval 


ebn0_temp = 3:1:10;
for kkk = 1:length(ebn0_temp)
    
ebn0 = ebn0_temp(kkk);  %Eb/No 
% ebn0 = 8;  %Eb/No

nloop = 10000; %Number of sumulation loops 
noe = 0;   %Number of error data  
nod = 0;   %Number of transmitted data 
eop = 0;   %Number of error packet  
nop = 0;   %Number of transmitted packet


for iii = 1:nloop
    %%%%%%%%%%%%%%%%%  发射机  %%%%%%%%%%%%%%%%%%%
    seldata = rand(1,para*nd*ml)>0.5;  %串行数据

    paradata = reshape(seldata,para,nd*ml); %串并转换

    [ich,qch] = qpskmod(paradata,para,nd,ml); %调制
    kmod = 1/sqrt(2);
    ich1 = ich.*kmod;
    qch1 = qch.*kmod;
    %%%%%%%%%%%% IFFT %%%%%%%%%%
    x = ich1 + qch1 *1j;
    
    spow1 = sum(sum(ich1.^2+ qch1.^2))/nd./para;
    
    y = ifft(x);
    ich2 = real(y);
    qch2 = imag(y);
    
    spow2 = sum(sum(ich2.^2+ qch2.^2))/nd./para;
    
    
    %%%%%%%% 添加保护间隔 %%%%%%%%
    [ich3,qch3] = giins(ich2,qch2,fftlen,gilen,nd);
    fftlen2 = fftlen + gilen;
    
%     figure(1);
%     plot(ich3,'-+');
%     hold on;
    
    
    
    %****************  Attenuation Calculation **************
    spow = sum(ich3.^2+ qch3.^2)/nd./para;
    attn = 0.5*spow*sr/br*10.^(-ebn0/10);
    attn = sqrt(attn);
    
    
    
    %%%%%%%%%%%%%%%%%%%%%%%  接收机  *************%%%%%%
    %%%%%%%%%%% AWGN addition *******************
    [ich4,qch4] = comb(ich3,qch3,attn);
    

%     plot(ich4,'-*');
  
    %%%%%%%% 去掉保护间隔 %%%%%%%%
    [ich5,qch5] = girem(ich4,qch4,fftlen2,gilen,nd);
 
    
    %%%%%%%%%%%%%%  FFT %%%%%%%%
    rx = ich5 + qch5.*1i;
    ry = fft(rx);
    ich6 = real(ry);
    qch6 = imag(ry);
    
    %%%%%%%%%%%%%% demoluation %%%%%%%%%%%%%%
    ich7 = ich6./kmod;
    qch7 = qch6./kmod;
    demodata = qpskdemod(ich7,qch7,para,nd,ml);
    
    %%%%%%%%%%%%%% 并串转换 %%%%%%%%%
    demodata1 = reshape(demodata,1,para*nd*ml);
    
    %%%%%%%%%%%%%%% Bit Error Rate %%%%%%%%%%%
    noe2 = sum(abs(demodata1-seldata));
    nod2 = length(seldata);
    
    %%%%cumulative the number of error and data in noe and nod
    noe = noe + noe2;
    nod = nod + nod2;
    
    %%%计算PER
    if noe2~=0
        eop = eop +1;
%     else
%         eop = eop;
        
    end

    nop = nop + 1;
%     fprintf('%f\t%e\t%d\n',iii,noe2/nod2,eop);
end

%**************   output result *************
per = eop/nop;
ber = noe/nod;

fprintf('%f\t%e\t%e\t%d\t\n',ebn0,ber,per,nloop);
fid = fopen('BERofdm.dat','a');
fprintf(fid,'%f\t%e\t%e\t%d\t\n',ebn0,ber,per,nloop);
fclose(fid);

end

%************************* 画误码率曲线进行对比 ******************%
% ebn0 = 3:1:10;
% awgn_theory = [0.0228784075610853,0.0125008180407376,0.00595386714777866,0.00238829078093281,0.000772674815378444,0.000190907774075993,3.36272284196176e-05,3.87210821552205e-06];
% awgn_no_compensation = [3.698496e-02,2.254329e-02,1.226654e-02,5.823633e-03,2.305339e-03,7.492187e-04,1.757812e-04,3.170573e-05];
% rayleign_one_path_theory = [0.125000000000000,0.100000000000000,0.0833333333333333,0.0714285714285715,0.0625000000000000,0.0555555555555556,0.0500000000000000,0.0454545454545455]; 
% 
% semilogy(ebn0,awgn_theory,'-*',ebn0,awgn_no_compensation,'-+');
% xlabel('比特信噪比');
% ylabel('误码率');
% title('不同信噪比下误码率仿真曲线');
% legend('理论曲线','实验曲线');
% grid on;

%***********   高斯白噪声下的OFDM采用QPSK调制的误码率值 **********%

%%%%%%%%%%%%%%%%%%%%%%%      理论值          **************%
%%%%%%%%%%%%%     EbN0(dB)      误码率        
%%%%%%%%%%%%%       3        0.0228784075610853
%%%%%%%%%%%%%       4        0.0125008180407376
%%%%%%%%%%%%%       5        0.00595386714777866
%%%%%%%%%%%%%       6        0.00238829078093281
%%%%%%%%%%%%%       7        0.000772674815378444
%%%%%%%%%%%%%       8        0.000190907774075993
%%%%%%%%%%%%%       9        3.36272284196176e-05
%%%%%%%%%%%%%      10        3.87210821552205e-06

%%%%%%%%%%%%%%%%%%%%%        实验值        *******%%%%%%%%%%%%
%%%%%%%%%%%%%      EbN0(dB)      误码率         误包率        循环次数
% % % % % % % % % 3.000000	3.698496e-02	1.000000e+00	10000	
% % % % % % % % % 4.000000	2.254329e-02	1.000000e+00	10000	
% % % % % % % % % 5.000000	1.226654e-02	1.000000e+00	10000	
% % % % % % % % % 6.000000	5.823633e-03	9.999000e-01	10000	
% % % % % % % % % 7.000000	2.305339e-03	9.709000e-01	10000	
% % % % % % % % % 8.000000	7.492187e-04	6.837000e-01	10000	
% % % % % % % % % 9.000000	1.757812e-04	2.384000e-01	10000	
% % % % % % % % % 10.000000	3.170573e-05	4.780000e-02	10000	    
   
%%%%%%%%%%%%%%%%%   结论    %%%%%%%%%%%%%%%%%%%%
%完成了OFDM经过高斯白噪声信道的误码率仿真
%由于OFDM中引入保护间隔,是一种冗余信息,因此相比于理论误码率曲线有10*log(160/128)=0.969dB的损失
%对应到误码率曲线上,即本实验误码率曲线相比理论误码率曲线向右平移0.969dB
%2020年11月7日   

第7章:OFDM 信道估计与均衡(1)

图2 OFDM采用QPSK在AWGN下的误码率曲线图

在上面的代码中,注意两点:

(1)当信号经过FFT之后,或者IFFT之后,功率会发生变化,这是为什么呢?功率的数量关系如何?

由N点DFT的表达式,知: X ( k ) = ∑ n = 0 N − 1 x ( n ) e − j 2 π N k n , k = 0 , 1 , ⋯   , N − 1 X\left( k \right) = \sum\limits_{n = 0}^{N - 1} {x\left( n \right){e^{ - j\frac{{2\pi }}{N}kn}}} ,k = 0,1, \cdots ,N - 1 X(k)=n=0∑N−1​x(n)e−jN2π​kn,k=0,1,⋯,N−1

为理解信号经过FFT前后功率发生的变化,联想到概率论中的公式: D ( a x + b y ) = a 2 D ( x ) + b 2 D ( y ) D\left( {ax + by} \right) = {a^2}D\left( x \right) + {b^2}D\left( y \right) D(ax+by)=a2D(x)+b2D(y)

因为 E { x ( 0 ) 2 } = E { x ( 1 ) 2 } = ⋯ = E { x ( N − 1 ) 2 } E\left\{ {x{{\left( 0 \right)}^2}} \right\} = E\left\{ {x{{\left( 1 \right)}^2}} \right\} = \cdots = E\left\{ {x{{\left( {N - 1} \right)}^2}} \right\} E{x(0)2}=E{x(1)2}=⋯=E{x(N−1)2}

所以有: E { X ( k ) 2 } = N ∙ E { x ( 0 ) 2 } E\left\{ {X{{\left( k \right)}^2}} \right\} = N \bullet E\left\{ {x{{\left( 0 \right)}^2}} \right\} E{X(k)2}=N∙E{x(0)2}

即信号经过FFT之后,功率变为原来的N倍。同理可以得到,信号经过IFFT后,功率变为原来的 1 N \frac{1}{N} N1​ 。

这样你便能理解ofdm.m代码中,发送端在经过IFFT后,才计算信号功率spow,再根据信噪比和spow,去计算相应的噪声功率

(2)仿真曲线相比于理论曲线看起来是向右平移的关系,所以是平移的关系码?如果是平移,那到底是平移了多少dB呢?

由于在本次仿真中,所有子载波采用相同的调制方式。当然,没有规定就说所有的子载波一定要采用相同的调制方式。

因此,既然子载波是采用相同的QPSK调制方式,那么理论线就是QPSK的误码率曲线,QPSK和2PSK的误码率曲线是一样的。

如果对QPSK和2PSK的误码率曲线是否一致,还未想清楚的话,请点击《陈老湿:问答交流1:采用过采样的原因》,看问题2的解释。

结合《第二章:线性分组码》中讲过信息比特与信道比特的关系。在上面的代码中,由于加入了保护间隔,保护间隔是采用循环前缀(Cyclic Prelix,CP)方式,即将OFDM符号中的后一部分进行复制,加入到OFDM前面,构成一个完整的OFDM符号。

复制的这一段信号,占用了功率资源,没有用来发送新的信息比特,因此便有了功率损失。注意到子载波数目是128,CP长度是32,即CP长度占整个OFDM符号长度的1/5。

举个数值例子方便你理解,本来你有1w的功率用来发送1个比特,现在你只能有0.8w用来发这个比特了,因为还有0.2w要用去给CP了。

所以相比下来会损失:10log10(1)-10log10(4/5)=0.9691dB。对应到本次实验中,即实验曲线会相比理论曲线有向右平移0.9691dB。

你也可以根据《第二章:线性分组码》中Eb/N0与SNR的换算关系,来将实验曲线进行向左平移0.9691dB,便可发现二者相近了。

那么问题来了,CP有什么用呢?CP的长度如何取呢?(思考几秒钟?)

在多径信道中,当信号带宽大于无线信道的相干带宽时,链路会受到多径衰落的影响,从而造成ISI(符号间干扰)。插入CP,可以避免ISI。当然,这要求CP的长度要大于最大多径时延扩展。

上面这段话,我不知道你看着是什么感觉?书上都是这么写的,以及上课老师也是这么讲的?但都没有说清楚为什么CP长度大于最大多径时延扩展,便可以避免ISI。

最大多径时延扩展,可以理解对一个符号最晚到达路径相对于最早到达路径的时间差。

下面从数学表达式来帮助你理解,这需要你有循环卷积线性卷积的概念。

第7章:OFDM 信道估计与均衡(1)

如图4.14所示,如果保护间隔长度小于最大多径时延扩展,对于前一个OFDM符号的尾部已经影响到下一个OFDM符号的前端,这样就造成ISI。在实际中,可能会出现符号定时偏差(STO),STO会使OFDM信号的前端和FFT窗的起始点不一致。

如图4.15所示,若CP的长度大于最大多径时延扩展,也可能会出现ISI和ICI(子载波干扰),这取决于FFT的起始点的定时。如果FFT窗的起始点早于时延的前一个符号末端,则会出现ISI,如果FFT窗的起始点晚于符号的起始点,既会出现ISI,又会出现ICI。

因此,在本次的AWGN信道仿真中,如果不加入保护间隔,也是可以的,加入CP对AWGN信道来说没起到实际的用处。如果你把保护间隔去掉,便就可以得到误码率的实验曲线和理论曲线非常接近了。

第7章:OFDM 信道估计与均衡(1)

第7章:OFDM 信道估计与均衡(1)

因此,当保护间隔采用循环前缀(Cyclic Prelix,CP)方式时,即将OFDM符号中的后一部分进行复制,加入到OFDM前面,构成一个完整的OFDM符号,保证了发射采样和信道采样的循环卷积性质。

注意到循环卷积的理解,下一节将根据循环卷积原理来对信道进行补偿。

第7章:OFDM 信道估计与均衡(1)

至此,已经讲完了CP的作用,以及怎么取。

三、总结

CP在高斯白噪声信道下起不到作用,那么如何看到OFDM在多径瑞利信道传输,CP发挥作用呢?

我们便首先要知道瑞利信道如何进行建模与仿真,之后便可以看到均衡对于信道补偿的作用。我们下次再讲。

也欢迎读者朋友就相关技术问题与我交流,一起学习,共同进步。请你也别忘了把这篇文章分享给你身边正在学习通信专业的同学们,也许能够帮到Ta。这是《陈老湿·通信MATLAB》仿真的第7章,期待下次更新见!

上一篇:21.10.28模拟 C


下一篇:【通信】OFDM-MIMO通信建模与仿真【Matlab 250期】