gusucode.com > 基于梳状导频的OFDM信道估计 > ofdm2.m

    %基于梳妆导频的OFDM信道估计
clear all;
close all
clc;

IFFT_bin_length=128;%ifft长度
carrier_count=100;%子载波数
bits_per_symbol=2;%每符号比特数
symbols_per_carrier=12;%一桢符号数,一桢包括很多的符号。
LI=7 ; %导频之间的间隔
Np=ceil(carrier_count/LI)+1;%16 导频数加1的原因:使最后一列也是导频
N_number=carrier_count*symbols_per_carrier*bits_per_symbol;%2400一祯比特数
carriers=1:carrier_count+Np;%116 子载波加导频
GI=8;             % guard interval length
N_snr=20;          % 每比特信噪比
snr=5;             %信噪比间隔k
%------------------------------------------------------------
% 初始化
X=zeros(1,N_number);%2400个bit
X1=[];X2=[];X3=[];X4=[];X5=[];X6=[];X7=[];
Y1=[];Y2=[];Y3=[];Y4=[];Y5=[];Y6=[];Y7=[];
XX=zeros(1,N_number);%2400
dif_bit=zeros(1,N_number);%2400
dif_bit1=zeros(1,N_number);%2400
dif_bit2=zeros(1,N_number);%2400
dif_bit3=zeros(1,N_number);%2400
X=randint(1,N_number);%产生二进制随即序列(非0即1)2400
%--------------------------------------------------------
%QPSK调制:(1 1)->pi/4;(0 1)->3*pi/4;(0 0)->-3*pi/4;(1,0)->-pi/4;

s=(X.*2-1)/sqrt(2);
sreal=s(1:2:N_number);
simage=s(2:2:N_number);
X1=sreal+j.*simage;%已调信号bit流0.7071 - 0.7071i   0.7071 - 0.7071i   0.7071 + 0.7071i。。。。。(1*1200)

%---------------------------------------------------------
%产生随机导频信号
%--------------------------------------------------------
train_sym=randint(1,2*symbols_per_carrier);%1*24
t=(train_sym.*2-1)/sqrt(2);
treal=t(1:2:2*symbols_per_carrier);
timage=t(2:2:2*symbols_per_carrier);
training_symbols1=treal+j.*timage;% 0.7071 - 0.7071i  -0.7071 - 0.7071i  -0.7071 - 0.7071i   1*12
training_symbols2=training_symbols1.';%12*1
training_symbols=repmat(training_symbols2,1,Np);%12*16 复制第一列变成16列

%disp(training_symbols)
pilot=1:LI+1:carrier_count+Np;%导频插入位置序号1     9    17    25    33    41    49    57    65    73    81    89    97   105  113
if length(pilot)~=Np
    pilot=[pilot,carrier_count+Np];%最后一列变成导频1     9    17    25    33    41    49    57    65    73    81    89    97   105  113   116
end
%--------------------------------------------------------
%串并转换
X2=reshape(X1,carrier_count,symbols_per_carrier).';%12*100,12个复信号符号,100列载波
%---------------------------------------------------------
%插入导频
signal=1:carrier_count+Np;%1*116
signal(pilot)=[];%1*100 有效数据的位置。
X3(:,pilot)=training_symbols;%先放入16列导频
X3(:,signal)=X2;%再放入12*100,100列子载波,共12*116
%X3=cat(1,training_symbols,X2);
IFFT_modulation=zeros(symbols_per_carrier,IFFT_bin_length);%12*128
IFFT_modulation(:,carriers)=X3;%116列后补12列全0子载波,12*128   子载波数+导频数+补零=傅里叶变换的数据。
%IFFT_modulation(:,conjugate_carriers)=conj(X3);
X4=ifft(IFFT_modulation,IFFT_bin_length,2);%每个符号128点ifft  获取发送信号的时域数据。
%X5=X4.';
%加保护间隔(循环前缀)
for k=1:symbols_per_carrier;
   for i=1:IFFT_bin_length;
      X6(k,i+GI)=X4(k,i);
   end
   for i=1:GI;
      X6(k,i)=X4(k,i+IFFT_bin_length-GI);    
   end
