OFDM原理及matlab代码仿真

我也不明白OFDM是个咋回事

OFDM

一,OFDM的原理

OFDM(Orthogonal Frequency Division Multiplexing)即正交频分复用技术,实际上OFDM是MCM(Multi Carrier Modulation),多载波调制的一种。通过频分复用实现高速串行数据的并行传输, 它具有较好的抗多径衰弱的能力,能够支持多用户接入。

OFDM的主要思想是将信道分成N个子信道。每个子信道包含一个子载波,不同的子载波之间相互正交。实现时,将一路高速串行输入的数据信号流转换成N路并行的低速子数据流,调制到每个子载波上进行传输。(类似于CDMA?)

那么什么是正交呢?

上图给出了详细的定义:两个波形在一段时间内内积为零,则他们在这段时间内正交。

那平时我们都知道sin(x)和cos(x)正交,他们在一个周期内的乘积为0。

如图sin和cos相乘,最后他们的乘积在一个周期内积分为0,则sin和cos在这段时间内是正交的。那么同理,sin(x)和sin(2x)呢?

从图上可以看到,sin(x)和sin(2x)的乘积在一个周期内的积分也为零,所以sin(x)和sin(2x)在这段时间内也是正交的。

那现在我们知道sin和cos是正交的,sin(x)和sin(2x)也是正交的。“OFDM的主要思想是将信道分成N个子信道。每个子信道包含一个子载波,不同的子载波之间相互正交。”,那么在实现时将不同频率的相互正交的信号进行调制,最后再加和发送(所以觉得和CMDA类似,不得不说通信这里正交才是核心啊)。

(上面的图是从给"小白"图示讲解OFDM的原理上截的)

实现时,我们先对不同的信道不同频率的信号进行调制,再将其加和,很明显这种清楚易懂的方法实现起来对硬件的要求比较高,所以我们能不能找到一条更容易实现的方法。

博客园这个都不能写公式的吗.....

从上面可以看出,将信号表示为指数形式,OFDM就可以采用FFT进行调制,而现实中DSP芯片技术已经成熟,可以采用相较于加法器而言速度更快的数字芯片。

 

OFDM的一个简单的结构

 

数据先进行编码,可以信源编码,用来对数据进行压缩,信道编码提高数据传输的稳定性,克服无线信道多径问题(无线上路径损耗,多径,阴影衰落)。信道编码可以用RS编码,也可以采用卷积码,实际中采用比较多的是卷积码。

卷积码的结构

 

级联编码的结构,中间的交织器可以加也可以不加(个人看法,和仿真的数据参数有关,如果最后的仿真结果不是很理想可以考虑加交织器,我的结果是在我的数据条件下,加交织器降低误码率的能力很小,不到一个数量级,在修改参数后,交织器降低误码率的效果很明显,二到四个数量级)。

星座映射就是将数据映射到星座点上,对数据进行调制,2ASK,2PSK,QPSK等等。

 

    由于信道噪声的随机性和信道多径的影响,为了会恢复原始数据流,在接收端我们需要对信道进行估计,获得OFDM符号每一子载波上的绝对参考相位和幅值,以便准确无误地恢复原始数据比特。信道估计的准确性直接影响到整个OFDM系统的性能。这里我们通过插入导频来估计信道信息。

上面这一堆是插入导频法的原理,实际上就是无线信道在随时间变化,信道对不同频率的信号影响不同,我们要正确处理信号要知道信号实际的幅度和相位,就要求得信道对信号造成的幅度和相位变化,我们插入导频,导频是已知的一串数据,导频和数据一起发送,比如我们发送幅度为1相位为0的信号,接受端信号的幅度为0.5,相位为90度,我们就可以知道信号的幅度和相位变化。我们发送一串数据,中间在特定的频率处我们插入导频(也可以全频,先发送消息数据,再发送导频,假定信道变化为慢衰落),在接受端我们对特定频率处数据进行处理,有这几个位置的信道状况来推算整个信道的状况。

信道训练步骤

串并变化是因为我们OFDM信号为多路数据,需要将信号变为并联来进行IFFT,变换完后还要再变成串联符号才能发送。

IFFT就是IFFT......(草)

关于循环前缀,

