📄 ofdm_mod.m
字号:
%%scr
close all;
clear all;
Nfft=128*2; %256 进行256点的FFT
Ng=32*2; %64
Nzero=0;
Nzerosub=floor((Nfft*0.5)/2); %for padding
Ntotal=Ng+2*Nzero+Nfft; %320
Constellation_num=16;
Symbol_num=20; %able
N=Symbol_num*Nfft; %total
Ns=Symbol_num*Ntotal;
Pnum_least(1:Symbol_num)=10000;
Pnum(1:Symbol_num)=0;
Ndata_o=Symbol_num*(Nfft/2-Nfft/16/2);
sita=0;
sita1=1;
sita2=0;
sita3=0; % 测试变量
sign=1;
%for filter
LHBF1=23; % 半带滤波器长度
% I1=zeros(1,Ndata_o);
% I2=zeros(1,Ndata_o);
% I3=zeros(1,Ndata_o);
% I4=zeros(1,Ndata_o);
CHBF1(1:LHBF1)=0;
InsertGIout(1:Symbol_num,1:Ntotal)=0;
% 半带滤波器系数
fid2=fopen('HBF23.txt','r');
CHBF1=fscanf(fid2,'%f');
fclose(fid2);
IHBF1in(1:LHBF1)=0;
QHBF1in(1:LHBF1)=0; % 进行半带滤波时的缓冲区
IHBF1out(1:2*Ns)=0;
QHBF1out(1:2:Ns)=0; % 两倍上采样后时域数据的存放数组
% I、Q分别表示I、Q两路信号
ii=1;
k=1;
k1=1;
k2=1;
k3=1;
k4=1;
k5=1;
t=1;
t2=1;
t3=1;
SoutI(1:Ns)=0;
SoutQ(1:Ns)=0; % 没有进行两倍上采样之前的时域数据存放数组
% I、Q分别表示I、Q两路信号
IFFToutI(1:Symbol_num,1:Nfft)=0;
IFFToutQ(1:Symbol_num,1:Nfft)=0;
IFFToutIQ(1:Symbol_num,1:Nfft)=0;
IFFToutIQS(1:Symbol_num,1:Nfft)=0; % 进行IFFT运算后OFDM符号存放数组
% I、Q分别表示I、Q两路信号
% IQ表示复数信息
FFTout_t_1(1:Symbol_num,1:2*Nfft)=0;
FFTout_t_2(1:Symbol_num,1:4*Nfft)=0;
FFTout_t_3(1:Symbol_num,1:8*Nfft)=0; % 测试变量
ii=1;
M_pilot=8;
subcarrier(1:N)=0;
subcarriercom(1:N)=0;
%train_word
% 获得短前导字频域信息
fid3=fopen('data_I_train_word_re_i0_256.txt','r');
I_train_word_re_temp=fscanf(fid3,'%f');
fclose(fid3);
I_train_word_re = (I_train_word_re_temp)';
fid3=fopen('data_Q_train_word_re_i0_256.txt','r');
Q_train_word_re_temp=fscanf(fid3,'%f');
fclose(fid3);
Q_train_word_re = (Q_train_word_re_temp)';
% 获得一个长前导字频域信息
fid3=fopen('data_I_train_word_1_i0_256.txt','r');
I_train_word_1_temp=fscanf(fid3,'%f');
fclose(fid3);
I_train_word_1 = (I_train_word_1_temp)';
fid3=fopen('data_Q_train_word_1_i0_256.txt','r');
Q_train_word_1_temp=fscanf(fid3,'%f');
fclose(fid3);
Q_train_word_1 = (Q_train_word_1_temp)';
% 获得二个长前导字频域信息
fid3=fopen('data_I_train_word_2_i0_256.txt','r');
I_train_word_2_temp=fscanf(fid3,'%f');
fclose(fid3);
I_train_word_2 = (I_train_word_2_temp)';
fid3=fopen('data_Q_train_word_2_i0_256.txt','r');
Q_train_word_2_temp=fscanf(fid3,'%f');
fclose(fid3);
Q_train_word_2 = (Q_train_word_2_temp)';
l=1;
%%%%%%%%%%%%%%^^^^^^^^^^^^^^^^^^^
%window sequence
% 加窗处理的参数设置
wind=zeros(1,(Nfft+Ng));
windo=hamming(Nfft+Ng);
wind((Ng+1):Nfft)=windo((Ng+1):Nfft);
wind(1:Ng)=windo(Ng+1);
wind((Nfft+1):(Nfft+Ng))=windo(Nfft);
%%%%%%%%%%%%%%%%^^^^^^^^^^^^^^^^^^^
stst=1;
%%%%%%%%%%%%%%%$$$$$$$$$$$$$$$$$
% 获得随机数,当作用户信息,调制到各个子载波上
fid3=fopen('I1.txt','r');
I1=fscanf(fid3,'%d,');
fclose(fid3);
fid3=fopen('I2.txt','r');
I2=fscanf(fid3,'%d,');
fclose(fid3);
fid3=fopen('I3.txt','r');
I3=fscanf(fid3,'%d,');
fclose(fid3);
fid3=fopen('I4.txt','r');
I4=fscanf(fid3,'%d,');
fclose(fid3);
% Bits Mapping to constellations
for i=1:N
% 前面4个符号是前导字
if(i < Nfft*4+1)
% 短前导字
if( i>0 & i < 2*Nfft+1)
if(rem(i,Nfft) == 0)
Imapped(i) = I_train_word_re(Nfft);
Qmapped(i) = Q_train_word_re(Nfft);
else
Imapped(i) = I_train_word_re(rem(i,Nfft));
Qmapped(i) = Q_train_word_re(rem(i,Nfft));
end
end
% 第一个长前导字
if( i>2*Nfft & i < 3*Nfft+1)
if(rem(i,Nfft) == 0)
Imapped(i) = I_train_word_1(Nfft);
Qmapped(i) = Q_train_word_1(Nfft);
else
Imapped(i) = I_train_word_1(rem(i,Nfft));
Qmapped(i) = Q_train_word_1(rem(i,Nfft));
end
end
% 第二个长前导字
if (i>3*Nfft & i<Nfft*4+1)
if(rem(i,Nfft) == 0)
Imapped(i) = I_train_word_2(Nfft);
Qmapped(i) = Q_train_word_2(Nfft);
else
Imapped(i) = I_train_word_2(rem(i,Nfft));
Qmapped(i) = Q_train_word_2(rem(i,Nfft));
end
end
else
% 前导字发送完后,发送用户信息,这里用随机数代替用户信息
% 中间查0的虚拟子载波没有用户信息
if ((rem(i,Nfft) < (Nfft/2-Nzerosub+1)) | (rem(i,Nfft) > (Nfft/2+Nzerosub)))
if(rem(i,Nfft/(2*M_pilot))==0) % insert pilots
if (sign==1)
Isignal=3*1.414;
Qsignal=0;
else
Isignal=-3*1.414;
Qsignal=0;
end %% sub-carrier polit scheme is BPSK
stst=stst+1;
else
% 插入导频信息
Isignal = 2*(I1(l)*1+I2(l)*2)-3;
Qsignal = 2*(I3(l)*1+I4(l)*2)-3;
l=l+1;
end
Imapped(i)=Isignal;
Qmapped(i)=Qsignal;
else
% 中间查0的虚拟子载波没有用户信息
Imapped(i)=0;
Qmapped(i)=0;
end
end
if (rem(i,Nfft)==0)
%%%%%%%%%%%
now_step = [num2str(ii)]
sign=rem(sign+1,2);
Imappedfs(1:Nfft)=Imapped(i-Nfft+1:i);
Qmappedfs(1:Nfft)=Qmapped(i-Nfft+1:i);
% 对频域信息进行IFFT变换,获得时域信息
IFFToutI(ii,1:Nfft)=ifft(Imappedfs,Nfft);
IFFToutQ(ii,1:Nfft)=ifft(Qmappedfs,Nfft);
%IFFToutIQ(ii,1:Nfft)=IFFToutI+j*IFFToutQ;
IFFToutIQS(ii,1:Nfft)=ifft(Imappedfs(1:Nfft)+j*Qmappedfs(1:Nfft),Nfft);
IFFToutIQ(ii,1:Nfft)=IFFToutIQS(ii,1:Nfft);
ii=ii+1;
end;
end; % end of fft symbol generation
% Insert Guard Interval, refix & postfix zero. Pallel processing . serial output at 1/Ts rate
for (ig=1:Symbol_num)
% 插入循环前缀
InsertGIout(ig,1:Nzero)=0;
InsertGIout(ig,Ng+Nzero+1:(Ng+Nfft+Nzero))=IFFToutIQ(ig,1:Nfft);
InsertGIout(ig,Nzero+1:(Ng+Nzero))=IFFToutIQ(ig,(Nfft-Ng)+1:Nfft);
InsertGIout(ig,(Ng+Nfft+Nzero)+1:Ntotal)=0;
%%%%%%%%%%%%%%%^^^^^^^^^^^^^^^^wind
% 加窗处理
if(ig > 4)
InsertGIouta(ig,1:Ntotal)=InsertGIout(ig,1:Ntotal);
InsertGIout(ig,1:Ntotal)=InsertGIouta(ig,1:Ntotal).*wind;
end
%%%%%%%%%%%%%%^^^^^^^^^^^^^^^^^
FFTout_t(ig,1:Nfft)=fft(InsertGIout(ig,Ng+1-sita:Nfft+Ng-sita),Nfft); % 进行中间变量的测试
% 将生成的OFDM时域信号依次写入一个数组里,形成一个连续的OFDM时域数据流
for (is=1:Ntotal)
SoutI((ig-1)*Ntotal+is)=real(InsertGIout(ig,is));
SoutQ((ig-1)*Ntotal+is)=imag(InsertGIout(ig,is));
end;
end;
% 对生成的OFDM时域信号进行两倍上采样
% sample rate interpolation and modulation
for(k=1:Ns)
% HBF1
for j1=1:2
IHBF1in(2:LHBF1)=IHBF1in(1:LHBF1-1);
QHBF1in(2:LHBF1)=QHBF1in(1:LHBF1-1);
if (j1==1)
IHBF1in(1)=SoutI(k);
QHBF1in(1)=SoutQ(k);
else
IHBF1in(1)=0;
QHBF1in(1)=0;
end;
IHBF1out(k1)=2*IHBF1in*CHBF1;
QHBF1out(k1)=2*QHBF1in*CHBF1;
if (rem(k1,2*Ntotal)==0)
FFTout_t_1(t,1:2*Nfft)=fft(IHBF1out(k1-2*Nfft+1-sita1:k1-sita1),2*Nfft)+j*fft(QHBF1out(k1-2*Nfft+1-sita1:k1-sita1),2*Nfft);
t=t+1;
end;
k1=k1+1;
end;% end of j1
end; %end of k
% MODULATION
% 将基带信号转换成中频信号
M=2;
NN=length(IHBF1out);
phase0=pi/30;
error_f=0;
w=pi/M; % IF=8*(symbol rate) or (sample rate)/4
IMOD(1:NN)=0;
QMOD(1:NN)=0;
Modout(1:NN)=0;
for i=1:NN
IMOD(i)=cos(rem(i*w+phase0,2*pi))*IHBF1out(i);
QMOD(i)=-sin(rem(i*w+phase0,2*pi))*QHBF1out(i);
Modout(i)=IMOD(i)+QMOD(i);
end;
zB=20*log10(abs(fft(SoutI+j*SoutQ)));
zF=20*log10(abs(fft(Modout)));
% 记录基带信号的频谱情况
fid=fopen('SoutI_4_BF.txt','w');
fprintf(fid,'%d,',zB);
fclose(fid);
% 记录中频信号的频谱情况
fid=fopen('SoutI_4_IF.txt','w');
fprintf(fid,'%d,',zF);
fclose(fid);
% 观测时域信号
figure(1);
plot(SoutI(1:length(SoutI)));
figure(2);
plot(SoutQ(1:length(SoutQ)));
% 观察频域情况
figure(3);
plot(real(FFTout_t(1,1:Nfft)));
figure(4);
plot(20*log10(abs(fft(SoutI+j*SoutQ))));
figure(5);
plot(20*log10(abs(fft(IHBF1out+j*QHBF1out))));
figure(6);
plot(20*log10(abs(fft(Modout))));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -