基于matlab的OFDM通信链路仿真,输出OFDM频谱,星座图,收发时域波形

279 阅读4分钟

1.算法描述

       在通信系统中,信道所能提供的带宽通常比传送一路信号所需的带宽要宽得多。如果一个信道只传送一路信号是非常浪费的,为了能够充分利用信道的带宽,就可以采用频分复用的方法。

 

       OFDM主要思想是:将信道分成若干正交子信道,将高速数据信号转换成并行的低速子数据流,调制到在每个子信道上进行传输。正交信号可以通过在接收端采用相关技术来分开,这样可以减少子信道之间的相互干扰(ISI) 。每个子信道上的信号带宽小于信道的相关带宽,因此每个子信道上可以看成平坦性衰落,从而可以消除码间串扰,而且由于每个子信道的带宽仅仅是原信道带宽的一小部分,信道均衡变得相对容易。

 

        OFDM技术是HPA联盟(HomePlug Powerline Alliance)工业规范的基础,它采用一种不连续的多音调技术,将被称为载波的不同频率中的大量信号合并成单一的信号,从而完成信号传送。由于这种技术具有在杂波干扰下传送信号的能力,因此常常会被利用在容易受外界干扰或者抵抗外界干扰能力较差的传输介质中。

 

       一个OFDM符号之内包含多个经过相移键控(PSK)或者正交幅度调制(QAM)的子载波。

 

       一旦要把传输的比特分配到各个子载波上,某一种调制模式则将他们映射为子载波的幅度和相位,通常采用等效基带信号来描述OFDM的输出信号:

1.png  

其中信号的实部和虚部分别对应OFDM的同相和正交分量,在实际系统可以分别与对应的c o s coscos分量和s i n sinsin分量相乘。

 

2.png

 

2.仿真效果预览

matlab2022a仿真如下:

3.png

4.png

5.png

6.png

7.png

8.png  