由于现实的无线信道中存在多径现象,一束信号从发送端经过多条路径到达接收端,多条路径由于距离不同导致信号传播的时延不同。不同时延的信号叠加在一起会导致码元间的相互干扰。为了解决由多径引起的码间串扰的问题,我们可以增加码元时间,当码元时间远远大于信道的时延时,码间串扰对于码元判决的影响将大大减小,但随之而来的是使码元的传输速度降低。为了有效的降低码间串扰的影响同时尽可能的减少对码元自身传输速率的影响,我们可以在每个OFDM符号之间插入保护问隔,而且该保护间隔长度Ts一般要大于无线信道的最大时延扩展,这样一个符号的多径分量就不会对下一个符号造成干扰。

 关于上面这段话,

图上这个是个两径的信道,当两个符号之间没有间隔的话,两径加和,得不到原始的信号。想要消除两径的影响,就要在两个符号之间加上大于两条路径之间时延的间隔。

上图就是两个符号之间加上足够的间隔的情况,这时我们采样不会发生干扰,但是这么做也有问题,会破坏不同信道之间正交性。

图上可以看出,当俩个不同频率波之间差上一段为零的间隔后,他们的信号乘积积分在一个周期内不为零,破坏了正交性。(不同频率波加和成一个符号)就相当于原本正交的信号有了一个初始相位。

那咋办。。。。

循环前缀,将一个符号的一部分移到符号前。

从图上可以看出积分为0,正交性得到了保持,添加循环前缀解决了多径的问题。(一般移1/4到符号前)

二,代码实现

代码是探究了信道编码方式,分析在信噪比1到20的编码效果(看误码率)

   代码主体

clc
clear all
[error_bit_all(:,1),error_symbol_all(:,1)]=con_coding();
[error_bit_all(:,2),error_symbol_all(:,2)]=con_rs_coding();
[error_bit_all(:,3),error_symbol_all(:,3)]=rs_coding();
[error_bit_all(:,4),error_symbol_all(:,4)]=no_coding();
figure(2);
semilogy(1:20,error_bit_all(:,4),'r-^');
hold on
semilogy(1:20,error_bit_all(:,3),'r-s');
hold on
semilogy(1:20,error_bit_all(:,1),'g-s');
hold on
semilogy(1:20,error_bit_all(:,2),'g-^');
title('Comparison of RS coding and RS with Convolutional coding performance');
legend('no coding','RS coding','Convolutional coding(2,1,7)','Convolutional coding RS');
xlabel('SNR');
ylabel('BER');

  卷积编码部分

function [error_bit_all,error_symbol_all]=con__coding()
%31个子频
sonCarrierNum_temp=60;
symbols_Per_Carrier=1000;%每子载波含符号数/帧数
bits_Per_Symbol=1;%每符号含比特数
modulate_bit=2;%调制阶数(每个符号比特数)
% IFFT_bin_length=2^ceil(log2(sonCarrierNum_temp));%FFT点数
% PrefixRatio=1/4;%保护间隔与OFDM数据的比例 1/6~1/4
% pilot_Inter=1;%插入导频间隔
% CP=PrefixRatio*IFFT_bin_length ;%每一个OFDM符号添加的循环前缀长度为1/4*IFFT_bin_length
% CP=25;
% SNR=0:1:20; %信噪比dB
% nn=15;
% kk=11;
%-------------------------------信源输入----------------------------------------------
inforSource=randi([0,1],1,sonCarrierNum_temp*symbols_Per_Carrier*bits_Per_Symbol);
%---------------------------信道编码--------------------------------------------------
trellis = poly2trellis(7,[133 171]);    %(2,1,7)卷积编码 输入一位,输出两位,约束长度为7,1011011-->133//1111001-->171
source_coded_data_con=convenc(inforSource,trellis);
%----------------------------调制-----------------------------------------------------
data_temp1= reshape(source_coded_data_con,modulate_bit,[])';   %以每组2比特进行分组,输出两列数据
modulate_data=pskmod(bi2de(data_temp1),2^(modulate_bit),pi/4);%输出一列数据
%-------------------------插入导频----------------------------------------------
modulate_data=reshape(modulate_data,60,[]);
[modulate_wide,modulate_length]=size(modulate_data);
modulate_data_temp=[modulate_data(1:30,:);zeros(1,modulate_length);modulate_data(31:60,:)];%在原来输出数据的中间插0
h1=commsrc.pn('GenPoly', [1 0 0 0 0 1 1],'NumBitsOut',61*modulate_length,'InitialConditions',[0 0 0 0 0 1]);
pn_code_temp=generate(h1);
pn_code=2*pn_code_temp-1;
pn_code=reshape(pn_code,61,[]);
modulate_data_pn=zeros(61,2*modulate_length);
for i=1:modulate_length
    modulate_data_pn(:,(2*i-1))=modulate_data_temp(:,i);
    modulate_data_pn(:,2*i)=pn_code(:,i);
