matlab的旋律 发表于 2018-5-3 17:36:13

OFDM系统中固定频偏算法

本帖最后由 matlab的旋律 于 2018-5-3 18:12 编辑

加入固定频偏:
function berMatrix = freqOffsetOFDM(BPS,NS,M,SNR,ifftsize,carriers,N,ep)

%标准OFDM系统
input_bit_stream= sign(randn(1,BPS*NS));
input_bit_stream(input_bit_stream== -1)=0;
parallel_data = StoP(input_bit_stream ,M);% 串并转换
%QAM调制
modulated_data =qammod(parallel_data,M);
berMatrix = zeros(size(SNR));
for m=1:length( SNR)%信噪比变量
    k= 1 ;
    for n = 1 : NS%OFDM信号序数变量
      ofdm_symbol = zeros(1 ,ifftsize);
      ofdm_symbol(carriers) = modulated_data(k: k+N-1);%各子信道加载数据
      %IFFT转换成时域信号
      tx_signal = ifft(ofdm_symbol ,ifftsize);
      %信道
      %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      %加入频域频移
      rx_signal = tx_signal.*exp((2*1i*pi*ep/ifftsize).*(0:ifftsize-1));
      %加入噪声
      rx_signal=awgn(rx_signal,SNR(m),'measured');
      %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      received_ofdm= fft(rx_signal, ifftsize); %FFT转换成各自通道数据
      received_symbols(k:k+N-1) = received_ofdm(carriers); %去掉循环前缀
      k= k +N ;
    end%OFDM信号序数变量结束

    %received_symbols:接收端FFT后得到的各子通道的复数据,
    %          直接画得到星座图
    %          %figure
    %          subplot(1,4,ll)
    %          plot(received_symbols,'*');
    %          axis([-log2(M),log2(M),-log2(M),log2(M)]);
    %          title(['\epsilon=' num2str(ep)] );

    %接收端对M进制复数据解调,得到M进制码元
    received_data =qamdemod(received_symbols,M);
    output_bit_stream = PtoS(received_data, M);%M进制转换为二进制码元
    berMatrix(m)= sum(xor(input_bit_stream, output_bit_stream))/length(input_bit_stream);%计算误码率
end %信噪比变量结束


对加频偏信号进行ICI自消除:
function berMatrix = freqOffsetOFDMICI(BPS,NS,M,SNR,ifftsize,carriers,N,ep)

%ICI自消除法
% Input Bit Streamis normally Distributed
input_bit_stream= sign(randn(1,BPS*NS));
input_bit_stream(input_bit_stream== -1)=0;
parallel_data = StoP(input_bit_stream ,M);
modulated_data =qammod(parallel_data,M);%QAM调制
%奇偶载波序列定义
odd_carriers = carriers(1:2: N-1);
even_carriers = carriers(2:2: N);