3.MATLAB核心程序 `%=====================添加循环前缀与后缀====================================

 

XX=zeros(symbols_per_carrier,IFFT_bin_length+GI+GIP);

 

for k=1:symbols_per_carrier;

 

    for i=1:IFFT_bin_length;

 

        XX(k,i+GI)=signal_after_IFFT(k,i);

 

    end

 

    for i=1:GI;

 

        XX(k,i)=signal_after_IFFT(k,i+IFFT_bin_length-GI);%添加循环前缀

 

    end

 

    for j=1:GIP;

 

        XX(k,IFFT_bin_length+GI+j)=signal_after_IFFT(k,j);%添加循环后缀

 

    end

 

end

 

time_wave_matrix_cp=XX;%添加了循环前缀与后缀的时域信号矩阵,此时一个OFDM符号长度为IFFT_bin_length+GI+GIP=660

 

%==============OFDM符号加窗==========================================

 

windowed_time_wave_matrix_cp=zeros(1,IFFT_bin_length+GI+GIP);

 

for i = 1:symbols_per_carrier

 

windowed_time_wave_matrix_cp(i,:) = real(time_wave_matrix_cp(i,:)).*rcoswindow(beta,IFFT_bin_length+GI)';%加窗  升余弦窗

 

end

 

%========================生成发送信号,并串变换==================================================

 

windowed_Tx_data=zeros(1,symbols_per_carrier*(IFFT_bin_length+GI)+GIP);

 

windowed_Tx_data(1:IFFT_bin_length+GI+GIP)=windowed_time_wave_matrix_cp(1,:);

 

for i = 1:symbols_per_carrier-1 ;

 

    windowed_Tx_data((IFFT_bin_length+GI)i+1:(IFFT_bin_length+GI)(i+1)+GIP)=windowed_time_wave_matrix_cp(i+1,:);%并串转换,循环后缀与循环前缀相叠加

 

end

 

%=======================================================

 

Tx_data=reshape(windowed_time_wave_matrix_cp',(symbols_per_carrier)*(IFFT_bin_length+GI+GIP),1)';%加窗后 循环前缀与后缀不叠加 的串行信号

 

%=================================================================

 

temp_time1 = (symbols_per_carrier)*(IFFT_bin_length+GI+GIP);%加窗后 循环前缀与后缀不叠加 发送总位数

 

figure (2)

 

subplot(2,1,1);

 

plot(0:temp_time1-1,Tx_data );%循环前缀与后缀不叠加 发送的信号波形

 

grid on

 

ylabel('Amplitude (volts)')

 

xlabel('Time (samples)')

 

title('循环前后缀不叠加的OFDM Time Signal')

 

temp_time2 =symbols_per_carrier*(IFFT_bin_length+GI)+GIP;

 

subplot(2,1,2);

 

plot(0:temp_time2-1,windowed_Tx_data);%循环后缀与循环前缀相叠加 发送信号波形

 

grid on

 

ylabel('Amplitude (volts)')

 

xlabel('Time (samples)')

 

title('循环前后缀叠加的OFDM Time Signal')

 

%===============加窗的发送信号频谱=================================

 

symbols_per_average = ceil(symbols_per_carrier/5);%符号数的1/5,10行

 

avg_temp_time = (IFFT_bin_length+GI+GIP)*symbols_per_average;%点数,10行数据,10个符号

 

averages = floor(temp_time1/avg_temp_time);

 

average_fft(1:avg_temp_time) = 0;%分成5段

 

for a = 0:(averages-1)

 

 subset_ofdm = Tx_data(((a*avg_temp_time)+1):((a+1)*avg_temp_time));%利用循环前缀后缀未叠加的串行加窗信号计算频谱

 

 subset_ofdm_f = abs(fft(subset_ofdm));%分段求频谱

 

 average_fft = average_fft + (subset_ofdm_f/averages);%总共的数据分为5段,分段进行FFT,平均相加

 

end

 

average_fft_log = 20*log10(average_fft);

 

figure (3)

 

subplot(2,1,2)

 

plot((0:(avg_temp_time-1))/avg_temp_time, average_fft_log)%归一化  0/avg_temp_time  :  (avg_temp_time-1)/avg_temp_time

 

hold on

 

plot(0:1/IFFT_bin_length:1, -35, 'rd')

 

grid on

 

axis([0 0.5 -40 max(average_fft_log)])

 

ylabel('Magnitude (dB)')

 

xlabel('Normalized Frequency (0.5 = fs/2)')

 

title('加窗的发送信号频谱')

 

%====================添加噪声=================================

 

Tx_signal_power = var(windowed_Tx_data);%发送信号功率

 

linear_SNR=10^(SNR/10);%线性信噪比

 

noise_sigma=Tx_signal_power/linear_SNR;

 

noise_scale_factor = sqrt(noise_sigma);%标准差sigma

 

noise=randn(1,((symbols_per_carrier)*(IFFT_bin_length+GI))+GIP)*noise_scale_factor;%产生正态分布噪声序列

 

Rx_data=windowed_Tx_data +noise;%接收到的信号加噪声

 

%=====================接收信号  串/并变换 去除前缀与后缀==========================================

 

Rx_data_matrix=zeros(symbols_per_carrier,IFFT_bin_length+GI+GIP);

 

for i=1:symbols_per_carrier;

 

    Rx_data_matrix(i,:)=Rx_data(1,(i-1)(IFFT_bin_length+GI)+1:i(IFFT_bin_length+GI)+GIP);%串并变换

 

end

 

Rx_data_complex_matrix=Rx_data_matrix(:,GI+1:IFFT_bin_length+GI);%去除循环前缀与循环后缀,得到有用信号矩阵

 

%==============================================================

 

%                      OFDM解码   16QAM解码

 

%=================FFT变换=================================

 

Y1=fft(Rx_data_complex_matrix,IFFT_bin_length,2);%OFDM解码 即FFT变换

 

Rx_carriers=Y1(:,carriers);%除去IFFT/FFT变换添加的0,选出映射的子载波

 

Rx_phase =angle(Rx_carriers);%接收信号的相位

 

Rx_mag = abs(Rx_carriers);%接收信号的幅度

 

figure(4);

 

polar(Rx_phase, Rx_mag,'bd');%极坐标坐标下画出接收信号的星座图

 

title('极坐标下的接收信号的星座图')

 

%======================================================================

 

[M, N]=pol2cart(Rx_phase, Rx_mag);

 

Rx_complex_carrier_matrix = complex(M, N);

 

figure(5);

 

plot(Rx_complex_carrier_matrix,'*r');%XY坐标接收信号的星座图

 

title('XY坐标接收信号的星座图')

 

axis([-4, 4, -4, 4]);

 

grid on

 

%====================16qam解调=======================================

 

Rx_serial_complex_symbols=reshape(Rx_complex_carrier_matrix',size(Rx_complex_carrier_matrix, 1)*size(Rx_complex_carrier_matrix,2),1)' ;

 

Rx_decoded_binary_symbols=demoduqam16(Rx_serial_complex_symbols);

 

%============================================================

 

baseband_in = Rx_decoded_binary_symbols;

 

figure(6);

 

subplot(2,1,1);

 

stem(baseband_out(1:100));

 

title('输出待调制的二进制比特流')

 

subplot(2,1,2);

 

stem(baseband_in(1:100));

 

title('接收解调后的二进制比特流')

A91`