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

📄 main.m

📁 程序里面包含各部分算法仿真 可供参考和使用
💻 M
📖 第 1 页 / 共 2 页
字号:
clear all;
close all;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% OFDMA链路层仿真程序框架

% 变量命名原则:
% 1) 开头大写,表示常量或可调全局变量,控制程序流程
% 2) 小写加下划线,表示临时变量,传递数据

% 变量使用原则:
% 1) 不同用户的临时变量数据封装在cell结构体元素中,这是因为其数据长度可能不同
% 2) 频域矩阵,不同列表示时间(OFDM符号),不同行表示子载波,矩阵第三维表示不同天线的数据
% 3) 时域矩阵,不同列表示时间的样点, 如有不同行则表示时延(如时域信道响应矩阵), 第三维同样表示天线
% 4) 部分常量或可调全局变量,用struct结构体归类

% 函数命名和使用原则:
% 1) 小写加下划线命名
% 2) 部分函数可以根据输入变量个数实现函数功能重载

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 一. 初始化部分

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 1.程序复杂度控制单元, 用结构体TurnOn, 和一些全局参数控制,
% 目的是针对特定需求, 降低运行复杂度, 使之在学术科研中发挥较大作用
% 打开相应模块功能---1,关闭相应模块功能---0

% 如关闭信道估计和补偿模块, 使用理想信道估计
ChannelEst = 1;
TurnOn = struct('ChannelEst',ChannelEst);

% 使用收发天线数进行控制, 开关多天线模块(包括空时编码和多天线信道).
% 单天线多径信道,其功率时延谱, 多普勒频移等参数由结构体ch确定. 
% 多天线多径信道,同一用户的不同收发天线假设功率时延谱相同, 
% 发送天线数, 可选1,2和4. 发送天线为1则没有空时编码
N_Tx_ant = 4;      
% 接收天线数, 可选1,2,4,8,..,2^N.  接收天线为1则没有合并
N_Rx_ant = 8;

% 信道编码模块
TurnOn.ChannelCoding = 0;

% 频域加信道模块。打开此模块,则关闭时域加信道模块,时域同步模块,OFDM调制解调模块。
TurnOn.AddChFreq = 1;

%  用户数目
N_user = 1;           

% 自适应调制
TurnOn.AdptMod = 0;

% 如关闭包检测和帧定时同步模块, 定时位置准确
TurnOn.Timing = 0;

% 如关闭频率同步模块, 载波频率偏差为 0 Hz, 不使用频偏纠正算法
TurnOn.FreqSyn = 0;

% 建议: 不同重点的研究,使用不同的程序结构,关闭认为次要的模块.
% 如要评估系统总的性能,则可以打开所有模块

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 2 参数定义单元,用户自定义

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 2.1 OFDMA收发机系统参数定义单元
% 命名规律: N_xxx: xxx的数目,为非负整数
%           T_xxx: xxx的持续时间,为非负实数
%           Idx_xxx: xxx的编号,为整数向量
%           一些约定俗成的表示, 如fc载频, Bw信道带宽等

% 1) 系统的帧结构(对863帧结构进行了简化,只考虑上行或下行时隙,不考虑切换时间,时隙的时隙结构可调)
%----------------------------------------------------------------------------------------------------
%|   同步时隙    |  数据时隙1     |   数据时隙2      |   数据时隙3      |   ...   |  数据时隙N      |
%|               |                |                  |                  |   ...   |                 |
%----------------------------------------------------------------------------------------------------

%|<----------------------------------------- 1帧 -------------------------------------------------->| 

N_frame = 10;               %  仿真的帧总数
% a) 同步时隙, 包括三个OFDM符号。用于定时,初始载波同步
N_syn_preamble = 3;          % 同步时隙训练符号为3个
% b) 数据时隙, 由多个数据OFDM符号组成,分为数据符号和导频符号。             
%  假设每个数据时隙有N_sym_ts个OFDM符号,而一共假设有N_ts个数据时隙。
%  数据符号,主要传输用户数据,并在数据符号子载波上间隔插入导频,用于载波相位跟踪, 导频位置由Idx_pilot确定。
%  导频符号,用于估计信道,并抵抗多普勒频移。可全插导频,也可以间隔插导频。
N_ts = 2;                                   % 总共的数据时隙数目
Pos_pilot_sym = [1 7];                      % 导频OFDM符号在时间上的位置
Pos_data_sym = [2:6];                         %  数据OFDM符号在时间上的位置
N_pilot_sym_ts = length(Pos_pilot_sym);     % 每个数据时隙的导频OFDM符号数目
N_data_sym_ts = length(Pos_data_sym);       % 每个数据时隙的数据OFDM符号数目
N_sym_ts = N_pilot_sym_ts + N_data_sym_ts;  % 每个数据时隙的OFDM符号数目
N_sym = N_sym_ts*N_ts + N_syn_preamble;     % 总的OFDM符号数目
N_data_sym = N_data_sym_ts*N_ts;            % 总的数据OFDM符号数目

