echo off; % 关闭回显
clear all; % 从内存中清除变量和函数
close all; % 关闭所有图形
fprintf( '\n OFDM仿真\n \n') ; % 设置显示格式
% --------------------------------------------- %
% 参数定义 %
% --------------------------------------------- %
IFFT_bin_length = 1024; % 发送端的IFFT变换长度, 接收端的FFT变换长度,R代表接受,T代表发送
carrier_count = 200; % 子载波数
bits_per_symbol = 2; % 位数/符号
symbols_per_carrier = 50; % 符号数/载波
cp_length = input('cp length = '); % 输入循环前缀长度
d4 = input('d4 = '); % 输入最大多径时延扩展
a4 = input('a4 = '); % 输入最大多径时延扩展的系数
SNR = input('SNR = '); % 输入信道信噪比(dB)
% --------------------------------------------- %
% 初始参数设置完毕 %
% --------------------------------------------- %
baseband_out_length = carrier_count * symbols_per_carrier * bits_per_symbol; % 计算发送的二进制序列长度:基带传送长度=载波数× 符号数/载波×位数/符号
carriers = (1:carrier_count) + (floor(IFFT_bin_length/4) - floor(carrier_count/2)); % 载波(坐标):(1:200) + 256 - 100 = 157:356
conjugate_carriers = IFFT_bin_length - carriers + 2; % 载波变换(坐标):1024 - (157:356) + 2 = 1026 - (157:356) = (869:670)
%---------------------------------------
% 构造共轭时间-载波矩阵,以便应用所谓的RCC,Reduced Computational Complexity算法,即ifft之后结果为实数
% 也可以用flipdim函数构造对称共轭矩阵
%---------------------------------------
% --------------------------------------------- %
% 发送信号 %
% --------------------------------------------- %
%---------------------------------------
% Generate a random binary output signal:
% - a row of uniform random numbers (between 0 and 1), rounded to 0 or 1
% - this will be the baseband signal which is to be transmitted.
%---------------------------------------
baseband_out = round(rand(1,baseband_out_length));
%---------------------------------------
% round:朝最近的整数取整,rand:产生均匀分布的随机数矩阵(1×baseband_out_length阶)
% Convert to 'modulo N' integers where N = 2^bits_per_symbol
% - this defines how many states each symbol can represent
% - first, make a matrix with each column representing consecutive bits
% from the input stream and the number of bits in a column equal to the
% number of bits per symbol
% - then, for each column, multiply each row value by the power of 2 that
% it represents and add all the rows
% - for example: input 0 1 1 0 0 0 1 1 1 0
% bits_per_symbol = 2
% convert_matrix = 0 1 0 1 1
% 1 0 0 1 0
% modulo_baseband = 1 2 0 3 2
%---------------------------------------
convert_matrix = reshape(baseband_out,bits_per_symbol,length(baseband_out)/bits_per_symbol) ;
%---------------------------------------
% RESHAPE Change size. 把baseband_out变为M×N阶的矩阵
% RESHAPE(X,M,N) returns the M-by-N matrix whose elements
% are taken columnwise from X. An error results if X does
% not have M*N elements.
%---------------------------------------
for k = 1:(length(baseband_out)/bits_per_symbol)
modulo_baseband(k) = 0 ;
for i = 1:bits_per_symbol
modulo_baseband(k) = modulo_baseband(k) + convert_matrix(i,k)*2^(bits_per_symbol - i) ;
end
end
%---------------------------------------
% Serial to Parallel Conversion 串并转换
% - convert the serial modulo N stream into a matrix where each column
% represents a carrier and each row represents a symbol
% - for example:
% serial input stream = a b c d e f g h i j k l m n o p
% parallel carrier distribution =
% C1/s1=a C2/s1=b C3/s1=c C4/s1=d
% C1/s2=e C2/s2=f C3/s2=g C4/s2=h
% C1/s3=i C2/s3=j C3/s3=k C4/s3=l
% . . . .
% . . . .
%---------------------------------------
carrier_matrix = reshape(modulo_baseband, carrier_count, symbols_per_carrier)'; % 生成时间-载波矩阵(carrier_count×symbols_per_carrier)
%---------------------------------------
% Apply differential coding to each carrier string
% - append an arbitrary start symbol (let it be 0, that works for all
% values of bits_per_symbol) (note that this is done using a vertical
% concatenation [x;y] of a row of zeros with the carrier matrix, sweet!)
% - perform modulo N addition between symbol(n) and symbol(n-1) to get the
% coded value of symbol(n)
% - for example:
% bits_per_symbol = 2 (modulo 4)
% symbol stream = 3 2 1 0 2 3
% start symbol = 0
%
% coded symbols = 0 + 3 = 3
% 3 + 2 = 11 = 1
% 1 + 1 = 2
% 2 + 0 = 2
% 2 + 2 = 10 = 0
% 0 + 3 = 3
%
% coded stream = 0 3 1 2 2 0 3
%---------------------------------------
% --------------------------------------------- %
% QDPSK调制 %
% --------------------------------------------- %
carrier_matrix = [zeros(1,carrier_count);carrier_matrix]; % 添加一个差分调制的初始相位,为0
for i = 2:(symbols_per_carrier + 1)
carrier_matrix(i,:) = rem(carrier_matrix(i,:)+carrier_matrix(i-1,:),2^bits_per_symbol); % 差分调制(rem除后取余)
end
%---------------------------------------
% Convert the differential coding into a phase
% - each phase represents a different state of the symbol
% - for example:
% bits_per_symbol = 2 (modulo 4)
% symbols = 0 3 2 1
% phases =
% 0 * 2pi/4 = 0 (0 degrees)
% 3 * 2pi/4 = 3pi/2 (270 degrees)
% 2 * 2pi/4 = pi (180 degrees)
% 1 * 2pi/4 = pi/2 (90 degrees)
%---------------------------------------
carrier_matrix = carrier_matrix * ((2*pi)/(2^bits_per_symbol)); % 产生差分相位
%---------------------------------------
% Convert the phase to a complex number
% - each symbol is given a magnitude of 1 to go along with its phase
% (via the ones(r,c) function)
% - it is then converted from polar to cartesian (complex) form
% - the result is 2 matrices, X with the real values and Y with the imaginary
% - each X column has all the real values for a carrier,