clc
clear
%q1:ifft点数难道不是应该等于子载波数吗?子载波数与ifft点数的关系?
%a:ifft点数等于子载波数
%q2:对矩阵进行fft?
%a:y可以是一向量或矩阵,若y为向量,则Y是y的FFT,并且与y具有相同的长度。若y为一矩阵,则Y是对矩阵的每一列向量进行FFT。
%image_data_generator();
%数据子载波数128
%fft点数512
snr = 0:1:20%dB 高斯信道的SNR
cdata_number = 128;
fft_n = 128;
%OFDM码元个数 500
%生成数据随机序列
cdata_length = 500;
cdata = rand_bit(cdata_number*cdata_length*2);
%--------------------------------------------------------------------------
figure;
subplot(2,1,1);
time(cdata(1,1:200),"信源序列时域图",'B');
subplot(2,1,2);
frequency_response(cdata(1,1:200),"信源序列频谱图",'B');
%--------------------------------------------------------------------------
%导频长度256
%插入导频间隔为5
%生成随机的的导频序列
pilot_inter = 5;
pilot_length = 256;
pilot_bit = rand_bit(pilot_length);
%--------------------------------------------------------------------------
figure;
subplot(2,1,1);
time(pilot_bit(1,1:200),"导频序列时域图",'B');
subplot(2,1,2);
frequency_response(pilot_bit(1,1:200),"导频序列频谱图",'B');
%--------------------------------------------------------------------------
%进行qpsk调制 输出复数矩阵
qpsk_bit = modulator_QPSK(cdata);
scatterplot(qpsk_bit);
%--------------------------------------------------------------------------
figure;
subplot(2,1,1);
time(real(qpsk_bit(1:100)),"信源序列QPSK",'B');
hold on;
time(imag(qpsk_bit(1:100)),"信源序列QPSK",'R');
subplot(2,1,2);
frequency_response(qpsk_bit(1:100),"信源序列QPSK频谱图",'B');
%--------------------------------------------------------------------------
%串并转换 128*1000
paradata = reshape(qpsk_bit,cdata_number,cdata_length);
%--------------------------------------------------------------------------
%插入导频
inserted_bit = insert_pilot(paradata,pilot_bit,pilot_inter);
%--------------------------------------------------------------------------
%逆傅里叶变换
ifft_data = ifft(inserted_bit,fft_n,1)*sqrt(fft_n);
%--------------------------------------------------------------------------
figure;
subplot(2,1,1);
time(real(ifft_data(1:100)),"逆傅里叶变换时域图",'B');
hold on;
time(imag(ifft_data(1:100)),"逆傅里叶变换时域图",'R');
subplot(2,1,2);
frequency_response(ifft_data(1:100),"逆傅里叶变换频域图",'B');
%--------------------------------------------------------------------------
%生成OFDM频谱图
figure;
for i = 1:600
hold on;
frequency_response_deshift(inserted_bit(:,i)',"OFDM频域图",'B');
end
%--------------------------------------------------------------------------
%插入循环前缀
symbol_cp_pro = cyclic_prefix(ifft_data);
%--------------------------------------------------------------------------
[row,column] = size(symbol_cp_pro);
%--------------------------------------------------------------------------
%经过高斯信道
awgn_err_plot(cdata,symbol_cp_pro);
%--------------------------------------------------------------------------
%ls多径信道
ERR1 = ls_err_plot(cdata,symbol_cp_pro,pilot_bit);
%--------------------------------------------------------------------------
%并串转换
symbol_cp = reshape(symbol_cp_pro,1,[]);
%--------------------------------------------------------------------------
figure;
time(real(symbol_cp(1:160)),"加入CP时域图",'B');
hold on;
time(imag(symbol_cp(1:160)),"加入CP时域图",'R');
%--------------------------------------------------------------------------
%信道
%ts采样间隔
%fdDoppler频偏,HZ
%tau多径延时
%pdb各径功率
%---------------------------------------------多径信道---------------------
fs = 15000;
ts = 1/fs;
fd = 0;
tau = [0,50,120,200,230,500,1600,2300,5000]/(10^9);
pdb = [-1.0,-1.0,-1.0,0,0,0,-3.0,-5.0,-7.0];
chan = rayleighchan(ts,fd,tau,pdb);
chan.ResetBeforeFiltering = 0;
chan_symbol_s = filter(chan,symbol_cp);
%--------------------------------------------------------------------------
figure;
subplot(2,1,1);
time(real(chan_symbol_s(1:100)),"过多经信道时域图",'B');
hold on;
time(imag(chan_symbol_s(1:100)),"过多经信道时域图",'R');
subplot(2,1,2);
frequency_response(chan_symbol_s(1:100),"过多经信道频谱图",'B');
%--------------------------------------------多径信道-----------------------
%------------------------------------------叠加高斯信道---------------------
SNR = 20;%单位dB
chan_symbol_s = awgn(chan_symbol_s,SNR);
%--------------------------------------------------------------------------
figure;
subplot(2,1,1);
time(real(chan_symbol_s(1:100)),"过多经信道叠加高斯信道时域图",'B');
hold on;
time(imag(chan_symbol_s(1:100)),"过多经信道叠加高斯信道时域图",'R');
subplot(2,1,2);
frequency_response(chan_symbol_s(1:100),"过多经信道叠加高斯信道频谱图",'B');
%--------------------------------------------------------------------------
figure;
for i=1:100
plot(chan_symbol_s(i),'b*');
title('QPSK调制经过高斯信道后的信号星座图');
xlabel('I(t)');
ylabel('Q(t)');
hold on;
end
%--------------------------------------------------------------------------
%串并转换
chan_symbol_p = reshape(chan_symbol_s,row,length(chan_symbol_s)/row);
%--------------------------------------------------------------------------
%去循环码
re_symbol_cp = re_cyclic_prefix(chan_symbol_p);
%--------------------------------------------------------------------------
%fft
fft_symbol = fft(re_symbol_cp,fft_n,1)./sqrt(fft_n);
%--------------------------------------------------------------------------
figure;
subplot(2,1,1);
time(real(fft_symbol(:,1)'),"傅里叶变换时域图",'B');
hold on;
time(imag(fft_symbol(:,1)'),"傅里叶变换时域图",'R');
subplot(2,1,2);
frequency_response(fft_symbol(:,1)',"傅里叶变换频谱图",'B');
%--------------------------------------------------------------------------
%去除导频
[output,pilot_symbol] = re_insert_pilot(fft_symbol,pilot_inter);
% %----------------导频位置信道响应LS估计-----------------------------------
pilot_qpsk = modulator_QPSK(pilot_bit);
pilot_patt=repmat(pilot_qpsk',1,100);
pilot_esti=pilot_symbol./pilot_patt; % Y = H*X + S
[r,c] = size(output);
h = zeros(r,c);
for i = 1:100
h(:,(1+(i-1)*5):i*5) = repmat(pilot_esti(:,i),1,pilot_inter);
end
output = output./h;
%--------------------------------------------------------------------------
figure;
subplot(2,1,1);
time(real(output(1:100)),"接收序列QPSK",'B');
hold on;
time(imag(output(1:100)),"接收序列QPSK",'R');
subplot(2,1,2);
frequency_response(output(1:100),"接收序列QPSK频谱图",'B');
%--------------------------------------------------------------------------
figure;
for i=1:100
plot(output(i),'b*');
title('经过信道均衡后的信号星座图');
xlabel('I(t)');
ylabel('Q(t)');
hold on;
end
%--------------------------------------------------------------------------
%并串转换
output = reshape(output,1,[]);
re_modulated =re_modulatorQPSK(output);
figure;
subplot(2,1,1);
time(re_modulated(1,1:200),"接收端序列时域图",'B');
subplot(2,1,2);
frequency_response(re_modulated(1,1:200),"接收端序列频谱图",'B');
%--------------------------------------------------------------------------
% err = 0;
% for n = 1:length(cdata)
% if cdata(n) ~= re_modulated(n)
% err = err + 1;
% end
% end
% err = err/length(cdata);
% n = 1:20;
% ERR = repmat(err,1,20);
% figure;
% semilogy(n,ERR,'-*b')
% legend('OFDM仿真误码率')
% xlabel('符号信噪比 (dB)');
% ylabel('误符号率/误比特率');
%输入随机序列
function sr = rand_bit(L)
sr = round(rand(1,L));
end
%输入信号进行QPSK调制
function pilot_modulated = modulator_QPSK(pilot)
length_pilot = length(pilot);
ip = zeros(1,floor(length_pilot/2));
for ii = 1:floor(length_pilot/2)
ip(ii) = 1/sqrt(2)*1i*(2*pilot(2*ii) - 1) + 1/sqrt(2)*(2*pilot(1 + 2*(ii - 1)) - 1);
end
pilot_modulated = ip;
end
%QPSK解调
function output =re_modulatorQPSK(input)%序列
length_input = length(input);
output = zeros(1,2*length_input);
for ii = 1:length_input