% 2) OFDM相关参数:
% 调制方式:
% a) 当TurnOn.AdptMod = 0 时表示所有子载波用调制方式:(不使用信道编码时)
% 1--BPSK调制, 2--QPSK调制,3--8PSK调制, 4--16QAM调制,6--64QAM调制
% b) 当TurnOn.AdptMod = 1 时表示自适应调制,平均每个子载波上调制的比特数
% 此时最大只能设置为4, 否则调制器无法处理
Modulation = 2;       

% 仿真循环开始的Eb_No,定义为每比特的能量Eb
% 和噪声的单边功率谱密度No的比值, dB值
Eb_NoStart = 0;                                                          
Eb_NoInterval = 2;              % 仿真Eb/No的间隔值(dB)
Eb_NoEnd = 20;                   % 仿真Eb/No的终止值(dB)                        

N_subc = 64;                              %  OFDM 子载波总数

switch N_subc
case 1024
    %Idx_used = [-416:-1 1:416];             %  使用的子载波位置编号
    Idx_used = [-512:1:511];
    Idx_pilot = [-400:25:-25 25:25:400];    %  数据OFDM符号中的导频子载波在频率上的位置编号
    PrefixRatio = 27/128;                   %  OFDM循环前缀占有效FFT时间的比例
case 512
    Idx_used = [-200:-1 1:200];             
    Idx_pilot = [-200:25:-25 25:25:200];    
    PrefixRatio = 1/4;                   
case 64
    %Idx_used = [-26:-1 1:26];    
    Idx_used = [-32:1:31];  
    Idx_pilot = [-21:14:-7 7:14:21];    
    PrefixRatio = 1/4;
end

Es = 1;                 % 在16QAM, 64QAM调制方式下,符号能量都已经被归一化 
Eb = Es/Modulation;     % 每比特能量    
fc = 3.5e9;                             %  载波频率(Hz)
Bw = 20e6;                              %  基带系统带宽(Hz)
fs = 20e6;                              %  基带抽样频率
T_sample = 1/fs;                        %  基带时域样点间隔(s)

N_used = length(Idx_used);              % 使用子载波数
N_pilot = length(Idx_pilot);            % 导频子载波数
N_data = N_used - N_pilot;              % 数据子载波数
Idx_data = zeros(1,N_data);

% 得到数据子载波的编号
m = 1; n = 1;
for k  = 1:length(Idx_used)
    if Idx_used(k) ~= Idx_pilot(m);
        Idx_data(n) = Idx_used(k);
        n = n + 1;
    else
        if m ~= N_pilot
            m = m + 1;
        end
    end
