%% clear the workspace
clear all;
close all;
%% Set paraments
pilot_inter=6; %导频符号间隔为5
pilot_bit=[0 0 0 1];
cp_length=144;
SNR_dB=0:20;
OFDM_symbol_num=100;
Subcarriers=2048-cp_length; %子载波个数,即FFT_Len
modOrd=4; %采用16QAM调制
ls_err_ber=zeros(1,length(SNR_dB));
lmmse_err_ber=zeros(1,length(SNR_dB));
svd_mmse_err_ber=zeros(1,length(SNR_dB));
for index=1:length(SNR_dB)
loop_num=10;
ls_bit_num=0;
lmmse_bit_num=0;
svd_mmse_bit_num=0;
total_bit_num=0;
for l=1:loop_num
%%
% *****************TRANSMITTER**********************************
msg=randint(modOrd*Subcarriers,OFDM_symbol_num,2);
[nbit,mbit]=size(msg);
total_bit_num=total_bit_num+nbit*mbit;
% ===================modulation====================================
h=modem.qammod('M', 2^modOrd, 'PhaseOffset', 0, 'SymbolOrder', 'binary',...
'InputType','bit');
hdemod=modem.qamdemod(h);
y_out=modulate(h,msg);
% ===================insert pilot================================
[insert_pilot_out,pilot_num,pilot_sequence]=insert_pilot(pilot_inter,pilot_bit,y_out);
%====================作FFTLen点逆FFT运算,完成ofdm调制=============
ofdm_modulation_out=ifft(insert_pilot_out,Subcarriers);
%====================insert CP====================================
ofdm_cp_out=insert_cp(ofdm_modulation_out,cp_length);
%%
%====================以下过程为ofdm符号通过频率选择性多径信道========
num_path=3;
%假设功率延迟谱服从负指数分布~exp(-t/trms),trms=(1/4)*cp时长;
%t在0~cp时长上均匀分布
%若cp时长为16e-6s,可以取5径延迟如下
delay=[0 50e-9 120e-9];% 8e-6 12e-6];
t_interval=32.55e-9; %采样间隔为1us
t_cp=cp_length*t_interval;
trms=t_cp/4;
t_max=t_cp/t_interval;
trms_a=trms/t_interval; %信道各径的平均延时,一般取为1/4CP长
var_pow=[-1 -1 -1];
fd=0;%最大doppler频率为0Hz
%信道采样点数,每个调制符号采一个点
passchan_ofdm_symbol=multipath_chann(ofdm_cp_out,num_path,var_pow,delay,t_interval);
%====================加高斯白噪声===================================
snr=10^(SNR_dB(index)/10);
[nn,mm]=size(passchan_ofdm_symbol);
signal_power=0;
for i=1:nn
for j=1:mm
signal_power=signal_power+real(passchan_ofdm_symbol(i,j))^2+imag(passchan_ofdm_symbol(i,j))^2;
end
end
signal_power_per=signal_power/(nn*mm);
sgma=sqrt(signal_power_per/(2*snr));
receive_ofdm_symbol=add_noise(sgma,passchan_ofdm_symbol);
%%
%===================去循环前缀======================================
cutcp_ofdm_symbol=cut_cp(receive_ofdm_symbol,cp_length);
%===================作FFT运算,ofdm信号解调=========================
ofdm_de_symbol_output=fft(cutcp_ofdm_symbol,Subcarriers);
%===================对信号进行信道估计==============================
ls_output=ls_estimation1(ofdm_de_symbol_output,pilot_inter,pilot_sequence,pilot_num);
lmmse_output=lmmse_estimation1(ofdm_de_symbol_output,pilot_inter,pilot_sequence,pilot_num,trms_a,t_max,snr);
svd_mmse_output=svd_mmse_estimation1(ofdm_de_symbol_output,pilot_inter,pilot_sequence,pilot_num,trms_a,t_max,snr,cp_length);
%===================demodulation===================================
ls_output_receive=demodulate(hdemod,ls_output);
lmmse_output_receive=demodulate(hdemod,lmmse_output);
svd_mmse_output_receive=demodulate(hdemod,svd_mmse_output);
%===================count the wrong number=========================
ls_err_num=error_count(msg,ls_output_receive);
lmmse_err_num=error_count(msg,lmmse_output_receive);
svd_mmse_err_num=error_count(msg,svd_mmse_output_receive);
ls_bit_num=ls_bit_num+ls_err_num;
lmmse_bit_num=lmmse_bit_num+lmmse_err_num;
svd_mmse_bit_num=svd_mmse_bit_num+svd_mmse_err_num;
end
% 计算各SNR下错误比特的数目
ls_err_ber(index)=ls_bit_num/total_bit_num;
lmmse_err_ber(index)=lmmse_bit_num/total_bit_num;
svd_mmse_err_ber(index)=svd_mmse_bit_num/total_bit_num;
end
%%
% 画图
semilogy(SNR_dB,ls_err_ber,'b-*')
hold on
semilogy(SNR_dB,lmmse_err_ber,'r-o')
hold on
semilogy(SNR_dB,svd_mmse_err_ber,'g-s')
grid on