berMatrix = zeros(size(SNR));
for m=1:length(SNR) %信噪比变量
    k = 1;
    for n = 1:NS   %OFDM信号序数变量
      ofdm_symbol1 = zeros(1,ifftsize);
      ofdm_symbol2 = zeros(1,ifftsize);
      ofdm_symbol1(odd_carriers) = modulated_data(k: k+N/2-1);
      ofdm_symbol1(even_carriers) = -modulated_data(k: k+N/2-1); %奇通道数据取反
      ofdm_symbol2(odd_carriers) = modulated_data(k+N/2: k+N-1);
      ofdm_symbol2(even_carriers) = -modulated_data(k+N/2:k+N-1); %奇通道数据取反
      %发送端时域信号
      tx_signal1 = (ifft(ofdm_symbol1,ifftsize));
      tx_signal2 = (ifft(ofdm_symbol2,ifftsize));
      %信道
      %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      %加入频移
      rx_signal1 = tx_signal1.*exp(1i*pi*ep/ifftsize*(0:ifftsize-1));
      rx_signal2 = tx_signal2.*exp(1i*pi*ep/ifftsize*(0:ifftsize-1));
      %加入噪声
      rx_signal1 = awgn(rx_signal1, SNR(m),'measured');
      rx_signal2 = awgn(rx_signal2, SNR(m),'measured');
      %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      % 接收端FFT
      received_ofdm1 = fft(rx_signal1, ifftsize);
      received_ofdm2 = fft(rx_signal2, ifftsize);
      demod_sym1 = .5*(received_ofdm1(odd_carriers)-received_ofdm1(even_carriers));%前半个OFDM信号
      demod_sym2 = .5*(received_ofdm2(odd_carriers)-received_ofdm2(even_carriers));%后半个OFDM信号
      received_ofdm3 = ;
      received_symbols(k:k+N-1) = received_ofdm3;
      k = k + N;
    end %OFDM信号序数变量结束
    received_data =qamdemod(received_symbols,M);%接收端对M进制复数据解调,得到M进制码元
    output_bit_stream = PtoS(received_data, M);%M进制转换为二进制码元
    berMatrix(m)= sum(xor(input_bit_stream, output_bit_stream))/length(input_bit_stream); %计算误码率
end %信噪比变量结束

极大似然估计法和改进算法
function berMatrix = freqOffsetOFDMMSL(BPS,NS,M,SNR,ifftsize,carriers,N,ep,N_awgn)

%极大似然估计法和改进算法
input_bit_stream= sign(randn(1,BPS*NS));
input_bit_stream(input_bit_stream== -1)=0;
parallel_data = StoP(input_bit_stream ,M);% 串并转换
modulated_data =qammod(parallel_data,M);%QAM调制
berMatrix = zeros(size(SNR));
for m=1:length(SNR)%信噪比变量
    %计算ep-SNR对应的频偏
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    ofdm_symbol = zeros(1,ifftsize);
    ofdm_symbol(carriers(1:N/2)) = modulated_data(1:N/2);   %Use only half the data for MLE
    tx_signal1 = ifft(ofdm_symbol,ifftsize/2);   %对前一半通道的数据进行ifft_size/2的IFFT
    tx_signal = ;         %复制前一半OFDM信号,形成一个完整的发送信号

    %信道
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %加入频移
    rx_signal = tx_signal.*exp((2*1i*pi*ep/ifftsize).*(0:ifftsize-1));
    %加入噪声
    %极大似然估计法:N_awgn=1;
    %修正算法:N_awgn>1;
    noise=0;
    for n_awgn=1:N_awgn
      %加入高斯白噪声
      noise=noise+awgn(rx_signal,SNR(m),'measured');
    end
    noise=noise/N_awgn;
    rx_signal = rx_signal + noise;
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %接收端对前后两时域序列分别进行FFT
    received_ofdm1 = fft(rx_signal(1:ifftsize/2), ifftsize/2);
    received_ofdm2 = fft(rx_signal((ifftsize/2)+1:ifftsize), ifftsize/2);

    %对频偏进行极大似然估计
    temp=0;temp1=0;
    for w=1:length(ifftsize/2)
      temp=temp + imag(received_ofdm2(w)*conj(received_ofdm1(w)));
      temp1=temp1 + real(received_ofdm2(w)*conj(received_ofdm1(w)));
    end
    epestMLE(m) = (atan(temp/temp1))/(pi);

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %完成ep-SNR对应的频偏估计
    %以后接收到的OFDM信号直接用估计值校正
    k = 1;
    for n = 1:NS%OFDM信号序数变量
      ofdm_symbol = zeros(1,ifftsize);
      ofdm_symbol(carriers(1:N)) = modulated_data(k:k+N-1);   %各子信道加载数据
      tx_signal = ifft(ofdm_symbol,ifftsize);%IFFT转换成时域信号

      %信道
      %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      rx_signal = tx_signal.*exp((2*1i*pi*ep/ifftsize).*(0:ifftsize-1));%加入频域频移
      rx_signal=awgn(rx_signal,SNR(m),'measured');%加入噪声
      %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      %利用第一次估计出的频偏进行校正
      received_ofdm = rx_signal.* exp((-2*1i*pi*epestMLE(m)/ifftsize)*(0:ifftsize-1));
      car_data= fft(received_ofdm,ifftsize); %FFT转换成各自通道数据
      received_symbols(k:k+N-1)=car_data(carriers(1:N)); %去掉循环前缀
      k = k + N;
    end %OFDM信号序数变量结束
    received_data =qamdemod(received_symbols,M);%接收端对M进制复数据解调,得到M进制码元
    output_bit_stream = PtoS(received_data, M); %M进制转换为二进制码元
    berMatrix(m)= sum(xor(input_bit_stream, output_bit_stream))/length(input_bit_stream); %计算误码率

