%本程序采用迭代的联合信道估计与符号检测算法,仿真了不同信噪比条件下,%
%信道估计的性能,包括有迭代和无迭代条件下的误码率和均方误差%
%------------------------------------------------------------------------%
echo off;clear all;
close all;
clc;
fprintf( 'OFDM仿真\n') ;
tic
% ---------------------------------------------%
% 参数定义 %
% --------------------------------------------- %
% Initialize the parameters
Num_Symbol=1000; %仿真OFDM符号数
Bits_per_Symbol=60; %每符号比特数
NumSubc=128; % 载波数
Numcp=NumSubc/4; %cp数约为载波数的1/4
mentor_times=20; %蒙氏仿真 最大次数
% h_time=create_channel(6);%产生一个6径信道
% figure;
% stem(abs(h_time));
% CL=length(h_time); %信道长度
pilots=1:NumSubc/16:NumSubc; %导频插入位置 共16个导频 等间隔插入
PL=length(pilots); %PL=16; 共16个导频
%------------------------------------------------%
Bits_Tx = floor(rand(Num_Symbol,Bits_per_Symbol)*2);
% Generate the random binary stream for transmit test
%-------------------------------------------------%
% 卷积编码
for i=1:Num_Symbol
a=Bits_Tx(i,:);
Bits_convenc(i,:)=cnv(a);
end
%------------------------------------------------%
% 随机交织 用系统函数生成
state=32; %定义交织器初始参数
for i=1:Num_Symbol
b=Bits_convenc(i,:);
Bits_Interleaved(i,:)=randintrlv(b,state); %随机交织
end
%---------------------------------------------------%
% 4QAM 星座图映射
for i=1:Num_Symbol
c=Bits_Interleaved(i,:);
QAM_modulated(i,:)=QAM_modu(c); %调用映射函数
end
%---------------------------------------------------%
% 在第一行插入导频 作信道估计用
QAM_modulated(1,pilots)=1;% 导频位置处插入导频1+j
QAM_modulated(1,pilots+1)=0;% 与导频相邻位置处插0
%----------------------------------------------------%
% 串/并转换
Symbol_paralleled=QAM_modulated.';
%--------------------------------------------------------%
% IFFT变换
Symbol_ifft_temp=ifft( Symbol_paralleled,NumSubc); %已变换
%---------------------------------------------------%
% 并/串转换
Symbol_ifft= Symbol_ifft_temp.'; %串联
%----------------------------------------------------%
% 加cp前缀
[m,n]=size(Symbol_ifft);
Symbol_cp=zeros(m,n+Numcp);
Symbol_cp(:,(Numcp+1):(n+Numcp))=Symbol_ifft(:,1:n);%先把Symbol_ifft整体复制到Symbol_cp_temp的后半部分去
Symbol_cp(:,1:Numcp)=Symbol_ifft(:,(n-Numcp+1):n); %加cp
% %-------------------------------------------------------%
%过信道
after_channel=zeros(m,n+Numcp);
snrtable=zeros(11,3); %存储信噪比和误码率
MSE_table=zeros(11,2); %存储估计的均方误差
for snr=0:3:30
ber_ratio1=0; %初始化误码率
ber_ratio2=0; %初始化误码率
estimation_error=zeros(2,NumSubc); %用以存储中间过程的估计误差
snrtable(snr/3+1,1)=snr;%第一列存储信噪比
for mentor=1:mentor_times
h_time=create_channel(6);%产生一个6径信道
CL=length(h_time); %信道长度
for i=1:m
d=Symbol_cp(i,:);
after_channel_temp=filter(h_time,1,d); % 过信道 用滤波器实现卷积
after_channel(i,:)=awgn(after_channel_temp,snr,'measured'); %加噪声
end
%-----------------------------------------------------%
% 去cp前缀
Symbol_de_cp_temp=after_channel.'; %转置 出来是并联的
Symbol_de_cp=zeros(n,m);
Symbol_de_cp(1:n,:)=Symbol_de_cp_temp((Numcp+1):(n+Numcp),:); %去掉最上面的Numcp行
%-----------------------------------------------------%
% 送入fft解调器
Symbol_fft=fft(Symbol_de_cp,NumSubc);
Symbol_fft_temp=Symbol_fft.'; %转置 变成串联
%-----------------------------------------------------%
%------------------------------------------------------%
% 信道估计部分
H_act=fft([h_time zeros(1,NumSubc-CL)],NumSubc);
H_est_temp=Symbol_fft_temp(1,pilots)./QAM_modulated(1,pilots); %导频位置处的信道初始估计
h1=ifft(H_est_temp,PL); %导频点数的ifft
h2=h1(1:CL); %取前CL点
h3=[h2 zeros(1,NumSubc-CL)]; %补零 达到NumSubc位
H_est1=fft(h3,NumSubc); %NumSubc点fft的变换 到频域
%------------------------------------------------------%
%---------------------------------------------------------%
for i=1:Num_Symbol-1
X(i,:)= Symbol_fft_temp(i+1,:)./H_est1; %接收信号除以估计的信道频率响应
end
for i=1:Num_Symbol-1
b=X(i,:);
transmit_bits_demapped(i,:)=QAM_demodu(b); %解映射
end
for i=1:Num_Symbol-1
c=transmit_bits_demapped(i,:);
transmit_bits_deinterleaved(i,:)=randdeintrlv(c,state); %解交织
end
for i=1:Num_Symbol-1
e=transmit_bits_deinterleaved(i,:);
[transmit_bits_decoded,survivor_state,cumulated_metric]=viterbi(e); %译码
decode(i,:)=transmit_bits_decoded;
end
%--------------------------------------------
Bits_Tx_temp=Bits_Tx(2:Num_Symbol,:);
[number,ratio] = biterr(Bits_Tx_temp,decode); %计算误码率
ber_ratio1=ber_ratio1+ratio; %累计误码率
%--------------------------------------------------------%
%---------------------------------------------------------%
error1=(abs(H_act(1,:)-H_est1(1,:)).^2); %初始估计误差
estimation_error(1,:)=estimation_error(1,:)+error1; %累计误差
RX=Symbol_fft_temp(2,:); %用接收的第二行数据做测试数据用
X_est1=RX./H_est1; %接收到的数据信号除以信道频率响应为发送信号的估计值
x_demap1=QAM_demodu(X_est1); %解调
x_deinterleaved=randdeintrlv(x_demap1,state); %解交织
[x_decoded,survivor_state,cumulated_metric]=viterbi(x_deinterleaved); %译码
x_coded=cnv(x_decoded); %编码
x_interleaved=randintrlv(x_coded,state);%交织
x_mapped=QAM_modu(x_interleaved); %映射
H_est2_temp1=RX./x_mapped;
H_est2_temp2=ifft(H_est2_temp1,NumSubc);
H_est2=fft([H_est2_temp2(1,1:CL) zeros(1,NumSubc-CL)],NumSubc);
X_est2=RX./H_est2;
x_demap2=QAM_demodu(X_est2);
%-----------------------------------------
%迭代信道估计部分
while(x_demap2~=x_demap1) %判断两次估计值的是否相同,相同则表示已收敛,无需继续迭代,否则继续迭代
x_deinterleaved=randdeintrlv(x_demap2,state); %解交织
[x_decoded,survivor_state,cumulated_metric]=viterbi(x_deinterleaved); %译码
x_coded=cnv(x_decoded); %编码
x_interleaved=randintrlv(x_coded,state);%交织
x_mapped=QAM_modu(x_interleaved); %映射
%以下三行是估计
H_est2_temp1=RX./x_mapped;
H_est2_temp2=ifft(H_est2_temp1,NumSubc); %变换到时域
H_est2=fft([H_est2_temp2(1,1:CL) zeros(1,NumSubc-CL)],NumSubc);%补零后再变换到频域
X_est1=RX./H_est2; %接收信号除以信道响应得到发送信号的估计值
x_demap1=QAM_demodu(X_est1); %解映射
%以下三行在交换,用以满足继续迭代的条件
temp=x_demap1;
x_demap1=x_demap2;
x_demap2=temp;
end
H_est=H_est2; %得到估计值
%-------------------------------------------------------------%
%---------------------------------------------------------------%
%迭代后的接收判决部分
for i=1:Num_Symbol-1
X(i,:)= Symbol_fft_temp(i+1,:)./H_est; %接收信号除以估计的信道频率响应
end
for i=1:Num_Symbol-1
b=X(i,:);
transmit_bits_demapped(i,:)=QAM_demodu(b); %解映射
end
for i=1:Num_Symbol-1
c=transmit_bits_demapped(i,:);
transmit_bits_deinterleaved(i,:)=randdeintrlv(c,state); %解交织
end
for i=1:Num_Symbol-1
e=transmit_bits_deinterleaved(i,:);
[transmit_bits_decoded,survivor_state,cumulated_metric]=viterbi(e); %译码
decode(i,:)=transmit_bits_decoded;
end
%--------------------------------------------
Bits_Tx_temp=Bits_Tx(2:Num_Symbol,:);
[number,ratio] = biterr(Bits_Tx_temp,decode); %计算误码率
ber_ratio2=ber_ratio2+ratio; %累计误码率
error2=(abs(H_act(1,:)-H_est(1,:)).^2); %估计误差
estimation_error(2,:)=estimation_error(2,:)+error2; %累计误差
%------------------------------ -----------------------
%------------------------------------------------------%
end
snrtable(snr/3+1,2)=ber_ratio1/mentor_times;
snrtable(snr/3+1,3)=ber_ratio2/mentor_times;
estimation_error=estimation_error./ment