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

📄 ofdm_mod.m

📁 OFDM仿真程序MATLAB 接收端采用的算法和程序流程与发送端发送的OFDM符号的帧结构有关系。具体的帧结构
💻 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 + -