end %信噪比变量结束

M进制转换为二进制码元:
function y=PtoS(received_data, M)

%M进制转换为二进制码元
M=log2(M);
=size(received_data);
y=zeros(1,M*n);
for k1=1: n
    for k2=1: M
      if(received_data(k1)>=2^(M-k2))
            y(M*(k1-1)+k2)=1;
            received_data(k1)=received_data(k1)-2^(M-k2);
      else
            y(M*(k1-1)+k2)=0;
      end
    end
end


串并转换:
function y=StoP(input_bit_stream ,M)

% 串并转换
M=log2(M);
n=length(input_bit_stream);
y=zeros(1,n/M);
for k1=1: n/M
    y(k1)=0;
    for k2=1: M
      y(k1)=y(k1)+input_bit_stream((k1-1)*M+k2)*2^(M-k2);
    end
end

调用函数的脚本程序如下:
clear
close all
clc

SNR=0:2:25; % 信噪比
NS = 1600; % NS:待传送OFDM信号总个数
M = 8;% M:调制进制
N = 60; % 子通道个数
BPS = N*log2(M); % 一个OFDM信号携带的比特数

carriers = (1:N );% 子通道序数
ifftsize =128; %FFT长度

%未加频偏,未采用消除方法时
ep = 0 ;%归一化频偏
berMatrix_NOEP_Non = freqOffsetOFDM(BPS,NS,M,SNR,ifftsize,carriers,N,ep);
%加频偏,未采用消除方法时
ep = 0.05;%归一化频偏
berMatrix_EP_Non = freqOffsetOFDM(BPS,NS,M,SNR,ifftsize,carriers,N,ep);
berMatrix_EP_ICI = freqOffsetOFDMICI(BPS,NS,M,SNR,ifftsize,carriers,N,ep);

N_awgn = 1;
berMatrix_EP_SL = freqOffsetOFDMMSL(BPS,NS,M,SNR,ifftsize,carriers,N,ep,N_awgn);

N_awgn = 10;
berMatrix_EP_MSL = freqOffsetOFDMMSL(BPS,NS,M,SNR,ifftsize,carriers,N,ep,N_awgn);

% 固定频偏下,不同算法 误码率-信噪比曲线
figure
plot(SNR,berMatrix_NOEP_Non,'-k' )
hold on
plot(SNR,berMatrix_EP_Non ,'.-r')
plot(SNR,berMatrix_EP_ICI ,'--g')
plot(SNR,berMatrix_EP_SL ,'-m')
plot(SNR,berMatrix_EP_MSL ,'-c')
set(gca,'YScale','log')

legend('未加频偏','无频偏估计','加频偏估计','SL','MSL');
grid on
xlabel( 'SNR(dB)')
ylabel('BER')



nadi 发表于 2018-5-9 04:34:30

HI,
I am looking for a matlab code to split OFDM sub-carriers into odd and even sub-carriers, can anyone help me please?

nadi 发表于 2018-5-11 03:58:50

:(:(:(:(:(
页: [1]
查看完整版本: OFDM系统中固定频偏算法