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

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM