OFDM技术原理及系统MATLAB仿真

Posted 一只学习的猫

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OFDM技术原理及系统MATLAB仿真相关的知识,希望对你有一定的参考价值。

1 前言

最近除了在看信道相关的内容,还学习了一些OFDM相关的技术原理,并进行了简单的仿真。继续记录~~~
欢迎感兴趣的朋友一起交流分享。

2 OFDM技术原理

首先给出一个OFDM系统的系统框图,然后再对其中的关键点进行介绍。
在这里插入图片描述

2.1 子载波之间的正交性

我们知道OFDM作为一种多载波并行传输技术,一个很大的优点就是频带利用率高,因为他的子载波具有正交性。
我们最开始接触正交性,其实是一个数学概念:两个信号的乘积在一个周期内的积分为0,我们则认为这两个信号是正交的。也正是利用这一点,接收端可以通过对每一路乘以不同的因子,然后积分运算解调出对应路的信息,而不受其它路信号的干扰。需要注意的是,时延可能会影响子载波之间的正交性,从而导致解调错误,因此会在OFDM符号周期的前面添加循环前缀以消除这种影响,这在后面会讲到。
对于OFDM系统来说,从时域上来看是这样子的:
在这里插入图片描述
但是从频域上来看正交性如何提高了频带利用率可能更直观一些,我们进行一个简单的matlab仿真,假设有四个正交子载波承载信息,把他们的频谱画在一起,是这个样子的:
在这里插入图片描述
可以看到相比一般的FDM系统,子载波频谱发生了交叠,频带利用率更高。
还可以参考博客:
(https://blog.csdn.net/madongchunqiu/article/details/18614233/?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-1&spm=1001.2101.3001.4242)
我觉得讲解的非常形象,想了解的更多更详细的朋友可以看看。
补充:给出一个有频偏的情况下,OFDM系统的解调性能。

clear all;
close all;
N=8;                    % 子载波数
f=1:N;                  % 各个子载波频率
x=randi([0 3],1,N);   % 子载波上的数据
x1=qammod(x,4);          % 4-QAM调制

t=0:0.001:1-0.001;      % 符号持续时间
w=2*pi*f.'*t;
w1=2*pi*(f+0.2).'*t;    % 频偏为0.2Hz时的子载波频率
y=x1*exp(j*w);          % 子载波调制
figure(1)
plot(t,abs(y))          % 画出调制后的波形包络
for ii=1:N
    y1(ii)=sum(y.*exp(-j*w(ii,:)))/length(t); %无频偏解调第ii个子载波上的数据
end
figure(2)
stem(abs(x1))                      % 显示无频偏时子载波解调后的结果
hold on
stem(abs(y1),'r<')
title('频偏为0时的子载波解调结果')
axis([0 9 0 3])
legend('原始数据','子载波解调后的数据')

% 存在频率偏差时的子载波解调结果                       
for ii=1:N
    y3(ii)=sum(y.*exp(-j*(w1(ii,:))))/length(t);
end
figure(3)
stem(abs(x1))
hold on
stem(abs(y3),'r<')
axis([0 9 0 3])
title('频偏为0.2Hz时的子载波解调结果')
legend('原始数据','子载波解调后的数据')

仿真结果如下:
在这里插入图片描述
在这里插入图片描述
可以发现当有频偏时,OFDM系统解调的性能会变差。

2.2 IFFT和FFT

首先我们给出离散傅里叶变换和离散傅里叶逆变换的公式:
在这里插入图片描述
接下来我们推导为什么OFDM调制等价于一个离散傅里叶逆变换。一个OFDM调制的过程:OFDM发射机将信息比特流映射成一个PSK或QAM符号序列 ,之后将符号序列转换为 个并行符号流。每 个经过串/并转换的符号被不同的子载波调制,生成1个OFDM符号。
在这里插入图片描述

2.3 循环前缀的作用

加入保护间隔的作用主要是两个,其一是抑制符号间串扰(ISI),一个是抑制子载波间干扰(ICI)。
为了抑制符号间干扰,可以在两个OFDM符号之间插入保护间隔。插入保护间隔的方式有两种,一种是直接插入空白(插入0),只要插入的保护间隔长度大于信道的最大传播时延,就可以完全消除ISI,然而这样并不能解决多径带来的子载波间干扰问题(假设第2个子载波存在时延,那么将导致在一个OFDM符号周期内,第2子载波不包括整数个周期波形,在解调时会对第一个子载波造成干扰)。为了消除由于多径导致的ICI,引入了第二种插入保护间隔的方法:插入循环前缀,将OFDM符号周期内的最后若干个点搬移导OFDM符号的前面。
下面给出一个OFDM系统加入空白前缀和循环前缀的系统性能对比仿真:

clear all;
close all;
N=64;                       % 系统子载波数
x=randi([0 15],N,2);      % 2个符号周期的数据
x1=qammod(x,16);            % 16-QAM调制
x2=ifft(x1);                % IFFT
x3=[zeros(16,2); x2];       % 空白前缀
x4=[x2(49:end,:); x2];      % 循环前缀

x3=reshape(x3,1,160);       % 并串变换
x4=reshape(x4,1,160);

h=sqrt(1/3)*(randn(1,3));   % 3径信道

y1=x3*h(1)+[zeros(1,8) x3(1:end-8)*h(2)]; %只考虑前2径
y2=x4*h(1)+[zeros(1,8) x4(1:end-8)*h(2)];

y3=reshape(y1,80,2);        % 串并变换
y4=reshape(y2,80,2);

y3=y3(17:end,2);            % 考虑第2个符号的影响
y4=y4(17:end,2);

y3=fft(y3);                 % FFT
y4=fft(y4);

h1=[h(1) zeros(1,7) h(2)];  % 信道FFT变换
H=fft(h1,N).';
y3=y3./H;                   % 信道均衡
y4=y4./H;

stem(abs(x1(:,2)),'fill');hold on;stem(abs(y3),'r<');stem(abs(y4),'-gs')
legend('原始信号','空白前缀','循环前缀')
axis([0 70 0 max(abs(y3))+2])
title('2径信道结果')

y1=y1+[zeros(1,20) x3(1:end-20)*h(3)];      % 3径信道结果
y2=y2+[zeros(1,20) x4(1:end-20)*h(3)];

y3=reshape(y1,80,2);        % 串并变换        
y4=reshape(y2,80,2);

y3=y3(17:end,2);            % 考虑第2个符号的影响
y4=y4(17:end,2);

y3=fft(y3);                 % FFT
y4=fft(y4);

h1=[h1 zeros(1,11) h(3)];   % 信道FFT变换
H=fft(h1,N).';
y3=y3./H;                   % 信道均衡
y4=y4./H;
figure
stem(abs(x1(:,2)),'fill');hold on;stem(abs(y3),'r<');stem(abs(y4),'-gs')
legend('原始信号','空白前缀','循环前缀')
axis([0 70 0 max(max(abs(y3),abs(y4)))+2])
title('3径信道结果')

仿真结果如下:
在这里插入图片描述
从上图中可以看出,在2径信道的情况下,经过信道均衡后,添加了循环前缀的第2个OFDM符号没有受到第一个OFDM符号和子载波间的干扰,而添加空白前缀的符号受到子载波间干扰的影响,因此解调结果与原始数据不一致。
在这里插入图片描述
在多径时延大于循环前缀的长度时,无法消除码间串扰,第2个OFDM符号受到第一个OFDM符号的干扰。

3 OFDM系统仿真

在对OFDM系统的一些比较重要的知识点进行介绍之后,下面给出一个OFDM系统的仿真主程序:

clear all;
close all;
clc;
Nsymbol = 100;   % OFDM符号个数
Ncarrier = 256;  % 子载波个数
space_pilot_carrier = 5;  % 子载波间隔
space_pilot_time = 10;    % 时域导频间隔
N_pilot_time = Nsymbol/space_pilot_time;   % 时域导频个数
N_pilot_carrier = (Ncarrier-1)/space_pilot_carrier+1;   % 频域导频个数
N_sym_pilot = N_pilot_carrier*N_pilot_time;   % 导频符号数
N_valid_sym = Nsymbol*Ncarrier-N_sym_pilot;   % 有效符号数
Nvalid_data = N_valid_sym;   % 有效的输入二进制比特数 
len_cp = 64;   % 循环前缀长度
origdata = randi([0,3],1,N_valid_sym);  %% 有效的符号
modulation_type = 'QPSK';    % 子载波调制类型 1: QPSK,2:16QAM,3:64QAM
fs = 4e6;  % 采样率
Ts = 1/fs; % 采样周期  单位s
sym_constell = pskmod(origdata,4);   % 映射后的有效符号

value = 1;  % 插入导频值为1

% 生成数据矩阵
data_matrix = zeros(Ncarrier,Nsymbol);
count = 1; 
for nn=1:Nsymbol
    for mm = 1:Ncarrier
        if ((mod(mm,space_pilot_carrier)==1)&&(mod(nn,space_pilot_time)==1))
            data_matrix(mm,nn) = value;
        else
            data_matrix(mm,nn) = sym_constell(count);
            count = count+1;
        end
    end
end
 
% IFFT
Tx_data = ifft(data_matrix,Ncarrier);


% 加CP
Tx_data_add_cp = [Tx_data(Ncarrier-len_cp+1:Ncarrier,:);Tx_data];

% 并串转换
len_row = len_cp+Ncarrier;   % 行数
len_column = Nsymbol;        % 列数
len_tx = len_row*len_column; % 总符号数
Tx_data_stream = zeros(1,len_tx);
count_tx = 1;
for ss = 1:len_column
    for  kk = 1:len_row
           Tx_data_stream(count_tx) = Tx_data_add_cp(kk,ss);
           count_tx =count_tx+1;
    end
end

Terrain_Index = 'RA';                                                    
Doppler=120;% 最大多普勒频移,决定了信道的时变快慢,当v=60km/h,fc = 2.4G时,fdmax = 133Hz
SNR = -10:1:30;
for ii = 1:length(SNR)
    snr = SNR(ii);
    % 通过COST207信道 
    [data_receive,tap_coff,sigma2_w]=Channel_pass_COST207(Tx_data_stream, Terrain_Index, Nsymbol,Ts, snr, Doppler);
    
    % 串并转换
    data_r = reshape(data_receive,len_row,[]);
    
    % 去除循环前缀
    data_r_no_cp = data_r(len_cp+1:end,:);
    
    % FFT
    data_r_fft =  fft(data_r_no_cp,Ncarrier);
    
    % 二维线性插值信道估计及均衡
    [equa_2D_linear_data,MSE_linear_interp_2D] = linear_interp_2D_chann_estimation(data_r_fft,Nsymbol,Ncarrier,N_pilot_carrier,N_pilot_time,space_pilot_carrier,space_pilot_time,tap_coff);
    
    % 去导频
    throwpilot_data = remove_pilot(equa_2D_linear_data,Nsymbol,modulation_type,N_pilot_carrier,N_pilot_time,space_pilot_carrier,space_pilot_time);
    
    % 逆映射
    demod_data=pskdemod(throwpilot_data,4);
    
    % 误码率性能
    [err_num_sym(ii),err_rate_sym(ii)]=symerr(origdata,demod_data);
    
    disp('err_num_sym:');
    disp(err_num_sym(ii));
    
    disp('err_rate_sym:');
    disp(err_rate_sym(ii));
end
figure(1)
plot(SNR,err_rate_sym*100,'linewidth',1);
xlabel('SNR/dB');
ylabel('误码率/%');

仿真的结果:
在这里插入图片描述

4 总结

以上主要是介绍了OFDM技术的一些基础知识,对于OFDM系统中的关键模块都有相关的算法研究,比如同步、信道估计、符号检测等等,希望后面能有更深入的了解。

参考书籍:
《详解MATLAB/Simulink通信系统建模与仿真》

以上是关于OFDM技术原理及系统MATLAB仿真的主要内容,如果未能解决你的问题,请参考以下文章

MATLAB-Simulink仿真实现OFDM通信系统

MATLAB-Simulink仿真实现OFDM通信系统

现代通信基于OFDM通信系统仿真matlab源码

现代通信基于matlab OFDM通信系统仿真含Matlab源码 1005期

误码率仿真基于matlab多径信道下OFDM通信系统误码率仿真含Matlab源码 2078期

误码率仿真基于matlab多径信道下OFDM通信系统误码率仿真含Matlab源码 2078期