end
%---------------------------------------------------------
%并串转换
X7=reshape(X6.',1,symbols_per_carrier*(IFFT_bin_length+GI));%12*136先转置,再变成1*1632复信号流

%---------------------------------------------------------
%信道模型:带多普勒频移的瑞利衰落信道
fd=50; %多普勒频移
r=6;   %多径数
a=[0.123 0.3 0.4 0.5 0.7 0.8]; %多径的幅度
d=[3 4 5 6 10 14]; %各径的延迟
fs=9600;
T=1/fs;  %系统采样周期
th=[90 0 72 144 216 288]*pi./180;%相移
h=zeros(1,carrier_count);%1*100
hh=[];
for k=1:r
    %deta=[zeros(1,d(k)-1),1,zeros(1,carrier_count-d(k))];
    h1=a(k)*exp(j*((2*pi*T*fd*d(k)/carrier_count+th(k))));
    %h1=a(k)*exp(j*((2*pi*T*fd*d(k)/carrier_count)));
    hh=[hh,h1];
end
h(d+1)=hh;%3 4 5 6 10 14处有多径效应
%noise=randn(1,length(X7))+j.*randn(1,length(X7)); 

%===================================================
% Fs=9600;            %采样频率
% Ts=1/Fs;            %采样间隔
% Fd=100;              %Doppler频偏,以Hz为单位
% tau=[0,0.001,0.0018,0.002,0.005,0.01];          %多径延时,以s为单位
% pdf=[0,0,0, 0, 0,0];          %各径功率,以dB位单位
% chan=rayleighchan(Ts,Fd,tau,pdf);
% data=[1,zeros(1,carrier_count-1)];%脉冲信号数据,该矩阵长度要适中,冲激序列
% % data=ones(1,4);
% h=filter(chan,data);  %脉冲响应,与chan进行卷积,相当于采样,得到信道h(t)
% temp=conv(X7,h);
% Tx_data_temp=ifft(temp);
% Tx_data=Tx_data_temp(1:12*136);
%===================================================

channel1=zeros(size(X7));%1*1632
channel1(1+d(1):length(X7))=hh(1).*X7(1:length(X7)-d(1));
channel2=zeros(size(X7));
channel2(1+d(2):length(X7))=hh(2).*X7(1:length(X7)-d(2));
channel3=zeros(size(X7));
channel3(1+d(3):length(X7))=hh(3).*X7(1:length(X7)-d(3));
channel4=zeros(size(X7));
channel4(1+d(4):length(X7))=hh(4).*X7(1:length(X7)-d(4));
channel5=zeros(size(X7));
channel5(1+d(5):length(X7))=hh(5).*X7(1:length(X7)-d(5));
channel6=zeros(size(X7));
channel6(1+d(6):length(X7))=hh(6).*X7(1:length(X7)-d(6));
%---------------------------------------------------------------
Tx_data=X7+channel1+channel2+channel3+channel4+channel5+channel6;%6径干扰后的数据流1*1632
%----------------------------------------------------------------
%加高斯白噪声
Error_ber=[];%误比特率
Error_ber1=[];
Error_ber2=[];%误比特率
Error_ber3=[];
%Error_ser=[];%误符号率
for snr_db=-20:snr:N_snr %0:8:40

    code_power=0;
    code_power=[norm(Tx_data)]^2/(length(Tx_data));%信号的符号功率
    %bit_power=var(Tx_data);
    bit_power=code_power/bits_per_symbol;%比特功率 
    noise_power=10*log10((bit_power/(10^(snr_db/10))));%噪声功率
    noise=wgn(1,length(Tx_data),noise_power,'complex');%产生GAUSS白噪声信号
    Y7=Tx_data+noise;
%-------------------------------------------------------
  %串并变换
   Y6=reshape(Y7,IFFT_bin_length+GI,symbols_per_carrier).';%先变成136*12,再转置成12*136,恢复成行为符号,列为载波  
  %去保护间隔
    for k=1:symbols_per_carrier;
       for i=1:IFFT_bin_length;
           Y5(k,i)=Y6(k,i+GI);
       end
    end
     Y4=fft(Y5,IFFT_bin_length,2);%每行的符号进行128点fft  12*128
     Y3=Y4(:,carriers);%去掉尾部12列原补零点, 12*116,得到有效的接收数据矩阵。
 %-------------------------------------------------------------   
 %LS信道估计
  H=[];
  Y2=Y3(:,signal);
  Rx_training_symbols=Y3(:,pilot);
  Rx_training_symbols0=reshape(Rx_training_symbols,symbols_per_carrier*Np,1);
  
  training_symbol0=reshape(training_symbols,1,symbols_per_carrier*Np);
  training_symbol1=diag(training_symbol0);
  %disp(training_symbols)
  training_symbol2=inv(training_symbol1);
  Hls=training_symbol2*Rx_training_symbols0;
  Hls1=reshape(Hls,symbols_per_carrier,Np);%用LS估计得到的导频部分的信道信息。
  HLs=[];
  HLs1=[];
 if ceil(carrier_count/LI)==carrier_count/LI
     for k=1:Np-1
        HLs2=[];
        for t=1:LI
           HLs1(:,1)=(Hls1(:,k+1)-Hls1(:,k))*(t-1)./LI+Hls1(:,k);
           HLs2=[HLs2,HLs1];
        end
       HLs=[HLs,HLs2];
    end
else
    for k=1:Np-2
        HLs2=[];
        for t=1:LI
           %%把第k+1与k个信道数据均匀分开,然后在第k的基础上相加,得到内插指
           HLs1(:,1)=(Hls1(:,k+1)-Hls1(:,k))*(t-1)./LI+Hls1(:,k); 
           HLs2=[HLs2,HLs1];
        end
       HLs=[HLs,HLs2];
    end
    HLs3=[];
    for t=1:mod(carrier_count,LI)
        HLs1(:,1)=(Hls1(:,Np)-Hls1(:,Np-1))*(t-1)./LI+Hls1(:,Np-1);
        HLs3=[HLs3,HLs1];
    end
    HLs=[HLs,HLs3];
 end

 for j=1:12
     Hls_time(j,:)=ifft(HLs(j,:),128);
 end
  %Hls1=Hls.';
  %H=repmat(Hls1,symbols_per_carrier,1);%将导频扩展成symbols_per_carrier*carrier_count矩阵
  Y1=Y2./HLs; 
%-------------------------------------------------------------------
  %并串变换
  YY=reshape(Y2.',1,N_number/bits_per_symbol);
  YY1=reshape(Y1.',1,N_number/bits_per_symbol);
%------------------------------------------------------------
%QPSK解调
   y_real=sign(real(YY));
   y_image=sign(imag(YY));
   y_re=y_real./sqrt(2);
   y_im=y_image./sqrt(2); 
   y_real1=sign(real(YY1));
   y_image1=sign(imag(YY1));
   y_re1=y_real1./sqrt(2);
   y_im1=y_image1./sqrt(2); 
 
   r00=[];
   r01=[];
   r10=[];
   r11=[];
 
  for k=1:length(y_real);
     r00=[r00,[y_real(k),y_image(k)]];
  end;
  for k=1:length(y_real1);
     r10=[r10,[y_real1(k),y_image1(k)]];
  end;
 
 for k=1:length(y_re);
     r01=[r01,[y_re(k),y_im(k)]];
 end;
 for k=1:length(y_re1);
     r11=[r11,[y_re1(k),y_im1(k)]];
 end;

    XX(find(r01>0))=1;
%-------------------------------------------------------------
%计算在不同信噪比下的误比特率并作图

 dif_bit=s-r01; 
 dif_bit1=s-r11; 

 ber_snr=0;    %纪录误比特数
    for k=1:N_number;
       if dif_bit(k)~=0;
         ber_snr=ber_snr+1;
       end
   end;
 ber_snr1=0;    %纪录误比特数
    for k=1:N_number;
       if dif_bit1(k)~=0;
          ber_snr1=ber_snr1+1;
      end
    end
 
 Error_ber=[Error_ber,ber_snr];
 Error_ber1=[Error_ber1,ber_snr1];
end

BER=zeros(1,length(0:snr:N_snr));
BER1=zeros(1,length(0:snr:N_snr));

BER=Error_ber./N_number;
BER1=Error_ber1./N_number;
%-------------------------------------------------------------
% figure
% for j=1:size(Hls1,1)
%     HLs_time(j,:)=ifft(Hls1(j,:),16);
% end
% HLs_time=HLs_time(:,1:100);
% stem(abs(HLs_time(2,:)))
%-------------------------------------------------------------
 i=-20:snr:N_snr;
figure
semilogy(i,BER,'-*r');

hold on;
semilogy(i,BER1,'-og');
hold on;

grid on;

legend('No Channel Estimation','LS Channel Estimation');
hold off