end
%  为编程使用方便,调整子载波编号为从1开始,到子载波总数
Idx_used = Idx_used + N_subc/2 +1;       
Idx_pilot = Idx_pilot + N_subc/2 +1;
Idx_data = Idx_data + N_subc/2 +1; 
% 数据符号用于同步的导频的取值
PilotValue = (( rand(N_pilot,1)>.5 )*2 - 1)/sqrt(N_Tx_ant);
% OFDM符号持续时间
T_sym = T_sample*( (1 + PrefixRatio)*N_subc );
N_ant_pair = N_Tx_ant * N_Rx_ant;   % 收发天线对的数目

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% 2.2 信道参数定义单元, 每个用户移动台参数不同
for u = 1:N_user
    % 车辆运动速度, 单位:km/hr. 范围:5km/hr~ 250km/hr. 对应多普勒频移:16.2Hz ~ 810.2Hz
    speed = 5;         
    ch{u} = struct('Speed', speed);
    % 多普勒频移, 单位: Hz
    ch{u}.fd = ch{u}.Speed *(1e3/3.6e3)*fc/3e8;  
    % 指数衰落的信道功率时延谱, 时延:ns    
    ch{u}.Power = 10.^([ 0 -6 -12 -18 -24 -30 ]'./10);  % 6径信道每条径的功率
    if N_subc == 1024
        ch{u}.Delay = [ 0 2000 4000 6000 8000 10000 ]';      % 最大多径时延 10us 室外信道
        %ch{u}.Delay = [ 0 1400 2800 4200 5600 7000 ]';      % 最大多径时延 7us 室外信道
        %ch{u}.Delay = [ 0 300 600 900 1200 1500 ]';         % 最大多径时延 1.5us 室外信道
    elseif N_subc == 512
        ch{u}.Delay = [ 0 1000 2000 3000 4000 5000 ]';     % 最大多径时延 5us 室外信道参数
    elseif N_subc == 64        %ch{u}.Delay = [ 0 50 100 150 200 250 ]';          % 最大多径时延 250ns 室内信道参数
        ch{u}.Delay = [ 0 100 200 300 400 500 ]';          % 最大多径时延 500ns 室内信道参数
    end
    Idx_cir = round(ch{u}.Delay/(T_sample*10^9)) + 1;           % 时域信道响应的径对应的时域样点位置

    % 室内信道的功率时延谱(HIPERLAN2)
    %        ch{u}.Power = [ 0.3240 0.4015 0.0929 0.0961 0.0291 0.0340 0.0060 0.0165];
    %        ch{u}.Delay = [ 50 100 150 200 250 300 350 400 ]';    
    
    ch{u}.Power = ch{u}.Power/ sum(ch{u}.Power); % 功率归一化
    % 每个用户每条径对应的样点数
    ch{u}.Delay_sample = round(ch{u}.Delay  * 1e-9 * fs);                 
    ch{u}.N_path = size(ch{u}.Power,1);          % 径数 
    % 每个用户,各条径对应的莱斯衰落K因子
    % ch{u}.Ricean_K = zeros(N_path,1) ;         

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 2.3 OFDMA收发机算法选择和参数定义单元

% 1) 信道估计: 单天线信道估计算法,使用导频辅助进行信道估计
% 1 - 基本LS算法; 2 - LS的DFT改进算法; 3 - 加判决反馈的LS-DFT
% 4 - 基本MMSE算法; 5 - MMSE的DFT改进算法; 6 - 加判决反馈的MMSE-DFT
% 7 - SVD分解算法,8 - Robust算法
% 9 - 自适应滤波器结合单天线信道估计的方法, 10 - EM 方法

SISO_CE_Method = 1;                    
% 使用LS或MMSE的DFT改进算法时,所保留的子载波数                                    
L_delay = max(ch{u}.Delay_sample) + 1;        % 最大多径时延对应的样点数  
% 插值方法: 1 - 线性插值, 2 - 二次插值, 3 - 三次样条插值,  
%           4 - 时域插值, 5 - 低通滤波器插值
InterpMethod = 3;

% 多天线信道估计方法,使用导频辅助进行信道估计
% 1 - 基本LS算法; 2 - LS的改进算法1; 3 - LS的改进算法2; 4 - LS的改进算法3; 
% 5 - 频域区分子载波的方法,使用 SISO_CE_Method 选择的算法,以及 InterpMethod 选择的插值方法
% 6 - 使用发送多个OFDM符号,线性组合求得多天线信道响应
MIMO_CE_Method = 1;
% 在方法6中使用正交导频--1,使用非正交导频--0
SwitchOrthogonalPilot = 0;

% 2) 空时编码:  1--空时分组码,2发,码率为1;4发,码率为1/2
%                 2--分层空时码,4发8收,码率为4。         
ST_Code = 2;
HardOrSoft = 0; % 0 - 分层空时码输出为未判决的星座点,1-- 分层空时码输出为判决后的星座点
LST_method = 1; % 分层空时码解码算法,1-- SIC-ZF, 2 -- MMSE.
% 空时处理的编码速率
if (ST_Code == 1)&(N_Tx_ant == 4)   % 4发STBC,码率1/2
    RateSTCoding = 1/2;
elseif (ST_Code == 2)&(N_Tx_ant == 4)   % 4发BLAST,码率4
    RateSTCoding = 4;
else
    RateSTCoding = 1;               
end

% 3) 信道编码,速率:1/3, 1/2, 2/3, 3/4
ChCodingMethod = 1;         % 1 - Turbo码+交织 , 2 - 卷积+RS+交织
Puncture = 0;                               % 是否凿孔

if TurnOn.ChannelCoding == 1
    if ChCodingMethod == 1
        RateChCoding = 1/(2 + Puncture);        % 编码速率
    elseif ChCodingMethod == 2
        RateChCoding = 1/2;               
    end
else 
    RateChCoding = 1;
end


% 如果使用Turbo码+交织:
Dec_alg = 0;                                             % 解码算法
N1 = 1;
L_total = N_data*RateChCoding*N1;                           % 帧长,也是交织长度
Generator = [ 1 1 1;
    1 0 1 ];                                            % 码字生成多项式
N_iter = 5;                                             % 解码器迭代次数
[temp, Alpha] = sort(rand(1,L_total));                  % 得到交织的顺序序列alpha

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -