⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.m

📁 程序里面包含各部分算法仿真 可供参考和使用
💻 M
📖 第 1 页 / 共 2 页
字号:
Turbo_frame = L_total - (size(Generator,2) - 1);
N_Turbo_frame = (Modulation * RateSTCoding * N_ts * N_data_sym_ts)/N1;

[temp, Alpha2] = sort(rand(1, L_total / RateChCoding * N_Turbo_frame));

% 如果使用卷积+RS+交织: 
% 假设每个用户的RS码参数相同,均为(204,188,8)                                   
UserRS_Coding = repmat([255,239,8]',1,N_user);                              
TraceBackLen = 3;       % 卷积码译码参数
% 假设每个用户的卷积码trellis 结构体相同
UserTrellis = repmat( poly2trellis(3,[6 7]),1,N_user );


% 4) 自适应调制: ,当TurnOn.AdptMod == 1时, 
% 1--自适应调制方法1, 给功率增加最小的子载波分配比特和功率, 子载波分配由AllocMethod确定
% 2--自适应调制方法2, 按照信道响应降序排列,子载波间争夺比特和功率, 子载波分配由AllocMethod确定
% 当TurnOn.AdptMod == 0 时,此不起作用, 无自适应调制
AdptMethod = 1;
% 子载波分配方法, 1--相邻分配, 2--交织分配, 3---跳频分配 ,4--自适应子载波分配
AllocMethod = 1;
% 自适应调制算法中需要的目标误比特率
TargetBer = 1e-3;


% 5)定时同步:
PreNoiseLen = 500;      % 为定时算法加的前噪样点数
PostNoiseLen = 500;     % 后噪样点数
delta_fc = 10e3;        % 载波频偏 (Hz)
% 帧(粗)定时
% 帧定时算法, 1--单窗口能量检测方法, 2--双窗口能量检测方法 , 3--延时相关方法帧定时
FrameTiming = 1;         
Window1 = 128;          % 帧定时算法的窗口宽度
Threshold1 = 0.4;       % 帧定时算法门限
Delay1 = 128;           % 帧定时延时相关算法的延时样点数
% 载波频偏粗估计
WinStart = 128*2;       
WinSize = 128;
Delay2 = 128*9;
% 符号定时算法
Window2 = 256;         % 和已知序列求相关,序列的长度
TimingAhead = 0;        % 定时提前的样点数
% 载波频偏细估计
WinStart2 = 256; 
WinSize2 = 1024;
Delay3 = 1280;