end
modulate_data_pn(62:64,:)=0;
modulate_data_pn_out=[modulate_data_pn(31:64,:);modulate_data_pn(1:30,:)];
%-----------------------------------ifft-------------------------------------
time_signal_ifft=ifft(modulate_data_pn_out);
%-----------------------------------cp---------------------------------------
time_signal_cp=[time_signal_ifft(39:64,:);time_signal_ifft(1:64,:)];%把ifft的末尾CP个数补充到最前面
[time_signal_cp_wide,time_signal_cp_length]=size(time_signal_cp);
%-------------------------------------并串变换-------------------------------------
for ii=1:modulate_length
    time_signal_out(:,ii)=[time_signal_cp(:,2*ii-1);time_signal_cp(:,2*ii)];
end
time_signal_out_1=reshape(time_signal_out,[],1);
% -----------------------------------信道----------------------------------------
for a=1:20
% chan=comm.RayleighChannel('SampleRate',550000, ...
%     'PathDelays',[0 2e-6],'AveragePathGains',[0 -3],'MaximumDopplerShift',100,'RandomStream','mt19937ar with seed','Seed',8007);
chan=comm.RayleighChannel('SampleRate',550000, ...
    'PathDelays',[0 2e-6],'AveragePathGains',[0 -3],'MaximumDopplerShift',100);
Rayleigh_signal=chan(time_signal_out_1);
awgn_signal=awgn( Rayleigh_signal,a,'measured');%添加高斯白噪声
%    awgn_signal=time_signal_out_1;
%------------------------------------串并转换----------------------------------
   receive_signal_serial=awgn_signal;
   receive_signal_perallel=reshape(receive_signal_serial,time_signal_cp_wide,[]);
%------------------------------------去循环前缀---------------------------------
   receive_data=receive_signal_perallel(27:90,:);
%-----------------------------------fft---------------------------------------
frequency_data_no_cp=fft(receive_data);
frequency_data=[frequency_data_no_cp(35:64,:);frequency_data_no_cp(1:31,:)];
[frequency_data_wide,frequency_data_length]=size(frequency_data);
%---------------------------------信道估计----------------------------------------
channel_condition=zeros(frequency_data_wide,modulate_length);
estimate_data=zeros(frequency_data_wide,modulate_length);
for iii=1:modulate_length
    channel_condition(:,iii)=frequency_data(:,2*iii)./pn_code(:,iii);
    estimate_data(:,iii)=frequency_data(:,(2*iii-1))./channel_condition(:,iii);
