📄 main.m
字号:
FrameTiming = 1;
Window1 = 128; % 帧定时算法的窗口宽度
Threshold1 = 0.4; % 帧定时算法门限
Delay1 = 128; % 帧定时延时相关算法的延时样点数
% 载波频偏粗估计
WinStart = 128*4;
WinSize = 128;
Delay2 = 128*4;
% 符号定时算法
Window2 = 256; % 和已知序列求相关,序列的长度
TimingAhead = 0; % 定时提前的样点数
% 载波频偏粗估计
WinStart2 = 256;
WinSize2 = 512;
Delay3 = 512;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 二. 仿真主体程序部分
% Eb/No信噪比循环
snr_idx = 1;
for Eb_No_dB = Eb_NoStart:Eb_NoInterval:Eb_NoEnd
Eb_No_dB
Eb_No = 10^(Eb_No_dB/10);
var_noise = Eb/(2*Eb_No); % 噪声样点的功率
%var_noise = 0.01; % 测试
tic; % 计算时间开始
% OFDM帧/数据包循环
for frame = 1:N_frame
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 1. 信道参数产生部分
% 产生不同用户(cell区分), 不同收发天线对(矩阵的第三维区分),不同OFDM符号
% 时间(矩阵列区分), 多径信道不同时延径(矩阵行区分)的时域信道响应
h_time = cell(1,N_user);
H_freq = cell(1,N_user);
for u = 1:N_user
% 得到时域信道的参数
h_time{u} = time_channel_para( ch{u}, N_Tx_ant, N_Rx_ant,N_sym, T_sym, fs, N_subc, ...
PrefixRatio,N_frame,frame,N_tran_sym);
% 由信道时域响应,得到信道的频域响应
H_freq{u} = to_freq_channel( h_time{u}, ch{u} ,N_subc ,N_sym, N_Tx_ant,...
N_Rx_ant,N_tran_sym);
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 2. 发射机部分
% 多用户数据生成模块
[user_bit,user_bit_cnt] = user_bit_gen( N_user, N_data ,N_sym , Modulation );
% 信道编码模块, 包括RS编码, 卷积编码等
coded_user_bit = channel_coding( user_bit , UserRS_Coding , ...
UserTrellis,TraceBackLen, TurnOn.ChannelCoding );
% 自适应调制和多用户复用模块
% 有自适应调制 , 使用固定或动态子载波分配
if TurnOn.AdptMod
[user_subc_alloc , mod_subc ,pwr_subc, pad_bit_cnt] = adpt_mod_para...
( coded_user_bit,N_sym,Idx_data,AllocMethod,AdptMethod ,...
H_freq,var_noise,TargetBer );
% 无自适应调制 , 使用固定子载波分配
else
[user_subc_alloc , mod_subc ,pwr_subc, pad_bit_cnt] = adpt_mod_para...
( coded_user_bit,N_sym,Idx_data ,AllocMethod );
end
% 按照给定的每用户,每子载波的调制方式,进行自适应调制
mod_sym = modulator(coded_user_bit,user_subc_alloc,mod_subc,...
pwr_subc, pad_bit_cnt ,N_subc, N_sym,TurnOn.AdptMod );
% 发送分集, 使用空时编码
st_coded = st_coding( mod_sym,N_Tx_ant,ST_Code);
% 加导频
pilot_added = pilot_insert(st_coded,Idx_pilot,PilotValue);
% OFDM调制,加前导序列. 如果使用发送分集,则输出多条天线的信号
[transmit_signal known_training] = ofdm_mod(st_coded,PrefixRatio,N_subc,N_sym,N_used,...
Idx_used,N_Tx_ant,N_tran_sym);
% 加发送机相位噪声, 下一步完成
% transmit_signal = phase_noise(transmit_signal,TurnOn.PhaseNoise);
% clear mod_sym, coded_user_bit;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 3. 多天线多径信道部分
for u = 1:N_user % 多个用户接收机的循环
% 信道和接收机区分开不同用户的原因:
% 1) 每个用户(移动台)的信道功率时延谱和衰落系数是不同的, 需要区别
% 2) 自适应调制和子载波分配算法中, 需要知道每个用户的信道响应
recv_signal = channel( transmit_signal,h_time{u}, ch{u}, N_Tx_ant, N_Rx_ant,...
PreNoiseLen,PostNoiseLen , var_noise,N_subc,PrefixRatio,N_sym,...
delta_fc,T_sample,N_tran_sym,TurnOn.FreqSyn );
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 4. 接收机部分
% 加接收机相位噪声, 下一步完成
% recv_signal = phase_noise(recv_signal ,TurnOn.PhaseNoise);
% 接收机帧定时(包检测,粗定时)
[recv_frame, err_frame_timing] = frame_timing( recv_signal ,Window1, Threshold1,...
Delay1,PreNoiseLen, PostNoiseLen, N_subc, PrefixRatio, N_sym, FrameTiming, N_tran_sym, N_Rx_ant ,...
TurnOn.Timing);
% 粗频偏估计 (整数倍的频偏估计). 也可以在频域做,使用freq_syn_freqdomain模块
[coarse_freq_out, offset1] = freq_syn_timedomain( recv_frame, WinStart, WinSize, Delay2, T_sample,...
N_Rx_ant,TurnOn.FreqSyn );
% 符号定时(精定时)
[timed_sym , err_sym_timing] = sym_timing( coarse_freq_out ,N_subc, PrefixRatio, N_sym, N_tran_sym,...
known_training,Window2,TimingAhead, N_Rx_ant, TurnOn.Timing);
% 精频偏估计(分数倍的频偏估计),如果粗频偏估计已经满足估计器的MSE要求, 则可以不使用此模块
% 调用和粗频偏估计相同的函数,只是输入参数不同
[fine_freq_out,offset2] = freq_syn_timedomain( timed_sym,WinStart2, WinSize2, Delay3, T_sample,...
N_Rx_ant,TurnOn.FreqSyn );
% 可选的时域均衡器,下一步完成.如果使用了频域均衡, 则不需要
% equalized_sym = equalizer_timedomain(timed_sym ,TurnOn.TimeDomainEq);
% OFDM解调,去前导序列
[training_sym ,data_sym] = ofdm_demod(fine_freq_out,PrefixRatio,N_subc,N_sym,N_tran_sym,N_Rx_ant);
% 如果在时域不进行整数倍的频偏估计, 则在频域进行.下一步完成.
% freq_offset_corrected = freq_syn_freqdomain( data_sym,TurnOn.FreqSyn );
% 频域信道估计器, 如果使用了时域均衡, 则不使用此模块
% channel_est = zeros(N_subc,1);
% [channel_est(Idx_used,1) , mse_ce] = estimator( training_sym(Idx_used,1) , known_training(Idx_used,2) , ...
% CE_Method , CE_SubcRemain , H_freq{u}(Idx_used,2));
[channel_est , mse_ce] = channel_estimator( training_sym ,CE_Method,CE_Method2,...
CE_SubcRemain,H_freq{u},known_training,N_Tx_ant,N_Rx_ant, N_subc,N_used,Idx_used,...
Modulation,var_noise,TurnOn.ChannelEst );
% 使用数据OFDM符号中的导频进行载波相位跟踪和补偿,下一步完成
% phase_err_corrected = phase_tracing( data_sym,freq_offset_corrected ,TurnOn.PhaseTrace );
% 使用数据OFDM符号中的导频抽样频偏的估计和补偿, 下一步完成
% sampling_err_corrected = sampling_syn( data_sym,phase_err_corrected ,TurnOn.SamplingSyn );
% 在频域加入理想信道响应,测试目的
% rev = zeros(N_subc, N_sym , N_Rx_ant );
% for n_r = 1:N_Rx_ant
% for n_t = 1:N_Tx_ant
% rev(:,:,n_r) = rev(:,:,n_r) + data_sym(:,:,n_t).*...
% repmat(H_freq{u}(:,1,(n_t-1)*N_Rx_ant + n_r), 1, N_sym );
% end
% end
% data_sym = rev;
% 接收机分集处理和空时解码
st_decoded = st_decoding( data_sym,channel_est,N_Tx_ant, N_Rx_ant ,ST_Code ,Idx_data);
% 根据每用户,每子载波的调制方式,进行解调
demod_user_bit = demodulator( st_decoded, user_subc_alloc{u} ,mod_subc{u} ,...
pad_bit_cnt(u),N_sym,TurnOn.AdptMod);
% 信道解码, 包括RS解码, 卷积码Viterbi编码等
decoded_user_bit{u} = channel_decoding ( demod_user_bit , UserRS_Coding(:,u) ,...
UserTrellis(u) ,TraceBackLen, user_bit_cnt(u) , TurnOn.ChannelCoding );
% 本帧,本信噪比下,本用户的性能统计
bit_err = sum(abs(decoded_user_bit{u} - user_bit{u}));
if TurnOn.FreqSyn
freq_err = delta_fc - (offset1 + offset2);
else
freq_err = 0;
end
user_bit_err{u}(frame,snr_idx) = bit_err ;
mse_ce_acc{u}(frame,snr_idx) = mse_ce;
frame_timing_acc{u}(frame,snr_idx) = err_frame_timing ;
freq_syn_acc{u}(frame,snr_idx) = freq_err ;
end % 多个用户接收机的循环结束
% 实时显示仿真性能
fprintf('Eb/No:%d dB\tFrame No.:%d Err Bits:%d\tCh.Est. MSE:%f Timing Err(Sample):%d\tFreq.Syn. Err(Hz):%d\n',...
Eb_No_dB, frame, bit_err, mse_ce, err_frame_timing , freq_err);
end % OFDM帧/数据包循环结束
timer(snr_idx) = toc % 计算时间结束
snr_idx = snr_idx + 1;
save saved_data.mat; % 保存数据
end % Eb/No信噪比循环结束
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 5. 性能评估部分,可以保存需要的数据,并对目标性能数据进行操作
% 如画图, 比较,进一步计算得到结论等
performance_eval;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 仿真程序结尾
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -