figure(1)
hold on
clear all;
%close all;
N_Tx_ant = 2; %发送天线为2
N_Rx_ant = 1; %接收天线为2
N_user = 1; %用户数为1
N_sym = 2; % 每帧中OFDM符号数, LTE中一帧长度为6~7个OFDM符号
N_frame = 500; % 仿真的帧个数
% 仿真循环开始的Eb_No,定义为每比特的能量Eb
% 和噪声的单边功率谱密度No的比值, dB值
Eb_NoStart = 0;
Eb_NoInterval = 2; % 仿真Eb/No的间隔值(dB)
Eb_NoEnd = 16; % 仿真Eb/No的终止值(dB)
%仿真参数选择的是LTE系统带宽为10MHz时参数
fc = 5e9; % 载波频率(Hz) 5GHz
Bw = 10e6; % 基带系统带宽(Hz) 10MHz
fs = 15.36e6; % 基带抽样频率 1024*15KHz=15360000Hz
T_sample = 1/fs; % 基带时域样点间隔(s)
N_subc = 1024; % OFDM 子载波总数,即FFT点数
Idx_used = [N_subc/2-300+1:N_subc/2+300]; % 使用的子载波坐标,一共使用600个子载波
N_data = length(Idx_used); % 使用的子载波数 600
PrefixRatio = 1/4; %循环前缀所占比例
T_sym = T_sample*( (1 + PrefixRatio)*N_subc );%一个OFDM符号(包含循环前缀)的持续时间
Modulation = 1; %调制方式,2--QPSK调制,1--BPSK
Es = 1; % 符号能量都被归一化
Eb = Es/Modulation; % 每比特能量
N_ant_pair = N_Tx_ant * N_Rx_ant; % 收发天线对的数目
ST_Code = 1; % 空时编码: , 1--空时分组码
% 添加信道
% 车辆运动速度, 单位:km/hr , 对应多普勒频移!!
speed = 0;
ch = struct('Speed', speed);
% 多普勒频移, 单位: Hz
ch.fd = ch.Speed *(1e3/3.6e3)*fc/3e8; %fd=f0*v/c
% 假定用户的信道功率时延谱不同
% 用户信道每条径的功率
ch.Power = 10.^([ 0 -6 -12 -18 -24 -30 ]'./10);%10.^([ 0 0 0 0 0 0 ]'./10);%
ch.Power = ch.Power/ sum(ch.Power); % 功率归一化
% 用户每条径的时延:ns
%ch.Delay = [ 0 1400 2800 4200 5600 7000 ]'; % 最大多径时延 7us 室外信道 相关带宽为最大时延的倒数 detaf=1/Tdelaymax=1/7000*10e-9=1.4286e4 Hz<15000Hz,故在一个子载波15KHz带宽内,可认为是平坦衰落
%ch.Delay = [ 0 1000 2000 3000 4000 5000 ]'; % 最大多径时延 5us 室外信道
ch.Delay = [ 0 100 200 300 400 500 ]'; % 最大多径时延 500ns 室内信道参数
% 用户每条径对应的样点数
ch.Delay_sample = round(ch.Delay * 1e-9 * fs);
ch.N_path = size(ch.Power,1); % 径数
CE_SubcRemain = max(ch.Delay_sample); % 最大多径时延对应的样点数
snr_idx = 1;
for Eb_No_dB = Eb_NoStart:Eb_NoInterval:Eb_NoEnd
Eb_No = 10^(Eb_No_dB/10); %线性信噪比
var_noise = Eb/(2*Eb_No); % 噪声样点的功率 No为单边功率 No=2*var_noise
for frame = 1:N_frame %逐帧循环计算
h_time = time_channel_para( ch, N_Tx_ant, N_Rx_ant,N_sym, T_sym, fs, N_subc, ...
PrefixRatio,N_frame,frame);%时域信道参数,每一条多径,每一个符号,每一条无线信道对应的时域信道参数
H_freq = to_freq_channel( h_time, ch ,N_subc ,N_sym, N_Tx_ant,...
N_Rx_ant);%频域信道参数,每一个子载波,每一个符号,每一条无线信道对应的频域信道参数
bit_per_sym = Modulation * N_data;%一个用户在一个OFDM符号内传送的总bit数
user_bit_cnt = bit_per_sym * N_sym ;%每用户一帧内比特数
user_bit = rand ( user_bit_cnt ,1 ) > 0.5 ;%产生二进制随机序列
bit_to_mod=reshape(user_bit,Modulation,user_bit_cnt/Modulation);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%BPSK调制
sym=2*bit_to_mod-1;
%QPSK调制
% mapping_matrix = exp(j*[-3/4*pi 3/4*pi -1/4*pi 1/4*pi]);% 比特的映射关系,00:-3/4*pi,01:3/4*pi,10: -1/4*pi,11: 1/4*pi
% index = [2 1]*bit_to_mod;
% sym = mapping_matrix(index + 1);%QPSK moudulation
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
sym=reshape(sym,N_data,N_sym);
mod_sym = zeros(N_subc,N_sym);
mod_sym(Idx_used,:)=sym;%子载波映射
%空时编码
st_coded = zeros(N_subc,N_sym, N_Tx_ant);%第三维表示不同的天线发送的数据
for n = 1:N_sym/N_Tx_ant
input = mod_sym( :,(n-1)*N_Tx_ant+1 : n*N_Tx_ant ) ;
Xe=input(:,1);%取第一列,即第一个OFDM符号
Xo=input(:,2);%取第二列,即第二个OFDM符号
coded_tmp=[Xe Xo;-conj(Xo) conj(Xe)];%alamouti编码
for ant = 1:N_Tx_ant
tmp = reshape(coded_tmp(:,ant), N_subc, N_Tx_ant);%第一根天线发送的前两个符号为[Xe,-conj(Xo)]
st_coded(:, (n-1)*N_Tx_ant+1:n*N_Tx_ant ,ant) = tmp;%利用第三维表示不同天线发送的OFDM符号
end
end
%OFDM调制
transmit_signal = zeros(1,N_subc*N_sym*(1+PrefixRatio),N_Tx_ant);
cp_len = round(PrefixRatio*N_subc);
for ant = 1:N_Tx_ant
ofdm_frame = sqrt(N_subc) * ifft( fftshift( st_coded(:,:,ant), 1 ) );%按列进行IFFT计算
cp = ofdm_frame(N_subc - cp_len + 1:N_subc ,:);
ofdm_frame = [cp;ofdm_frame];
transmit_signal(:,:,ant) =1/2* reshape( ofdm_frame, 1, N_subc*N_sym*(1+PrefixRatio) ); %两天线的发送信号
end
%接收机
TurnOn.Channel=1;%是否添加瑞利衰落信道
[recv_signal ] = channel( transmit_signal,h_time, ch, N_Tx_ant, N_Rx_ant,...
var_noise,N_subc,PrefixRatio,N_sym,TurnOn.Channel );
%OFDM解调
data_sym = zeros(N_subc,N_sym,N_Rx_ant);
cp_len = round(PrefixRatio*N_subc);
recv_signal=recv_signal(:,1:N_subc*(1+PrefixRatio)*N_sym,:);%去除一帧最后的延迟样点
for ant = 1:N_Rx_ant
ofdm_tmp = reshape( recv_signal(1,:,ant), N_subc*(1+PrefixRatio) , N_sym );%将每根天线上接收到的信号进行串并变换
cp_cut = ofdm_tmp( cp_len + 1:end,: );%去除循环前缀
ofdm_sym(:,:,ant) = fftshift(1/sqrt(N_subc) * fft( cp_cut ), 1);
end
data_sym = ofdm_sym(:, 1:N_sym ,:); %数据OFDM符号
%空时解码
channel_est = H_freq(:,2,:); %理想信道估计,取一帧内第二个符号的H作为信道估计值
st_decoded = zeros(N_subc, N_sym);
H = squeeze(channel_est(:,1,:));%不管实际信道为快衰落或者慢衰落,STBC解码均假设为准静态信道,
%即相邻两符号的衰落系数相同,故在时刻上取一个时刻的衰落系数即可
%接收天线数为1时的空时解码
for n = 1:N_sym/N_Tx_ant
R = [];
R = [R data_sym(:,(n-1)*N_Tx_ant+1:n*N_Tx_ant) ];%天线在时刻1 和时刻2 接收到的信号
R1=R(:,1);
R2=R(:,2);
H1=H(:,1);%发送天线1到接收天线1的衰落系数
H2=H(:,2);%发送天线2到接收天线1的衰落系数
for i=1:1:N_subc
Xe(i,1)= conj(H1(i))*R1(i)+H2(i)*conj(R2(i));
Xo(i,1)= conj(H2(i))*R1(i)-H1(i)*conj(R2(i));
end
output=[Xe Xo];
st_decoded(:,(n-1)*N_Tx_ant+1:n*N_Tx_ant) = output;
end
%数字解调
demod_user_bit = [];
for n = 1:N_sym
demodu_sym=st_decoded(Idx_used,n).';
bit_out = zeros(Modulation ,size(demodu_sym,2));
%BPSK解调
bit_out(:)=demodu_sym>0;
%QPSK解调
% bit0 = real(demodu_sym) ;
% bit1 = imag(demodu_sym) ;
% bit_out(1,:) = bit0 > 0;
% bit_out(2,:) = bit1 > 0;
demod_user_bit=[demod_user_bit bit_out(:)];
end
demod_user_bit=reshape(demod_user_bit,1,size(user_bit,1)).';
%性能统计
bit_err = sum(abs(demod_user_bit - user_bit));%一帧内误码计算
user_bit_err(frame,snr_idx) = bit_err ;%每一个信噪比下,每一帧内的误码数
fprintf('Eb/No:%d dB\tFrame No.:%d Err Bits:%d\n',...
Eb_No_dB, frame, bit_err);
end %重复帧循环结束
snr_idx =