OFDM原理及matlab代碼仿真

我也不明白OFDM是個咋回事

OFDM

一,OFDM的原理

OFDM(Orthogonal Frequency Division Multiplexing)即正交頻分複用技術,實際上OFDM是MCM(Multi Carrier Modulation),多載波調製的一種。經過頻分複用實現高速串行數據的並行傳輸, 它具備較好的抗多徑衰弱的能力,可以支持多用戶接入。dom

OFDM的主要思想是將信道分紅N個子信道。每一個子信道包含一個子載波,不一樣的子載波之間相互正交。實現時,將一路高速串行輸入的數據信號流轉換成N路並行的低速子數據流,調製到每一個子載波上進行傳輸。(相似於CDMA?)ide

那麼什麼是正交呢?性能

上圖給出了詳細的定義:兩個波形在一段時間內內積爲零,則他們在這段時間內正交。編碼

那平時咱們都知道sin(x)和cos(x)正交,他們在一個週期內的乘積爲0。spa

如圖sin和cos相乘,最後他們的乘積在一個週期內積分爲0,則sin和cos在這段時間內是正交的。那麼同理,sin(x)和sin(2x)呢?.net

從圖上能夠看到,sin(x)和sin(2x)的乘積在一個週期內的積分也爲零,因此sin(x)和sin(2x)在這段時間內也是正交的。3d

那如今咱們知道sin和cos是正交的,sin(x)和sin(2x)也是正交的。「OFDM的主要思想是將信道分紅N個子信道。每一個子信道包含一個子載波,不一樣的子載波之間相互正交。」,那麼在實現時將不一樣頻率的相互正交的信號進行調製,最後再加和發送(因此以爲和CMDA相似,不得不說通訊這裏正交纔是核心啊)。code

(上面的圖是從給"小白"圖示講解OFDM的原理上截的)orm

實現時,咱們先對不一樣的信道不一樣頻率的信號進行調製,再將其加和,很明顯這種清楚易懂的方法實現起來對硬件的要求比較高,因此咱們能不能找到一條更容易實現的方法。blog

博客園這個都不能寫公式的嗎.....

從上面能夠看出,將信號表示爲指數形式,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
相關文章
相關標籤/搜索