end
real_data_temp=[estimate_data(1:30,:);estimate_data(32:61,:)];
%---------------------------------------解调-----------------------------------------
demodulate_data_temp=reshape(real_data_temp,1,[]);
demodulate_data=pskdemod(demodulate_data_temp,2^(modulate_bit),pi/4);
demodulate_data_bits_temp=reshape(demodulate_data,[],1);
demodulate_data_bits=de2bi(demodulate_data_bits_temp);
real_data_temp1 = reshape(demodulate_data_bits',1,[]);
%--------------------------------------------译码-------------------------------------
trellis = poly2trellis(7,[133 171]);    %(2,1,7)卷积编码 输入一位,输出两位,约束长度为7,1011011-->133//1111001-->171
rx_decode=vitdec(real_data_temp1,trellis,35,'trunc','hard');   %硬判决
%-----------------------------------------------误码率----------------------------------
[error_num,error_ratio]=biterr(inforSource,rx_decode);
error_bit_all(a,1)=error_ratio;
%------------------------------------------------误符号率--------------------------------
error_symbol_data1= reshape(rx_decode,modulate_bit,[])';   %以每组2比特进行分组,输出两列数据
error_symbol_data_receive=bi2de(error_symbol_data1);
error_symbol_data2= reshape(inforSource,modulate_bit,[])';   %以每组2比特进行分组,输出两列数据
error_symbol_data_transmite=bi2de(error_symbol_data2);%输出一列数据
[error_symbol_num,error_symbol_ratio]=symerr(error_symbol_data_receive,error_symbol_data_transmite);
error_symbol_all(a,1)=error_symbol_ratio;
end
end

  

  RS编码

function [error_bit_all,error_symbol_all]=rs_coding()
sonCarrierNum_temp=88;
symbols_Per_Carrier=1000;%每子载波含符号数/帧数
bits_Per_Symbol=1;%每符号含比特数
modulate_bit=2;%调制阶数(每个符号比特数)
nn=15;
kk=11;
%-------------------------------信源输入----------------------------------------------
inforSource=randi([0,1],1,sonCarrierNum_temp*symbols_Per_Carrier*bits_Per_Symbol);
%---------------------------信道编码--------------------------------------------------
msg4_temp=reshape(inforSource,4,[])';
msg4=bi2de(msg4_temp,'left-msb');%将原来的数据转换为4位16进制
msg4_togf=reshape(msg4,kk,[]).'; %带转换的矩阵,十一输入
msgGF=gf(msg4_togf,4);%转换为伽罗华域
msgrs=rsenc(msgGF,nn,kk); %(15,11)RS编码 11个输入 15个输出
msgrs1=reshape(msgrs.',1,length(msg4)/kk*nn);%将rs编码输出转成一行
msgrs2=de2bi(double(msgrs1.x),'left-msb');%十进制转二进制
source_coded_data_rs=reshape(msgrs2',1,length(msg4)/kk*nn*4);%待调制信号 输出一行信号(数据)
st2 = 4831;
inter_rs_code = randintrlv(source_coded_data_rs,st2); % Interleave.
%----------------------------调制-----------------------------------------------------
data_temp1= reshape(inter_rs_code,modulate_bit,[])';   %以每组2比特进行分组,输出两列数据
modulate_data=pskmod(bi2de(data_temp1),2^(modulate_bit),pi/4);%输出一列数据
%-------------------------信道训练----------------------------------------------
modulate_data=reshape(modulate_data,60,[]);
[modulate_wide,modulate_length]=size(modulate_data);
modulate_data_temp=[modulate_data(1:30,:);zeros(1,modulate_length);modulate_data(31:60,:)];%在原来输出数据的中间插0
h1=commsrc.pn('GenPoly', [1 0 0 0 0 1 1],'NumBitsOut',61*modulate_length,'InitialConditions',[0 0 0 0 0 1]);
pn_code_temp=generate(h1);
pn_code=2*pn_code_temp-1;
pn_code=reshape(pn_code,61,[]);
modulate_data_pn=zeros(61,2*modulate_length);
for i=1:modulate_length
    modulate_data_pn(:,(2*i-1))=modulate_data_temp(:,i);
    modulate_data_pn(:,2*i)=pn_code(:,i);
end
modulate_data_pn(62:64,:)=0;
modulate_data_pn_out=[modulate_data_pn(31:64,:);modulate_data_pn(1:30,:)];
%-----------------------------------ifft-------------------------------------
time_signal_ifft=ifft(modulate_data_pn_out);
%-----------------------------------cp---------------------------------------
time_signal_cp=[time_signal_ifft(39:64,:);time_signal_ifft(1:64,:)];%把ifft的末尾CP个数补充到最前面
[time_signal_cp_wide,time_signal_cp_length]=size(time_signal_cp);
%-------------------------------------并串变换-------------------------------------
for ii=1:modulate_length
    time_signal_out(:,ii)=[time_signal_cp(:,2*ii-1);time_signal_cp(:,2*ii)];
end
time_signal_out_1=reshape(time_signal_out,[],1);
for a=1:20
% -----------------------------------信道----------------------------------------
% chan=comm.RayleighChannel('SampleRate',550000, ...
%     'PathDelays',[0 2e-6],'AveragePathGains',[0 -3],'MaximumDopplerShift',100,'RandomStream','mt19937ar with seed','Seed',8007);
chan=comm.RayleighChannel('SampleRate',550000, ...
    'PathDelays',[0 2e-6],'AveragePathGains',[0 -3],'MaximumDopplerShift',100);
Rayleigh_signal=chan(time_signal_out_1);
awgn_signal=awgn( Rayleigh_signal,a,'measured');%添加高斯白噪声
%   awgn_signal=time_signal_out_1;
%------------------------------------串并转换----------------------------------
   receive_signal_serial=awgn_signal;
   receive_signal_perallel=reshape(receive_signal_serial,time_signal_cp_wide,[]);
%------------------------------------去循环前缀---------------------------------
   receive_data=receive_signal_perallel(27:90,:);
%-----------------------------------fft---------------------------------------
frequency_data_no_cp=fft(receive_data);
frequency_data=[frequency_data_no_cp(35:64,:);frequency_data_no_cp(1:31,:)];
[frequency_data_wide,frequency_data_length]=size(frequency_data);
%---------------------------------信道估计----------------------------------------
channel_condition=zeros(frequency_data_wide,modulate_length);
estimate_data=zeros(frequency_data_wide,modulate_length);
for iii=1:modulate_length
    channel_condition(:,iii)=frequency_data(:,2*iii)./pn_code(:,iii);
    estimate_data(:,iii)=frequency_data(:,(2*iii-1))./channel_condition(:,iii);
end
real_data_temp=[estimate_data(1:30,:);estimate_data(32:61,:)];
%---------------------------------------解调-----------------------------------------
demodulate_data_temp=reshape(real_data_temp,1,[]);
demodulate_data=pskdemod(demodulate_data_temp,2^(modulate_bit),pi/4);
demodulate_data_bits_temp=reshape(demodulate_data,[],1);
demodulate_data_bits=de2bi(demodulate_data_bits_temp);
real_data_temp1 = reshape(demodulate_data_bits',1,[]);
%--------------------------------------------译码-------------------------------------
deinter_con = randdeintrlv(real_data_temp1,st2); % Deinterleave.
[real_data_temp1_wide,real_data_length]=size(deinter_con);
yrsgs4=reshape(deinter_con ,4,real_data_temp1_wide*real_data_length/4).';
yrsgs41=bi2de(yrsgs4,'left-msb');
yrsgs41=reshape(yrsgs41,nn,length(yrsgs41)/nn).';
ygsrsdecode=rsdec(gf(yrsgs41,4),nn,kk);
d1=reshape(ygsrsdecode.x',1,[]);
d2=de2bi(d1,'left-msb').';
rx_decode=reshape(d2,1,[]);
%-----------------------------------------------误码率----------------------------------
[error_num,error_ratio]=biterr(inforSource,rx_decode);
error_bit_all(a,1)=error_ratio;
%------------------------------------------------误符号率--------------------------------
error_symbol_data1= reshape(rx_decode,modulate_bit,[])';   %以每组2比特进行分组,输出两列数据
error_symbol_data_receive=bi2de(error_symbol_data1);
error_symbol_data2= reshape(inforSource,modulate_bit,[])';   %以每组2比特进行分组,输出两列数据
error_symbol_data_transmite=bi2de(error_symbol_data2);%输出一列数据
[error_symbol_num,error_symbol_ratio]=symerr(error_symbol_data_receive,error_symbol_data_transmite);
error_symbol_all(a,1)=error_symbol_ratio;
end
end

  

  级联编码

function [error_bit_all,error_symbol_all]=con_rs_coding()
sonCarrierNum_temp=44;
bits_Per_Symbol=1;%每符号含比特数
symbols_Per_Carrier=1000;%每子载波含符号数/帧数
modulate_bit=2;%调制阶数(每个符号比特数)
% IFFT_bin_length=2^ceil(log2(sonCarrierNum_temp));%FFT点数
% PrefixRatio=1/4;%保护间隔与OFDM数据的比例 1/6~1/4
% pilot_Inter=1;%插入导频间隔
% CP=PrefixRatio*IFFT_bin_length ;%每一个OFDM符号添加的循环前缀长度为1/4*IFFT_bin_length
CP=25;
SNR=0:1:20; %信噪比dB
nn=15;
kk=11;
%-------------------------------信源输入----------------------------------------------
inforSource=randi([0,1],1,sonCarrierNum_temp*symbols_Per_Carrier*bits_Per_Symbol);
%---------------------------信道编码--------------------------------------------------
msg4_temp=reshape(inforSource,4,[])';
msg4=bi2de(msg4_temp,'left-msb');%将原来的数据转换为4位16进制
msg4_togf=reshape(msg4,kk,[]).'; %带转换的矩阵,十一输入
msgGF=gf(msg4_togf,4);%转换为伽罗华域
msgrs=rsenc(msgGF,nn,kk); %(15,11)RS编码 11个输入 15个输出
msgrs1=reshape(msgrs.',1,length(msg4)/kk*nn);%将rs编码输出转成一行
msgrs2=de2bi(double(msgrs1.x),'left-msb');%十进制转二进制
source_coded_data_rs=reshape(msgrs2',1,length(msg4)/kk*nn*4);%待调制信号 输出一行信号(数据)
% st2 = 4831;
% inter_rs_code = randintrlv(source_coded_data_rs,st2); % Interleave.
trellis = poly2trellis(7,[133 171]);    %(2,1,7)卷积编码 输入一位,输出两位,约束长度为7,1011011-->133//1111001-->171
source_coded_data_con=convenc(source_coded_data_rs,trellis);
%----------------------------调制-----------------------------------------------------
data_temp1= reshape(source_coded_data_con,modulate_bit,[])';   %以每组2比特进行分组,输出两列数据
modulate_data=pskmod(bi2de(data_temp1),2^(modulate_bit),pi/4);%输出一列数据
%-------------------------插入导频----------------------------------------------
modulate_data=reshape(modulate_data,60,[]);
[modulate_wide,modulate_length]=size(modulate_data);
modulate_data_temp=[modulate_data(1:30,:);zeros(1,modulate_length);modulate_data(31:60,:)];%在原来输出数据的中间插0
h1=commsrc.pn('GenPoly', [1 0 0 0 0 1 1],'NumBitsOut',61*modulate_length,'InitialConditions',[0 0 0 0 0 1]);
pn_code_temp=generate(h1);
pn_code=2*pn_code_temp-1;
pn_code=reshape(pn_code,61,[]);
modulate_data_pn=zeros(61,2*modulate_length);
for i=1:modulate_length
    modulate_data_pn(:,(2*i-1))=modulate_data_temp(:,i);
    modulate_data_pn(:,2*i)=pn_code(:,i);
end
modulate_data_pn(62:64,:)=0;
modulate_data_pn_out=[modulate_data_pn(31:64,:);modulate_data_pn(1:30,:)];
%-----------------------------------ifft-------------------------------------
time_signal_ifft=ifft(modulate_data_pn_out);
%-----------------------------------cp---------------------------------------
time_signal_cp=[time_signal_ifft(39:64,:);time_signal_ifft(1:64,:)];%把ifft的末尾CP个数补充到最前面
[time_signal_cp_wide,time_signal_cp_length]=size(time_signal_cp);
%-------------------------------------并串变换-------------------------------------
for ii=1:modulate_length
    time_signal_out(:,ii)=[time_signal_cp(:,2*ii-1);time_signal_cp(:,2*ii)];
end
time_signal_out_1=reshape(time_signal_out,[],1);
for a=1:20
% -----------------------------------信道----------------------------------------
% chan=comm.RayleighChannel('SampleRate',550000, ...
%     'PathDelays',[0 2e-6],'AveragePathGains',[0 -3],'MaximumDopplerShift',100,'RandomStream','mt19937ar with seed','Seed',8007);
chan=comm.RayleighChannel('SampleRate',550000, ...
    'PathDelays',[0 2e-6],'AveragePathGains',[0 -3],'MaximumDopplerShift',100);
Rayleigh_signal=chan(time_signal_out_1);
awgn_signal=awgn( Rayleigh_signal,a,'measured');%添加高斯白噪声
%    awgn_signal=time_signal_out_1;
%------------------------------------串并转换----------------------------------
   receive_signal_serial=awgn_signal;
   receive_signal_perallel=reshape(receive_signal_serial,time_signal_cp_wide,[]);
%------------------------------------去循环前缀---------------------------------
   receive_data=receive_signal_perallel(27:90,:);
%-----------------------------------fft---------------------------------------
frequency_data_no_cp=fft(receive_data);
frequency_data=[frequency_data_no_cp(35:64,:);frequency_data_no_cp(1:31,:)];
[frequency_data_wide,frequency_data_length]=size(frequency_data);
%---------------------------------信道估计----------------------------------------
channel_condition=zeros(frequency_data_wide,modulate_length);
estimate_data=zeros(frequency_data_wide,modulate_length);
for iii=1:modulate_length
    channel_condition(:,iii)=frequency_data(:,2*iii)./pn_code(:,iii);
    estimate_data(:,iii)=frequency_data(:,(2*iii-1))./channel_condition(:,iii);
end
real_data_temp=[estimate_data(1:30,:);estimate_data(32:61,:)];
%---------------------------------------解调-----------------------------------------
demodulate_data_temp=reshape(real_data_temp,1,[]);
demodulate_data=pskdemod(demodulate_data_temp,2^(modulate_bit),pi/4);
demodulate_data_bits_temp=reshape(demodulate_data,[],1);
demodulate_data_bits=de2bi(demodulate_data_bits_temp);
real_data_temp1 = reshape(demodulate_data_bits',1,[]);
%--------------------------------------------译码-------------------------------------
trellis = poly2trellis(7,[133 171]);    %(2,1,7)卷积编码 输入一位,输出两位,约束长度为7,1011011-->133//1111001-->171
decode_con=vitdec(real_data_temp1,trellis,34,'trunc','hard');   %硬判决
% deinter_con = randdeintrlv(decode_con,st2); % Deinterleave.
[real_data_temp1_wide,real_data_length]=size(decode_con);
yrsgs4=reshape(decode_con ,4,real_data_temp1_wide*real_data_length/4).';
yrsgs41=bi2de(yrsgs4,'left-msb');
yrsgs41=reshape(yrsgs41,nn,length(yrsgs41)/nn).';
ygsrsdecode=rsdec(gf(yrsgs41,4),nn,kk);
d1=reshape(ygsrsdecode.x',1,[]);
d2=de2bi(d1,'left-msb').';
rx_decode=reshape(d2,1,[]);
%-----------------------------------------------误码率----------------------------------
[error_num,error_ratio]=biterr(inforSource,rx_decode);
error_bit_all(a,1)=error_ratio;
%------------------------------------------------误符号率--------------------------------
error_symbol_data1= reshape(rx_decode,modulate_bit,[])';   %以每组2比特进行分组,输出两列数据
error_symbol_data_receive=bi2de(error_symbol_data1);
error_symbol_data2= reshape(inforSource,modulate_bit,[])';   %以每组2比特进行分组,输出两列数据
error_symbol_data_transmite=bi2de(error_symbol_data2);%输出一列数据
[error_symbol_num,error_symbol_ratio]=symerr(error_symbol_data_receive,error_symbol_data_transmite);
error_symbol_all(a,1)=error_symbol_ratio;
end

  

  无编码

function [error_bit_all,error_symbol_all]=no_coding()
sonCarrierNum_temp=120;
symbols_Per_Carrier=1000;%每子载波含符号数/帧数
bits_Per_Symbol=1;%每符号含比特数
modulate_bit=2;%调制阶数(每个符号比特数)
CP=25;
SNR=0:1:20; %信噪比dB
nn=15;
kk=11;
%-------------------------------信源输入----------------------------------------------
inforSource=randi([0,1],1,sonCarrierNum_temp*symbols_Per_Carrier*bits_Per_Symbol);
%---------------------------信道编码--------------------------------------------------
% msg4_temp=reshape(inforSource,4,[])';
% msg4=bi2de(msg4_temp,'left-msb');%将原来的数据转换为4位16进制
% msg4_togf=reshape(msg4,kk,[]).'; %带转换的矩阵,十一输入
% msgGF=gf(msg4_togf,4);%转换为伽罗华域
% msgrs=rsenc(msgGF,nn,kk); %(15,11)RS编码 11个输入 15个输出
% msgrs1=reshape(msgrs.',1,length(msg4)/kk*nn);%将rs编码输出转成一行
% msgrs2=de2bi(double(msgrs1.x),'left-msb');%十进制转二进制
% source_coded_data_rs=reshape(msgrs2',1,length(msg4)/kk*nn*4);%待调制信号 输出一行信号(数据)
% st2 = 4831;
% inter_rs_code = randintrlv(source_coded_data_rs,st2); % Interleave.
% trellis = poly2trellis(7,[133 171]);    %(2,1,7)卷积编码 输入一位,输出两位,约束长度为7,1011011-->133//1111001-->171
% source_coded_data_con=convenc(inter_rs_code,trellis);
source_coded_data_con=inforSource;
%----------------------------调制-----------------------------------------------------
data_temp1= reshape(source_coded_data_con,modulate_bit,[])';   %以每组2比特进行分组,输出两列数据
modulate_data=pskmod(bi2de(data_temp1),2^(modulate_bit),pi/4);%输出一列数据
%-------------------------插入导频----------------------------------------------
modulate_data=reshape(modulate_data,60,[]);
[modulate_wide,modulate_length]=size(modulate_data);
modulate_data_temp=[modulate_data(1:30,:);zeros(1,modulate_length);modulate_data(31:60,:)];%在原来输出数据的中间插0
h1=commsrc.pn('GenPoly', [1 0 0 0 0 1 1],'NumBitsOut',61*modulate_length,'InitialConditions',[0 0 0 0 0 1]);
pn_code_temp=generate(h1);
pn_code=2*pn_code_temp-1;
pn_code=reshape(pn_code,61,[]);
modulate_data_pn=zeros(61,2*modulate_length);
for i=1:modulate_length
    modulate_data_pn(:,(2*i-1))=modulate_data_temp(:,i);
    modulate_data_pn(:,2*i)=pn_code(:,i);
end
modulate_data_pn(62:64,:)=0;
modulate_data_pn_out=[modulate_data_pn(31:64,:);modulate_data_pn(1:30,:)];
%-----------------------------------ifft-------------------------------------
time_signal_ifft=ifft(modulate_data_pn_out);
%-----------------------------------cp---------------------------------------
time_signal_cp=[time_signal_ifft(39:64,:);time_signal_ifft(1:64,:)];%把ifft的末尾CP个数补充到最前面
[time_signal_cp_wide,time_signal_cp_length]=size(time_signal_cp);
%-------------------------------------并串变换-------------------------------------
for ii=1:modulate_length
    time_signal_out(:,ii)=[time_signal_cp(:,2*ii-1);time_signal_cp(:,2*ii)];
end
time_signal_out_1=reshape(time_signal_out,[],1);
for a=1:20
% -----------------------------------信道----------------------------------------
% chan=comm.RayleighChannel('SampleRate',550000, ...
%     'PathDelays',[0 2e-6],'AveragePathGains',[0 -3],'MaximumDopplerShift',100,'RandomStream','mt19937ar with seed','Seed',8007);
chan=comm.RayleighChannel('SampleRate',550000, ...
    'PathDelays',[0 2e-6],'AveragePathGains',[0 -3],'MaximumDopplerShift',100);
Rayleigh_signal=chan(time_signal_out_1);
awgn_signal=awgn( Rayleigh_signal,a,'measured');%添加高斯白噪声
%    awgn_signal=time_signal_out_1;
%------------------------------------串并转换----------------------------------
   receive_signal_serial=awgn_signal;
   receive_signal_perallel=reshape(receive_signal_serial,time_signal_cp_wide,[]);
%------------------------------------去循环前缀---------------------------------
   receive_data=receive_signal_perallel(27:90,:);
%-----------------------------------fft---------------------------------------
frequency_data_no_cp=fft(receive_data);
frequency_data=[frequency_data_no_cp(35:64,:);frequency_data_no_cp(1:31,:)];
[frequency_data_wide,frequency_data_length]=size(frequency_data);
%---------------------------------信道估计----------------------------------------
channel_condition=zeros(frequency_data_wide,modulate_length);
estimate_data=zeros(frequency_data_wide,modulate_length);
for iii=1:modulate_length
    channel_condition(:,iii)=frequency_data(:,2*iii)./pn_code(:,iii);
    estimate_data(:,iii)=frequency_data(:,(2*iii-1))./channel_condition(:,iii);
end
real_data_temp=[estimate_data(1:30,:);estimate_data(32:61,:)];
%---------------------------------------解调-----------------------------------------
demodulate_data_temp=reshape(real_data_temp,1,[]);
demodulate_data=pskdemod(demodulate_data_temp,2^(modulate_bit),pi/4);
demodulate_data_bits_temp=reshape(demodulate_data,[],1);
demodulate_data_bits=de2bi(demodulate_data_bits_temp);
real_data_temp1 = reshape(demodulate_data_bits',1,[]);
%--------------------------------------------译码-------------------------------------
% trellis = poly2trellis(7,[133 171]);    %(2,1,7)卷积编码 输入一位,输出两位,约束长度为7,1011011-->133//1111001-->171
% decode_con=vitdec(real_data_temp1,trellis,34,'trunc','hard');   %硬判决
% deinter_con = randdeintrlv(decode_con,st2); % Deinterleave.
% [real_data_temp1_wide,real_data_length]=size(deinter_con);
% yrsgs4=reshape(deinter_con ,4,real_data_temp1_wide*real_data_length/4).';
% yrsgs41=bi2de(yrsgs4,'left-msb');
% yrsgs41=reshape(yrsgs41,nn,length(yrsgs41)/nn).';
% ygsrsdecode=rsdec(gf(yrsgs41,4),nn,kk);
% d1=reshape(ygsrsdecode.x',1,[]);
% d2=de2bi(d1,'left-msb').';
% rx_decode=reshape(d2,1,[]);
rx_decode=real_data_temp1;
%-----------------------------------------------误码率----------------------------------
[error_num,error_ratio]=biterr(inforSource,rx_decode);
error_bit_all(a,1)=error_ratio;
%------------------------------------------------误符号率--------------------------------
error_symbol_data1= reshape(rx_decode,modulate_bit,[])';   %以每组2比特进行分组,输出两列数据
error_symbol_data_receive=bi2de(error_symbol_data1);
error_symbol_data2= reshape(inforSource,modulate_bit,[])';   %以每组2比特进行分组,输出两列数据
error_symbol_data_transmite=bi2de(error_symbol_data2);%输出一列数据
[error_symbol_num,error_symbol_ratio]=symerr(error_symbol_data_receive,error_symbol_data_transmite);
error_symbol_all(a,1)=error_symbol_ratio;
end

  

posted @ 2019-07-29 15:47  孤独野猪骑士  阅读(12896)  评论(19编辑  收藏  举报