% 6) 测试选项
% 0 -- 无测试, 加AWGN和瑞利多径信道效应; 1 -- 测试,不加AWGN,仅考虑瑞利多径信道效应;
% 2 -- 测试,不加瑞利多径信道效应, 仅考虑AWGN;
ChannelEffectTest = 0;

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*RateChCoding);              % 噪声样点的功率
    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} = channel_gen( ch{u}.Power,ch{u}.fd, T_sym*fs, T_sample, N_sym, ...
                N_frame, frame, N_Tx_ant, N_Rx_ant );

            % 由信道时域响应,得到信道的频域响应
            H_freq{u} = to_freq_channel( h_time{u}, ch{u} ,N_subc ,N_sym, N_Tx_ant,...
                N_Rx_ant,ChannelEffectTest);
        end
        
        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        % 2. 发射机部分
        
        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        
        
        % 多用户数据生成模块
        [user_bit,user_bit_cnt] = user_bit_gen( N_user, N_data ,N_ts, N_data_sym_ts, RateSTCoding,...
            Modulation,RateChCoding,Turbo_frame , N_Turbo_frame , TurnOn.ChannelCoding );
        
        % 信道编码模块, 包括RS编码, 卷积编码等
        coded_user_bit = channel_coding( user_bit,ChCodingMethod,Dec_alg,L_total,Generator,Puncture,...
            N_iter,RateChCoding,Alpha,Turbo_frame,N_Turbo_frame, UserRS_Coding ,UserTrellis,...
            TraceBackLen,TurnOn.ChannelCoding );
        
        coded_user_bit{1} = coded_user_bit{1}(Alpha2);
        
        % 自适应调制和多用户复用模块
        % 单用户情况,有自适应调制
        if TurnOn.AdptMod           
            [user_subc_alloc , mod_subc ,pwr_subc, pad_bit_cnt] = adpt_mod_para... 
                ( coded_user_bit,N_data_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_data_sym*RateSTCoding ,Idx_data ,AllocMethod ); 
        end
        
        % 按照给定的每用户,每子载波的调制方式,进行自适应调制
        mod_sym =  modulator(coded_user_bit,user_subc_alloc,mod_subc,...
            pwr_subc, pad_bit_cnt ,N_subc,N_data_sym*RateSTCoding ,TurnOn.AdptMod );
        
        % 发送分集, 使用空时编码
       st_coded = st_coding( mod_sym, N_Tx_ant, N_data_sym, ST_Code);
        
        % 在数据符号帧之间插入导频OFDM符号, 并在数据OFDM符号中加间隔的导频
        [pilot_added ,known_pilot] = pilot_insert(st_coded,N_pilot_sym_ts,N_data_sym_ts,N_ts,Pos_pilot_sym,...
            Pos_data_sym,Idx_pilot,PilotValue,N_subc,Idx_used,N_Tx_ant,L_delay,MIMO_CE_Method,SwitchOrthogonalPilot);
           
        % OFDM调制. 如果使用发送分集,则输出多条天线的信号
        transmit_signal = ofdm_mod(pilot_added,PrefixRatio,N_subc,N_used,N_sym_ts,N_ts,...
            Idx_used,N_Tx_ant,TurnOn.AddChFreq);
        
        % 成帧,加前导序列
        [transmit_signal, syn_preamble] = framing(transmit_signal,N_syn_preamble,PrefixRatio,N_subc,N_used,...
            Idx_used,N_Tx_ant,TurnOn.AddChFreq);
        
        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        % 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,TurnOn.FreqSyn ,TurnOn.AddChFreq );
            
            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
            % 4. 接收机部分
            
            % 接收机帧定时(包检测,粗定时)
            [recv_frame, err_frame_timing] = frame_timing( recv_signal ,Window1, Threshold1,...
                Delay1,PreNoiseLen, PostNoiseLen, N_subc, PrefixRatio, FrameTiming, N_Rx_ant ,...
                TurnOn.Timing ,TurnOn.AddChFreq);
            
            % 粗频偏估计 (整数倍的频偏估计). 也可以在频域做,使用freq_syn_freqdomain模块
            [coarse_freq_out, offset1] = freq_syn_timedomain( recv_frame, WinStart, WinSize, Delay2, T_sample,...
                N_Rx_ant,TurnOn.FreqSyn ,TurnOn.AddChFreq);
            
            % 符号定时(精定时)
            [timed_sym , err_sym_timing] = sym_timing( coarse_freq_out ,N_subc, PrefixRatio, N_sym ,...
                N_syn_preamble,syn_preamble,Window2,TimingAhead, N_Rx_ant, TurnOn.Timing ,TurnOn.AddChFreq);
            
            % 精频偏估计(分数倍的频偏估计),如果粗频偏估计已经满足估计器的MSE要求, 则可以不使用此模块
            % 调用和粗频偏估计相同的函数,只是输入参数不同
            [fine_freq_out,offset2] = freq_syn_timedomain( timed_sym,WinStart2, WinSize2, Delay3, T_sample,...
                N_Rx_ant,TurnOn.FreqSyn ,TurnOn.AddChFreq);
            
            % OFDM解调
            ofdm_sym = ofdm_demod( fine_freq_out, PrefixRatio, N_subc, N_sym_ts, N_ts , N_Rx_ant ,TurnOn.AddChFreq );
            
            % 在频域加入信道响应
            
            ofdm_sym = add_freqdomain_reponse(pilot_added,H_freq{u},N_subc,N_syn_preamble,N_sym,N_Rx_ant,...
                N_Tx_ant,var_noise,ofdm_sym,ChannelEffectTest,TurnOn.AddChFreq);
            
            % 分离提取数据OFDM符号和导频OFDM符号
            [ data_sym,pilot_sym] = pilot_extract(ofdm_sym,N_subc,N_pilot_sym_ts,N_data_sym_ts,N_ts,Pos_pilot_sym,...
                Pos_data_sym,N_Rx_ant);
            
            % 频域信道估计器, 如果使用了时域均衡, 则不使用此模块            
            [channel_est , mse_ce] = channel_estimator( pilot_sym,known_pilot,SISO_CE_Method,MIMO_CE_Method,...
                L_delay,InterpMethod,H_freq{u},N_Tx_ant,N_Rx_ant,N_subc,N_used,Idx_used,Modulation,var_noise,...
                ch{u},N_ts,N_sym_ts,N_pilot_sym_ts,N_data_sym_ts,Pos_pilot_sym,Pos_data_sym,N_syn_preamble,...
                frame,Idx_cir,TurnOn.ChannelEst ,ChannelEffectTest ,SwitchOrthogonalPilot );
            
            % 接收机分集处理和空时解码    
            st_decoded = st_decoding( data_sym,channel_est,N_subc,N_data_sym, N_Tx_ant, N_Rx_ant ,ST_Code ,...
                Idx_data,RateSTCoding,Modulation,HardOrSoft,LST_method,var_noise,ChannelEffectTest);
            
            % 根据每用户,每子载波的调制方式,进行解调
            demod_user_bit = demodulator( st_decoded, user_subc_alloc{u} ,mod_subc{u} ,pad_bit_cnt(u),TurnOn.AdptMod);            
            
            % 信道解码, 包括RS解码, 卷积码Viterbi编码等
            
            demod_user_bit(Alpha2) = demod_user_bit;
            
            decoded_user_bit{u} = channel_decoding( demod_user_bit,ChCodingMethod,Dec_alg,L_total,Generator,Puncture,...
                N_iter,RateChCoding,Alpha,Turbo_frame,N_Turbo_frame, UserRS_Coding(:,u) ,UserTrellis(u) ,...
                TraceBackLen, user_bit_cnt(u) , TurnOn.ChannelCoding );
            
            % 本帧,本信噪比下,本用户的性能统计
            bit_err = sum(abs(decoded_user_bit{u} - user_bit{u}));
            ber = bit_err / length(decoded_user_bit{u});
            frame_err(frame, snr_idx) = ( bit_err ~= 0 );
            
            if TurnOn.FreqSyn 
                freq_err = delta_fc - (offset1 + offset2);
            else
                freq_err = NaN;
            end   
            
            user_bit_err{u}(frame,snr_idx) = bit_err;
            
            mse_ce_acc{u}(frame,snr_idx) = mse_ce;
            mean_nor_H = sum(H_freq{u}(Idx_used,2,1)'* H_freq{u}(Idx_used,2,1))/N_used;
            mean_nor_H = sum(abs(mean_nor_H))/N_Rx_ant;
            nmse_ce_acc{u}(frame,snr_idx) = mse_ce/mean_nor_H ;
            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\tBER:%f\tCh.Est. MSE:%f  Timing Err(Sample):%d\tFreq.Syn. Err(Hz):%d\n',...
            Eb_No_dB, frame, bit_err,ber, mse_ce, err_frame_timing , freq_err);
        
    end                      % OFDM帧
    
    ber_snr = sum(user_bit_err{u}(:,snr_idx))/(length(decoded_user_bit{u})*N_frame);
    fer_snr = sum(frame_err(:,snr_idx))/(N_frame);
    mse_snr = sum(mse_ce_acc{u}(:,snr_idx))/(N_frame);
    fprintf('\nStatistics for the current Eb/No:\t');
    fprintf('BER:%f\t FER:%f\t Ch.Est. MSE:%f\n',ber_snr,fer_snr,mse_snr);
    
    timer(snr_idx) = toc;     % 计算时间结束
    time_passed = round(sum(timer)/60);
    time_left = round( (length([Eb_NoStart:Eb_NoInterval:Eb_NoEnd]) - snr_idx)*time_passed/snr_idx );
    fprintf('\nTime Passed:\t%d min\t Time Left:\t  %d min\n\n\n',time_passed,time_left);
    
    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 + -