OFDM技术仿真MATLAB代码
(完整版)OFDMmatlab实现
![(完整版)OFDMmatlab实现](https://img.taocdn.com/s3/m/d34ffb804a7302768f993940.png)
close all;carrier_count=200;%子载波数symbols_per_carrier=12;%每子载波含符号数bits_per_symbol=4;%每符号含比特数,16QAM调制IFFT_bin_length=512;%FFT点数PrefixRatio=1/4;%保护间隔与OFDM数据的比例1/6~1/4GI=PrefixRatio*IFFT_bin_length ;%每一个OFDM符号添加的循环前缀长度为1/4*IFFT_bin_length 即保护间隔长度为128beta=1/32;%窗函数滚降系数GIP=beta*(IFFT_bin_length+GI);%循环后缀的长度20SNR=15; %信噪比dB%==================================================%================信号产生=================================== baseband_out_length = carrier_count * symbols_per_carrier * bits_per_symbol;%所输入的比特数目carriers = (1:carrier_count) + (floor(IFFT_bin_length/4) - floor(carrier_count/2));%共轭对称子载波映射复数数据对应的IFFT点坐标conjugate_carriers = IFFT_bin_length - carriers + 2;%共轭对称子载波映射共轭复数对应的IFFT点坐标rand( 'state',0);baseband_out=round(rand(1,baseband_out_length));%输出待调制的二进制比特流%==============16QAM调制====================================complex_carrier_matrix=qam16(baseband_out);%列向量complex_carrier_matrix=reshape(complex_carrier_matrix',carrier_count,symbols_per_car rier)';%symbols_per_carrier*carrier_count 矩阵figure(1);plot(complex_carrier_matrix,'*r');%16QAM调制后星座图axis([-4, 4, -4, 4]);grid on%=================IFFT===========================IFFT_modulation=zeros(symbols_per_carrier,IFFT_bin_length);%添0组成IFFT_bin_length IFFT 运算IFFT_modulation(:,carriers ) = complex_carrier_matrix ;%未添加导频信号,子载波映射在此处IFFT_modulation(:,conjugate_carriers ) = conj(complex_carrier_matrix);%共轭复数映射%========================================================stem(0:IFFT_bin_length-1, abs(IFFT_modulation(2,1:IFFT_bin_length)),'b*-')%第一个OFDM符号的频谱grid onaxis ([0 IFFT_bin_length -0.5 4.5]);ylabel('Magnitude');xlabel('IFFT Bin');title('OFDM Carrier Frequency Magnitude');figure(3);plot(0:IFFT_bin_length-1, (180/pi)*angle(IFFT_modulation(2,1:IFFT_bin_length)), 'go') hold onstem(0:carriers-1, (180/pi)*angle(IFFT_modulation(2,1:carriers)),'b*-');%第一个OFDM符号的相位stem(0:conjugate_carriers-1,(180/pi)*angle(IFFT_modulation(2,1:conjugate_carriers)),'b*-');axis ([0 IFFT_bin_length -200 +200])grid onylabel('Phase (degrees)')xlabel('IFFT Bin')title('OFDM Carrier Phase')%================================================================= signal_after_IFFT=ifft(IFFT_modulation,IFFT_bin_length,2);%OFDM调制即IFFT变换time_wave_matrix =signal_after_IFFT;%时域波形矩阵,行为每载波所含符号数,列ITTF 点数,N个子载波映射在其内,每一行即为一个OFDM符号figure(4);subplot(3,1,1);plot(0:IFFT_bin_length-1,time_wave_matrix(2,:));%第一个符号的波形axis([0, 700, -0.2, 0.2]);grid on;ylabel('Amplitude');xlabel('Time');title('OFDM Time Signal, One Symbol Period');%===========================================================%=====================添加循环前缀与后缀====================================XX=zeros(symbols_per_carrier,IFFT_bin_length+GI+GIP);for k=1:symbols_per_carrier;for i=1:IFFT_bin_length;XX(k,i+GI)=signal_after_IFFT(k,i);endfor i=1:GI;XX(k,i)=signal_after_IFFT(k,i+IFFT_bin_length-GI);%添加循环前缀endfor j=1:GIP;XX(k,IFFT_bin_length+GI+j)=signal_after_IFFT(k,j);%添加循环后缀endendtime_wave_matrix_cp=XX;%添加了循环前缀与后缀的时域信号矩阵,此时一个OFDM符号长度为IFFT_bin_length+GI+GIP=660subplot(3,1,2);plot(0:length(time_wave_matrix_cp)-1,time_wave_matrix_cp(2,:));%第一个符号添加循环前缀后的波形axis([0, 700, -0.2, 0.2]);grid on;ylabel('Amplitude');xlabel('Time');title('OFDM Time Signal with CP, One Symbol Period');%==============OFDM符号加窗==========================================windowed_time_wave_matrix_cp=zeros(1,IFFT_bin_length+GI+GIP);for i = 1:symbols_per_carrierwindowed_time_wave_matrix_cp(i,:) =real(time_wave_matrix_cp(i,:)).*rcoswindow(beta,IFFT_bin_length+GI)';%加窗升余弦窗endsubplot(3,1,3);plot(0:IFFT_bin_length-1+GI+GIP,windowed_time_wave_matrix_cp(2,:));%第一个符号的波形axis([0, 700, -0.2, 0.2]);grid on;ylabel('Amplitude');xlabel('Time');title('OFDM Time Signal Apply a Window , One Symbol Period');%========================生成发送信号,并串变换==================================================windowed_Tx_data=zeros(1,symbols_per_carrier*(IFFT_bin_length+GI)+GIP); windowed_Tx_data(1:IFFT_bin_length+GI+GIP)=windowed_time_wave_matrix_cp(1,:); for i = 1:symbols_per_carrier-1 ;windowed_Tx_data((IFFT_bin_length+GI)*i+1:(IFFT_bin_length+GI)*(i+1)+GIP)=window ed_time_wave_matrix_cp(i+1,:);%并串转换,循环后缀与循环前缀相叠加end%=======================================================Tx_data_withoutwindow=reshape(time_wave_matrix_cp',(symbols_per_carrier)*(IFFT_bin_length+GI+GIP),1)';%没有加窗,只添加循环前缀与后缀的串行信号Tx_data=reshape(windowed_time_wave_matrix_cp',(symbols_per_carrier)*(IFFT_bin_length+GI +GIP),1)';%加窗后循环前缀与后缀不叠加的串行信号%================================================================= temp_time1 = (symbols_per_carrier)*(IFFT_bin_length+GI+GIP);%加窗后循环前缀与后缀不叠加发送总位数figure (5)subplot(2,1,1);plot(0:temp_time1-1,Tx_data );%循环前缀与后缀不叠加发送的信号波形grid onylabel('Amplitude (volts)')xlabel('Time (samples)')title('OFDM Time Signal')temp_time2 =symbols_per_carrier*(IFFT_bin_length+GI)+GIP;subplot(2,1,2);plot(0:temp_time2-1,windowed_Tx_data);%循环后缀与循环前缀相叠加发送信号波形grid onylabel('Amplitude (volts)')xlabel('Time (samples)')title('OFDM Time Signal')%=================未加窗发送信号频谱==================================symbols_per_average = ceil(symbols_per_carrier/5);%符号数的1/5,10行avg_temp_time = (IFFT_bin_length+GI+GIP)*symbols_per_average;%点数,10行数据,10个符号averages = floor(temp_time1/avg_temp_time);average_fft(1:avg_temp_time) = 0;%分成5段for a = 0:(averages-1)subset_ofdm = Tx_data_withoutwindow(((a*avg_temp_time)+1):((a+1)*avg_temp_time));%subset_ofdm_f = abs(fft(subset_ofdm));%将发送信号分段求频谱average_fft = average_fft + (subset_ofdm_f/averages);%总共的数据分为5段,分段进行FFT,平均相加endaverage_fft_log = 20*log10(average_fft);figure (6)subplot(2,1,1);plot((0:(avg_temp_time-1))/avg_temp_time, average_fft_log)%归一化0/avg_temp_time : (avg_temp_time-1)/avg_temp_timehold onplot(0:1/IFFT_bin_length:1, -35, 'rd')grid onaxis([0 0.5 -40 max(average_fft_log)])ylabel('Magnitude (dB)')xlabel('Normalized Frequency (0.5 = fs/2)')title('OFDM Signal Spectrum without windowing')%===============加窗的发送信号频谱================================= symbols_per_average = ceil(symbols_per_carrier/5);%符号数的1/5,10行avg_temp_time = (IFFT_bin_length+GI+GIP)*symbols_per_average;%点数,10行数据,10个符号averages = floor(temp_time1/avg_temp_time);average_fft(1:avg_temp_time) = 0;%分成5段for a = 0:(averages-1)subset_ofdm = Tx_data(((a*avg_temp_time)+1):((a+1)*avg_temp_time));%利用循环前缀后缀未叠加的串行加窗信号计算频谱subset_ofdm_f = abs(fft(subset_ofdm));%分段求频谱average_fft = average_fft + (subset_ofdm_f/averages);%总共的数据分为5段,分段进行FFT,平均相加endaverage_fft_log = 20*log10(average_fft);subplot(2,1,2)plot((0:(avg_temp_time-1))/avg_temp_time, average_fft_log)%归一化0/avg_temp_time : (avg_temp_time-1)/avg_temp_timehold onplot(0:1/IFFT_bin_length:1, -35, 'rd')grid onaxis([0 0.5 -40 max(average_fft_log)])ylabel('Magnitude (dB)')xlabel('Normalized Frequency (0.5 = fs/2)')title('Windowed OFDM Signal Spectrum')%====================添加噪声============================================Tx_signal_power = var(windowed_Tx_data);%发送信号功率linear_SNR=10^(SNR/10);%线性信噪比noise_sigma=Tx_signal_power/linear_SNR;noise_scale_factor = sqrt(noise_sigma);%标准差sigmanoise=randn(1,((symbols_per_carrier)*(IFFT_bin_length+GI))+GIP)*noise_scale_factor; %产生正态分布噪声序列%noise=wgn(1,length(windowed_Tx_data),noise_sigma,'complex');%产生复GAUSS白噪声信号Rx_data=windowed_Tx_data +noise;%接收到的信号加噪声%=====================接收信号串/并变换去除前缀与后缀==========================================Rx_data_matrix=zeros(symbols_per_carrier,IFFT_bin_length+GI+GIP);for i=1:symbols_per_carrier;Rx_data_matrix(i,:)=Rx_data(1,(i-1)*(IFFT_bin_length+GI)+1:i*(IFFT_bin_length+GI)+GI P);%串并变换endRx_data_complex_matrix=Rx_data_matrix(:,GI+1:IFFT_bin_length+GI);%去除循环前缀与循环后缀,得到有用信号矩阵%============================================================%==== ============================================================%==============================================================% OFDM解码16QAM解码%=================FFT变换=================================Y1=fft(Rx_data_complex_matrix,IFFT_bin_length,2);%OFDM解码即FFT变换Rx_carriers=Y1(:,carriers);%除去IFFT/FFT变换添加的0,选出映射的子载波Rx_phase =angle(Rx_carriers);%接收信号的相位Rx_mag = abs(Rx_carriers);%接收信号的幅度figure(7);polar(Rx_phase, Rx_mag,'bd');%极坐标坐标下画出接收信号的星座图%================================================================== ====[M, N]=pol2cart(Rx_phase, Rx_mag);Rx_complex_carrier_matrix = complex(M, N);figure(8);plot(Rx_complex_carrier_matrix,'*r');%XY坐标接收信号的星座图axis([-4, 4, -4, 4]);grid on%====================16qam解调==================================================Rx_serial_complex_symbols =reshape(Rx_complex_carrier_matrix',size(Rx_complex_carrier_matrix,1)*size(Rx_complex_carrier_matrix,2),1)' ;Rx_decoded_binary_symbols=demoduqam16(Rx_serial_complex_symbols);%============================================================ baseband_in = Rx_decoded_binary_symbols;figure(9);subplot(2,1,1);stem(baseband_out(1:100));subplot(2,1,2);stem(baseband_in(1:100));%================误码率计算=============================================bit_errors=find(baseband_in ~=baseband_out);bit_error_count = size(bit_errors, 2)ber=bit_error_count/baseband_out_length。
OFDM原理及matlab代码仿真
![OFDM原理及matlab代码仿真](https://img.taocdn.com/s3/m/695cba2c182e453610661ed9ad51f01dc28157d8.png)
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就可以采⽤FFT进⾏调制,⽽现实中DSP芯⽚技术已经成熟,可以采⽤相较于加法器⽽⾔速度更快的数字芯⽚。
(完整版)OFDMmatlab实现
![(完整版)OFDMmatlab实现](https://img.taocdn.com/s3/m/d34ffb804a7302768f993940.png)
close all;carrier_count=200;%子载波数symbols_per_carrier=12;%每子载波含符号数bits_per_symbol=4;%每符号含比特数,16QAM调制IFFT_bin_length=512;%FFT点数PrefixRatio=1/4;%保护间隔与OFDM数据的比例1/6~1/4GI=PrefixRatio*IFFT_bin_length ;%每一个OFDM符号添加的循环前缀长度为1/4*IFFT_bin_length 即保护间隔长度为128beta=1/32;%窗函数滚降系数GIP=beta*(IFFT_bin_length+GI);%循环后缀的长度20SNR=15; %信噪比dB%==================================================%================信号产生=================================== baseband_out_length = carrier_count * symbols_per_carrier * bits_per_symbol;%所输入的比特数目carriers = (1:carrier_count) + (floor(IFFT_bin_length/4) - floor(carrier_count/2));%共轭对称子载波映射复数数据对应的IFFT点坐标conjugate_carriers = IFFT_bin_length - carriers + 2;%共轭对称子载波映射共轭复数对应的IFFT点坐标rand( 'state',0);baseband_out=round(rand(1,baseband_out_length));%输出待调制的二进制比特流%==============16QAM调制====================================complex_carrier_matrix=qam16(baseband_out);%列向量complex_carrier_matrix=reshape(complex_carrier_matrix',carrier_count,symbols_per_car rier)';%symbols_per_carrier*carrier_count 矩阵figure(1);plot(complex_carrier_matrix,'*r');%16QAM调制后星座图axis([-4, 4, -4, 4]);grid on%=================IFFT===========================IFFT_modulation=zeros(symbols_per_carrier,IFFT_bin_length);%添0组成IFFT_bin_length IFFT 运算IFFT_modulation(:,carriers ) = complex_carrier_matrix ;%未添加导频信号,子载波映射在此处IFFT_modulation(:,conjugate_carriers ) = conj(complex_carrier_matrix);%共轭复数映射%========================================================stem(0:IFFT_bin_length-1, abs(IFFT_modulation(2,1:IFFT_bin_length)),'b*-')%第一个OFDM符号的频谱grid onaxis ([0 IFFT_bin_length -0.5 4.5]);ylabel('Magnitude');xlabel('IFFT Bin');title('OFDM Carrier Frequency Magnitude');figure(3);plot(0:IFFT_bin_length-1, (180/pi)*angle(IFFT_modulation(2,1:IFFT_bin_length)), 'go') hold onstem(0:carriers-1, (180/pi)*angle(IFFT_modulation(2,1:carriers)),'b*-');%第一个OFDM符号的相位stem(0:conjugate_carriers-1,(180/pi)*angle(IFFT_modulation(2,1:conjugate_carriers)),'b*-');axis ([0 IFFT_bin_length -200 +200])grid onylabel('Phase (degrees)')xlabel('IFFT Bin')title('OFDM Carrier Phase')%================================================================= signal_after_IFFT=ifft(IFFT_modulation,IFFT_bin_length,2);%OFDM调制即IFFT变换time_wave_matrix =signal_after_IFFT;%时域波形矩阵,行为每载波所含符号数,列ITTF 点数,N个子载波映射在其内,每一行即为一个OFDM符号figure(4);subplot(3,1,1);plot(0:IFFT_bin_length-1,time_wave_matrix(2,:));%第一个符号的波形axis([0, 700, -0.2, 0.2]);grid on;ylabel('Amplitude');xlabel('Time');title('OFDM Time Signal, One Symbol Period');%===========================================================%=====================添加循环前缀与后缀====================================XX=zeros(symbols_per_carrier,IFFT_bin_length+GI+GIP);for k=1:symbols_per_carrier;for i=1:IFFT_bin_length;XX(k,i+GI)=signal_after_IFFT(k,i);endfor i=1:GI;XX(k,i)=signal_after_IFFT(k,i+IFFT_bin_length-GI);%添加循环前缀endfor j=1:GIP;XX(k,IFFT_bin_length+GI+j)=signal_after_IFFT(k,j);%添加循环后缀endendtime_wave_matrix_cp=XX;%添加了循环前缀与后缀的时域信号矩阵,此时一个OFDM符号长度为IFFT_bin_length+GI+GIP=660subplot(3,1,2);plot(0:length(time_wave_matrix_cp)-1,time_wave_matrix_cp(2,:));%第一个符号添加循环前缀后的波形axis([0, 700, -0.2, 0.2]);grid on;ylabel('Amplitude');xlabel('Time');title('OFDM Time Signal with CP, One Symbol Period');%==============OFDM符号加窗==========================================windowed_time_wave_matrix_cp=zeros(1,IFFT_bin_length+GI+GIP);for i = 1:symbols_per_carrierwindowed_time_wave_matrix_cp(i,:) =real(time_wave_matrix_cp(i,:)).*rcoswindow(beta,IFFT_bin_length+GI)';%加窗升余弦窗endsubplot(3,1,3);plot(0:IFFT_bin_length-1+GI+GIP,windowed_time_wave_matrix_cp(2,:));%第一个符号的波形axis([0, 700, -0.2, 0.2]);grid on;ylabel('Amplitude');xlabel('Time');title('OFDM Time Signal Apply a Window , One Symbol Period');%========================生成发送信号,并串变换==================================================windowed_Tx_data=zeros(1,symbols_per_carrier*(IFFT_bin_length+GI)+GIP); windowed_Tx_data(1:IFFT_bin_length+GI+GIP)=windowed_time_wave_matrix_cp(1,:); for i = 1:symbols_per_carrier-1 ;windowed_Tx_data((IFFT_bin_length+GI)*i+1:(IFFT_bin_length+GI)*(i+1)+GIP)=window ed_time_wave_matrix_cp(i+1,:);%并串转换,循环后缀与循环前缀相叠加end%=======================================================Tx_data_withoutwindow=reshape(time_wave_matrix_cp',(symbols_per_carrier)*(IFFT_bin_length+GI+GIP),1)';%没有加窗,只添加循环前缀与后缀的串行信号Tx_data=reshape(windowed_time_wave_matrix_cp',(symbols_per_carrier)*(IFFT_bin_length+GI +GIP),1)';%加窗后循环前缀与后缀不叠加的串行信号%================================================================= temp_time1 = (symbols_per_carrier)*(IFFT_bin_length+GI+GIP);%加窗后循环前缀与后缀不叠加发送总位数figure (5)subplot(2,1,1);plot(0:temp_time1-1,Tx_data );%循环前缀与后缀不叠加发送的信号波形grid onylabel('Amplitude (volts)')xlabel('Time (samples)')title('OFDM Time Signal')temp_time2 =symbols_per_carrier*(IFFT_bin_length+GI)+GIP;subplot(2,1,2);plot(0:temp_time2-1,windowed_Tx_data);%循环后缀与循环前缀相叠加发送信号波形grid onylabel('Amplitude (volts)')xlabel('Time (samples)')title('OFDM Time Signal')%=================未加窗发送信号频谱==================================symbols_per_average = ceil(symbols_per_carrier/5);%符号数的1/5,10行avg_temp_time = (IFFT_bin_length+GI+GIP)*symbols_per_average;%点数,10行数据,10个符号averages = floor(temp_time1/avg_temp_time);average_fft(1:avg_temp_time) = 0;%分成5段for a = 0:(averages-1)subset_ofdm = Tx_data_withoutwindow(((a*avg_temp_time)+1):((a+1)*avg_temp_time));%subset_ofdm_f = abs(fft(subset_ofdm));%将发送信号分段求频谱average_fft = average_fft + (subset_ofdm_f/averages);%总共的数据分为5段,分段进行FFT,平均相加endaverage_fft_log = 20*log10(average_fft);figure (6)subplot(2,1,1);plot((0:(avg_temp_time-1))/avg_temp_time, average_fft_log)%归一化0/avg_temp_time : (avg_temp_time-1)/avg_temp_timehold onplot(0:1/IFFT_bin_length:1, -35, 'rd')grid onaxis([0 0.5 -40 max(average_fft_log)])ylabel('Magnitude (dB)')xlabel('Normalized Frequency (0.5 = fs/2)')title('OFDM Signal Spectrum without windowing')%===============加窗的发送信号频谱================================= symbols_per_average = ceil(symbols_per_carrier/5);%符号数的1/5,10行avg_temp_time = (IFFT_bin_length+GI+GIP)*symbols_per_average;%点数,10行数据,10个符号averages = floor(temp_time1/avg_temp_time);average_fft(1:avg_temp_time) = 0;%分成5段for a = 0:(averages-1)subset_ofdm = Tx_data(((a*avg_temp_time)+1):((a+1)*avg_temp_time));%利用循环前缀后缀未叠加的串行加窗信号计算频谱subset_ofdm_f = abs(fft(subset_ofdm));%分段求频谱average_fft = average_fft + (subset_ofdm_f/averages);%总共的数据分为5段,分段进行FFT,平均相加endaverage_fft_log = 20*log10(average_fft);subplot(2,1,2)plot((0:(avg_temp_time-1))/avg_temp_time, average_fft_log)%归一化0/avg_temp_time : (avg_temp_time-1)/avg_temp_timehold onplot(0:1/IFFT_bin_length:1, -35, 'rd')grid onaxis([0 0.5 -40 max(average_fft_log)])ylabel('Magnitude (dB)')xlabel('Normalized Frequency (0.5 = fs/2)')title('Windowed OFDM Signal Spectrum')%====================添加噪声============================================Tx_signal_power = var(windowed_Tx_data);%发送信号功率linear_SNR=10^(SNR/10);%线性信噪比noise_sigma=Tx_signal_power/linear_SNR;noise_scale_factor = sqrt(noise_sigma);%标准差sigmanoise=randn(1,((symbols_per_carrier)*(IFFT_bin_length+GI))+GIP)*noise_scale_factor; %产生正态分布噪声序列%noise=wgn(1,length(windowed_Tx_data),noise_sigma,'complex');%产生复GAUSS白噪声信号Rx_data=windowed_Tx_data +noise;%接收到的信号加噪声%=====================接收信号串/并变换去除前缀与后缀==========================================Rx_data_matrix=zeros(symbols_per_carrier,IFFT_bin_length+GI+GIP);for i=1:symbols_per_carrier;Rx_data_matrix(i,:)=Rx_data(1,(i-1)*(IFFT_bin_length+GI)+1:i*(IFFT_bin_length+GI)+GI P);%串并变换endRx_data_complex_matrix=Rx_data_matrix(:,GI+1:IFFT_bin_length+GI);%去除循环前缀与循环后缀,得到有用信号矩阵%============================================================%==== ============================================================%==============================================================% OFDM解码16QAM解码%=================FFT变换=================================Y1=fft(Rx_data_complex_matrix,IFFT_bin_length,2);%OFDM解码即FFT变换Rx_carriers=Y1(:,carriers);%除去IFFT/FFT变换添加的0,选出映射的子载波Rx_phase =angle(Rx_carriers);%接收信号的相位Rx_mag = abs(Rx_carriers);%接收信号的幅度figure(7);polar(Rx_phase, Rx_mag,'bd');%极坐标坐标下画出接收信号的星座图%================================================================== ====[M, N]=pol2cart(Rx_phase, Rx_mag);Rx_complex_carrier_matrix = complex(M, N);figure(8);plot(Rx_complex_carrier_matrix,'*r');%XY坐标接收信号的星座图axis([-4, 4, -4, 4]);grid on%====================16qam解调==================================================Rx_serial_complex_symbols =reshape(Rx_complex_carrier_matrix',size(Rx_complex_carrier_matrix,1)*size(Rx_complex_carrier_matrix,2),1)' ;Rx_decoded_binary_symbols=demoduqam16(Rx_serial_complex_symbols);%============================================================ baseband_in = Rx_decoded_binary_symbols;figure(9);subplot(2,1,1);stem(baseband_out(1:100));subplot(2,1,2);stem(baseband_in(1:100));%================误码率计算=============================================bit_errors=find(baseband_in ~=baseband_out);bit_error_count = size(bit_errors, 2)ber=bit_error_count/baseband_out_length。
(完整版)OFDM仿真
![(完整版)OFDM仿真](https://img.taocdn.com/s3/m/fe7e1e32c77da26924c5b043.png)
一、题目OFDM系统的Matlab仿真二、仿真要求要求一:OFDM系统的数据传输①传输的数据随机产生;②调制方式采用16QAM;③必须加信道的衰落④必须加高斯白噪声⑤接收端要对信道进行均衡。
要求二:要求对BER的性能仿真设计仿真方案,得到在数据传输过程中不同信噪比的BER性能结论,要求得到的BER曲线较为平滑。
三、仿真方案详细设计(一)基于IFFT/FFT 实现的OFDM 系统方框图:(二)详细设计方案: 1确定参数需要确定的参数为:子信道,子载波数,FFT 长度,每次使用的OFDM 符号数,调制度水平,符号速率,比特率,保护间隔长度,信噪比,插入导频数,基本的仿真可以不插入导频,可以为0。
2产生数据使用个随机数产生器产生二进制数据,每次产生的数据个数为carrier_count * symbols_per_carrier * bits_per_symbol 。
3编码交织交织编码可以有效地抗突发干扰。
4子载波调制OFDM 采用BPSK 、QPSK 、16QAM 、64QAM4种调制方式。
按照星座图,将每个子信道上的数据,映射到星座图点的复数表示,转换为同相Ich 和正交分量Qch 。
其实这是一种查表的方法,以16QAM 星座为例,bits_per_symbol=4,则每个OFDM 符号的每个子信道上有4个二进制数{d1,d2,d3,d4},共有16种取值,对应星座图上16个点,每个点的实部记为Qch 。
为了所有的映射点有相同高的平均功率,输出要进行归一化,所以对应BPSK,PQSK,16QAM,64QAM ,分别乘以归一化系数系数1,21, 101, 421.输出的复数序列即为映射后的调制结果。
5串并转换。
将一路高速数据转换成多路低速数据 6 IFFT 。
对上一步得到的相同分量和正交分量按照(Ich+Qch*i )进行IFFT 运算。
并将得到的复数的实部作为新的Ich ,虚部作为新的Qch 。
mimoofdm无线通信技术与matlab代码
![mimoofdm无线通信技术与matlab代码](https://img.taocdn.com/s3/m/8b4d07a94bfe04a1b0717fd5360cba1aa8118c16.png)
mimoofdm无线通信技术与matlab代码1. 引言1.1 概述无线通信技术的发展迅猛,随着移动互联网时代的到来,人们对高速、稳定的无线通信需求日益增加。
MIMO-OFDM无线通信技术作为一种重要的解决方案,在提升系统容量和抗干扰性能方面具有显著优势。
本文旨在介绍MIMO-OFDM 无线通信技术原理,并借助MATLAB代码实现,通过仿真和性能评估分析展示其有效性和优越性。
1.2 文章结构本文分为五个部分:引言、MIMO-OFDM无线通信技术、MATLAB代码实现、实验结果与讨论以及结论与展望。
在引言部分,我们将简要介绍文章的背景和目标。
接下来,会详细讲解MIMO-OFDM无线通信技术的基本原理,并说明其在提高系统容量和抗干扰性能方面的作用。
然后,我们会详细描述如何使用MATLAB编写MIMO-OFDM系统模拟代码,并进行性能评估与分析。
随后,我们会展示仿真参数设置和结果展示,并对结果进行深入分析和性能讨论。
最后,在结论与展望部分,我们将总结本文的研究工作和贡献,并讨论目前的不足之处以及可能的改进方案。
1.3 目的本文的主要目的是深入介绍MIMO-OFDM无线通信技术及其原理,并通过MATLAB代码实现来验证其性能。
通过对实验结果进行分析和讨论,我们旨在揭示MIMO-OFDM技术在提高系统容量和抗干扰性能方面的优势。
同时,本文也希望为读者提供一个了解和学习MIMO-OFDM无线通信技术以及使用MATLAB进行系统模拟的参考。
以上就是“1. 引言”部分内容,概述了本文的背景、目标和结构。
在接下来的章节中,我们将逐一展开讲解MIMO-OFDM无线通信技术、MATLAB代码实现、实验结果与讨论以及结论与展望部分。
2. MIMO-OFDM无线通信技术:2.1 MIMO技术介绍:多输入多输出(MIMO)技术是一种通过在发射和接收端使用多个天线来增加系统容量和提高通信质量的无线通信技术。
MIMO技术利用空间上的多样性,通过在不同天线之间形成独立的传输通道,从而带来更好的抗干扰能力和信号接收品质。
(完整版)OFDMmatlab实现
![(完整版)OFDMmatlab实现](https://img.taocdn.com/s3/m/1a377fed10a6f524cdbf85d7.png)
clear all;close all;carrier_count=200;%子载波数symbols_per_carrier=12;%每子载波含符号数bits_per_symbol=4;%每符号含比特数,16QAM调制IFFT_bin_length=512;%FFT点数PrefixRatio=1/4;%保护间隔与OFDM数据的比例1/6~1/4GI=PrefixRatio*IFFT_bin_length ;%每一个OFDM符号添加的循环前缀长度为1/4*IFFT_bin_length 即保护间隔长度为128beta=1/32;%窗函数滚降系数GIP=beta*(IFFT_bin_length+GI);%循环后缀的长度20SNR=15; %信噪比dB%==================================================%================信号产生===================================baseband_out_length = carrier_count * symbols_per_carrier * bits_per_symbol;%所输入的比特数目carriers = (1:carrier_count)+ (floor(IFFT_bin_length/4) - floor(carrier_count/2));%共轭对称子载波映射复数数据对应的IFFT点坐标conjugate_carriers = IFFT_bin_length —carriers + 2;%共轭对称子载波映射共轭复数对应的IFFT点坐标rand('state’,0);baseband_out=round(rand(1,baseband_out_length));%输出待调制的二进制比特流%==============16QAM调制====================================complex_carrier_matrix=qam16(baseband_out);%列向量complex_carrier_matrix=reshape(complex_carrier_matrix',carrier_count,symbols_per_carrier)';%symbols_per_carrier*carrier_count 矩阵figure(1);plot(complex_carrier_matrix,'*r’);%16QAM调制后星座图axis([-4,4, —4,4]);grid on%=================IFFT===========================IFFT_modulation=zeros(symbols_per_carrier,IFFT_bin_length);%添0组成IFFT_bin_length IFFT 运算IFFT_modulation(:,carriers )= complex_carrier_matrix ;%未添加导频信号,子载波映射在此处IFFT_modulation(:,conjugate_carriers ) = conj(complex_carrier_matrix);%共轭复数映射%========================================================figure(2);stem(0:IFFT_bin_length—1,abs(IFFT_modulation(2,1:IFFT_bin_length)),'b*-’)%第一个OFDM符号的频谱grid onaxis ([0 IFFT_bin_length —0。
【matlab编程代做】OFDM
![【matlab编程代做】OFDM](https://img.taocdn.com/s3/m/b16cf61102020740be1e9b5a.png)
clc;clear;%参数初始化i=sqrt(-1);awgn=0; % 定义高斯信道se=0; % 估计技术nse=64; % OFDM载波个数ng=16; % 循环前缀长度SNR=[0 5 10 15 20 25 30 35 40]; % 信噪比mt=2; % 发送天线mr=2; % 接收天线pilot=[1:nse/ng:nse]; % 子带载波ds=5; % 信道延迟number=200;%====================================================================== N=50;fm=100;B=20e3;fd=(rand(1,N)-0.5)*2*fm;theta=randn(1,N)*2*pi;c=randn(1,N);c=c/sum(c.^2);t=0:fm/B:10000*fm/B;T_c=zeros(size(t));T_s=zeros(size(t));for k=1:NT_c=c(k)*cos(2*pi*fd(k)*t+theta(k))+T_c;T_s=c(k)*sin(2*pi*fd(k)*t+theta(k))+T_s;endr=ones(mt*mr,1)*(T_c.^2+T_s.^2).^0.5;index=floor(rand(mt*mr,ds)*5000+1);MEE1=zeros(1,length(SNR));MEE2=zeros(1,length(SNR));for snrl=1:length(SNR)snrlestimation_error1=zeros(mt*mr,nse);estimation_error2=zeros(mt*mr,nse);R1=besselj(0,2*pi*fm*(nse+ng)/B);sigma2=10^(-SNR(snrl)/10);aa=(1-R1^2)/(1-R1^2+sigma2);bb=sigma2*R1/(1-R1^2+sigma2);for iteration=1:numberif awgn==1h=ones(mt*mr,1);elsephi=rand*2*pi;h=r(index+iteration)*exp(j*phi);h=h.*(ones(mt*mr,1)*(exp(-0.5).^[1:ds]));h=h./(sqrt(sum(abs(h).^2,2))*ones(1,ds));end% 信道长度CL=size(h,2);data_time=zeros(mt,nse+ng);data_qam=zeros(mt,nse);data_out=zeros(mr,nse);output=zeros(mr,nse);for tx=1:mtdata_b=0*round(rand(4,nse));data_qam(tx,:)=j*(2*(mod(data_b(1,:)+data_b(2,:),2)+2*data_b(1,:))-3)+2*(mod(data_b(3,:)+data_b(4,:),2)+2*da ta_b(3,:))-3;for loop=1:mtdata_qam(tx,pilot+loop-1)=(1+j)*(loop==tx);enddata_time_temp=ifft(data_qam(tx,:));data_time(tx,:)=[data_time_temp(end-ng+1:end) data_time_temp];endfor rx=1:mrfor tx=1:mtoutput_temp=conv(data_time(tx,:),h((rx-1)*mt+tx,:));output(rx,:)=output_temp(ng+1:ng+nse)+output(rx,:);endnp=(sum(abs(output(rx,:)).^2)/length(output(rx,:)))*sigma2;noise=(randn(size(output(rx,:)))+i*randn(size(output(rx,:))))*sqrt(np);output(rx,:)=output(rx,:)+noise;data_out(rx,:)=fft(output(rx,:));end%信道估计H_act=zeros(mt*mr,nse);H_est1=zeros(mt*mr,nse);H_est2=zeros(mt*mr,nse);i=1;for tx=1:mtfor rx=1:mrH_est_temp=data_out(rx,pilot+tx-1)./data_qam(tx,pilot+tx-1);h_time=ifft(H_est_temp);h_time=[h_time zeros(1,nse-length(h_time))];H_est1((rx-1)*mt+tx,:)=fft(h_time);H_est2((rx-1)*mt+tx,:)=((aa*abs(H_est1((rx-1)*mt+tx,:))+bb*abs(H_est2((rx-1)*mt+tx,:)))....*H_est1((rx-1)*mt+tx,:))./abs(H_est1((rx-1)*mt+tx,:));if (tx>1)H_est1((rx-1)*mt+tx,:)=[H_est1((rx-1)*mt+tx,nse-tx+2:nse)H_est1((rx-1)*mt+tx,1:nse-tx+1)];H_est2((rx-1)*mt+tx,:)=[H_est2((rx-1)*mt+tx,nse-tx+2:nse)H_est2((rx-1)*mt+tx,1:nse-tx+1)];endH_act((rx-1)*mt+tx,:)=fft([h((rx-1)*mt+tx,:) zeros(1,nse-CL)]);error1=(abs(H_act((rx-1)*mt+tx,:)-H_est1((rx-1)*mt+tx,:)).^2);error2=(abs(H_act((rx-1)*mt+tx,:)-H_est2((rx-1)*mt+tx,:)).^2);estimation_error1((rx-1)*mt+tx,:)=estimation_error1((rx-1)*mt+tx,:)+error1;estimation_error2((rx-1)*mt+tx,:)=estimation_error2((rx-1)*mt+tx,:)+error2;endendendestimation_error1=estimation_error1/number;estimation_error2=estimation_error2/number;MEE1(snrl)=sum(sum(estimation_error1))/(mt*mr*nse);MEE2(snrl)=sum(sum(estimation_error2))/(mt*mr*nse);endplot(SNR,10*log10(MEE1));hold on;plot(SNR,10*log10(MEE2),'r');error1=(abs(H_act-H_est1).^2)./(abs(H_act).^2);error2=(abs(H_act-H_est2).^2)./(abs(H_act).^2);fig=4;i=1;figure(1);subplot(fig,1,i),plot([0:length(H_act)-1],abs(H_act)); i=i+1;subplot(fig,1,i),plot([0:length(H_est1)-1],abs(H_est1)); i=i+1;subplot(fig,1,i),plot([0:length(H_est2)-1],abs(H_est2)); i=i+1;subplot(fig,1,i),plot([0:length(error1)-1],error1); i=i+1;IFFT_bin_length=128;carrier_count=100;biT_s_per_symbol=2;symbols_per_carrier=12;LI=7 ;Np=ceil(carrier_count/LI)+1;N_number=carrier_count*symbols_per_carrier*biT_s_per_symbol; carriers=1:carrier_count+Np;GI=8;N_snr=40; % 每比特信噪比snr=8; %信噪比间隔X=zeros(1,N_number) ;XX=zeros(1,N_number) ;dif_bit=zeros(1,N_number) ;dif_bit1=zeros(1,N_number);dif_bit2=zeros(1,N_number);dif_bit3=zeros(1,N_number);X=randint(1,N_number) ;s=(X.*2-1)/sqrt(2) ;sreal=s(1:2:N_number) ;simage=s(2:2:N_number) ;%=========================================X1=sreal+j.*simage;train_sym=randint(1,2*symbols_per_carrier);t=(train_sym.*2-1)/sqrt(2);treal=t(1:2:2*symbols_per_carrier);timage=t(2:2:2*symbols_per_carrier);training_symbols1=treal+j.*timage;training_symbols2=training_symbols1.';training_symbols=repmat(training_symbols2,1,Np);pilot=1:LI+1:carrier_count+Np;if length(pilot)~=Nppilot=[pilot,carrier_count+Np];end%串并转换X2=reshape(X1,carrier_count,symbols_per_carrier).';%插入导频signal=1:carrier_count+Np;signal(pilot)=[];X3(:,pilot)=training_symbols;X3(:,signal)=X2;IFFT_modulation=zeros(symbols_per_carrier,IFFT_bin_length); IFFT_modulation(:,carriers)=X3;X4=ifft(IFFT_modulation,IFFT_bin_length,2);%加保护间隔(循环前缀)for k=1:symbols_per_carrier;for i=1:IFFT_bin_length;X6(k,i+GI)=X4(k,i);endfor i=1:GI;X6(k,i)=X4(k,i+IFFT_bin_length-GI);endend%并串转换X7=reshape(X6.',1,symbols_per_carrier*(IFFT_bin_length+GI)); %信道模型:带多普勒频移的瑞利衰落信道fd=100; %多普勒频移r=6; %多径数a=[0.123 0.3 0.4 0.5 0.7 0.8]; %多径的幅度d=[2 3 4 5 9 13]; %各径的延迟T=1; %系统采样周期th=[90 0 72 144 216 288]*pi./180;%相移h=zeros(1,carrier_count);hh=[];for k=1:rh1=a(k)*exp(j*((2*pi*T*fd*d(k)/carrier_count)));hh=[hh,h1];endh(d+1)=hh;channel1=zeros(size(X7));channel1(1+d(1):length(X7))=hh(1)*X7(1:length(X7)-d(1)); channel2=zeros(size(X7));channel2(1+d(2):length(X7))=hh(2)*X7(1:length(X7)-d(2)); channel3=zeros(size(X7));channel3(1+d(3):length(X7))=hh(3)*X7(1:length(X7)-d(3)); channel4=zeros(size(X7));channel4(1+d(4):length(X7))=hh(4)*X7(1:length(X7)-d(4)); channel5=zeros(size(X7));channel5(1+d(5):length(X7))=hh(5)*X7(1:length(X7)-d(5)); channel6=zeros(size(X7));channel6(1+d(6):length(X7))=hh(6)*X7(1:length(X7)-d(6));Tx_data=X7+channel1+channel2+channel3+channel4;%加高斯白噪声Error_ber=[];%误比特率Error_ber1=[];Error_ber2=[];%误比特率Error_ber3=[];for snr_db=0:snr:N_snrcode_power=0;code_power=[norm(Tx_data)]^2/(length(Tx_data)); %信号的符号功率bit_power=code_power/biT_s_per_symbol; %比特功率noise_power=10*log10((bit_power/(10^(snr_db/10))));%噪声功率noise=wgn(1,length(Tx_data),noise_power,'complex');%产生GAUSS白噪声信号Y7=Tx_data+noise;%串并变换Y6=reshape(Y7,IFFT_bin_length+GI,symbols_per_carrier).';%去保护间隔for k=1:symbols_per_carrier;for i=1:IFFT_bin_length;Y5(k,i)=Y6(k,i+GI);endendY4=fft(Y5,IFFT_bin_length,2);Y3=Y4(:,carriers);%LS信道估计H=[];Y2=Y3(:,signal);Rx_training_symbols=Y3(:,pilot);Rx_training_symbols0=reshape(Rx_training_symbols,symbols_per_carrier*Np,1);training_symbol0=reshape(training_symbols,1,symbols_per_carrier*Np);training_symbol1=diag(training_symbol0);training_symbol2=inv(training_symbol1);Hls=training_symbol2*Rx_training_symbols0;Hls1=reshape(Hls,symbols_per_carrier,Np);HLs=[];HLs1=[];if ceil(carrier_count/LI)==carrier_count/LIfor k=1:Np-1HLs2=[];for t=1:LIHLs1(:,1)=(Hls1(:,k+1)-Hls1(:,k))*(t-1)./LI+Hls1(:,k);HLs2=[HLs2,HLs1];endHLs=[HLs,HLs2];endelsefor k=1:Np-2HLs2=[];for t=1:LIHLs1(:,1)=(Hls1(:,k+1)-Hls1(:,k))*(t-1)./LI+Hls1(:,k);HLs2=[HLs2,HLs1];endHLs=[HLs,HLs2];endHLs3=[];for t=1:mod(carrier_count,LI)HLs1(:,1)=(Hls1(:,Np)-Hls1(:,Np-1))*(t-1)./LI+Hls1(:,Np-1);HLs3=[HLs3,HLs1];end;HLs=[HLs,HLs3];endY1=Y2./HLs;%并串变换YY=reshape(Y2.',1,N_number/biT_s_per_symbol);YY1=reshape(Y1.',1,N_number/biT_s_per_symbol);%QPSK解调y_real=sign(real(YY));y_image=sign(imag(YY));y_re=y_real./sqrt(2);y_im=y_image./sqrt(2);y_real1=sign(real(YY1));y_image1=sign(imag(YY1));y_re1=y_real1./sqrt(2);y_im1=y_image1./sqrt(2);r00=[];r01=[];r10=[];r11=[];for k=1:length(y_real);r00=[r00,[y_real(k),y_image(k)]];end;for k=1:length(y_real1);r10=[r10,[y_real1(k),y_image1(k)]];end;for k=1:length(y_re);r01=[r01,[y_re(k),y_im(k)]];end;for k=1:length(y_re1);r11=[r11,[y_re1(k),y_im1(k)]];end;XX(find(r01>0))=1;%计算在不同信噪比下的误比特率并作图dif_bit=s-r01;dif_bit1=s-r11;ber_snr=0; %纪录误比特数for k=1:N_number;if dif_bit(k)~=0;ber_snr=ber_snr+1;endend;ber_snr1=0; %纪录误比特数for k=1:N_number;if dif_bit1(k)~=0;ber_snr1=ber_snr1+1;endendError_ber=[Error_ber,ber_snr]; Error_ber1=[Error_ber1,ber_snr1]; endBER=zeros(1,length(0:snr:N_snr)); BER1=zeros(1,length(0:snr:N_snr));BER=Error_ber./N_number;BER1=Error_ber1./N_number; figure(2);i=0:snr:N_snr;semilogy(i,BER,'-*r');hold on;semilogy(i,BER1,'-og');hold on;legend('无信道估计','线性信道估计');。
OFDM MATLAB仿真程序
![OFDM MATLAB仿真程序](https://img.taocdn.com/s3/m/9b51b8ef102de2bd9605886d.png)
OFDM.m: OFDM Simulator (outer function)clear all;A = [1 1/exp(1) 1/exp(2)]; % power delay profileN = 64; % number of symbols in a single OFDM symbolGI = 16; % guard intervalMt = 1; % number of Tx antennasMr = 1; % number of Rx antennassig2 = 1e-3; % noise varianceM = 8; % max constellation bit numberMgap = 10.^(1:(1.7/10):2.7); % gapBtot = 100*Mt; % total # bits per OFDM symbolTransmitIter = 50; % # iterations of symbol transmissions for each channel instance ChannelIter = 100; % # iterations of independent identically distributed channel instances GapIter = length(Mgap);load ENC2.matload ENC4.matload ENC16.matload ENC64.matload ENC256.matTotEbNo = [];Errors =[];EbNo = [];for lGap = 1:GapIterlGapgap = Mgap(lGap);totalErrors = 0;for lChan = 1:ChannelIter% create channel[H h_f]=create_channel(Mt, Mr, A, N+GI);% decompose each subchannel in the frequency domain[U S V] = svd_decompose_channel(Mt, Mr, h_f, N);% bitloading[bits_alloc,energy_alloc] = BitLoad(S,Btot,Mt*N,gap,sig2,M);%energy_alloc=energy_alloc/(mean(energy_alloc));%energy_alloc=ones(1,128);for lTrans = 1:TransmitIter% bits to transmitx = (randn(1,Btot)>0);% modulatex_mod = modulate(x,bits_alloc,energy_alloc, s2,s4,s16,s64,s256);% precode modulated signalx_pre = precode(Mt, x_mod, V, N);% ifft, with cyclic prefix for each antennaofdm_symbol =[];for i=1:Mtofdm_symbol = [ofdm_symbol; ifft_cp_tx_blk(x_pre(i:Mt:Mt*(N-1)+i),N,GI)];endofdm_symbol2 = reshape(ofdm_symbol,Mt*(N+GI),1);% channely = transpose(channel(sig2, Mt, Mr, ofdm_symbol2, H, N+GI));% fftrec_symbol =[];for i=1:Mtrec_symbol = [rec_symbol; fft_cp_rx_blk(y(i:Mt:Mt*(N+GI-1)+i),N,GI)];endrec_symbol2 = reshape(rec_symbol,1,Mt*N);% shape received signalshaped_vals = shape(rec_symbol2, Mr, U, N);% demodulatey_demod = demodulate(shaped_vals, bits_alloc, energy_alloc, S, s2,s4,s16,s64,s256, c2,c4,c16,c64,c256); % comparisontotalErrors = totalErrors + sum(xor(y_demod,x));endEbNo = [EbNo sum(energy_alloc)/Btot/sig2];endErrors = [Errors totalErrors/Btot/ChannelIter/TransmitIter]TotEbNo = [TotEbNo mean(EbNo)]EbNo = [];endsemilogx(TotEbNo, Errors);xlabel('Eb/No');ylabel('BER');title('SISO link, adaptive rate and power')save SISO_adaptive2.mat Errors EbNocreate_channel.m: Generates a Rayleigh fading frequency-selective channel, parametrized by the antenna configuration, the OFDM configuration, and the power-delay profile.function [H, H_f]=create_channel(Mt, Mr, A, N);% function [H, H_f]=create_channel(Mt, Mr, A, N);%% A - vector containing the power-delay profile (real values)% Mt - number of Tx antennas% Mr - number of Rx antennas% N - number of vector symbols to be sent in a single OFDM symbol Tx% ie: N MIMO transmissions in one OFDM symbol% This is for Rayleigh frequency-selective fading, which assumes complex % Gaussian matrix elements with in-phase and quadrature components independent.% Assume iid matrix channel elements, and further, independent channel taps % define the channel tapsH_int = 1/sqrt(2)*(randn(Mr*length(A),Mt) + j*randn(Mr*length(A),Mt));H_int2=[];for i = 1:length(A)H_int2 = [H_int2;sqrt(A(i))*H_int((i-1)*Mr+1:i*Mr,:)];end%h_f = fft(H_int2',64);%%H = H_int2';H_int2 = [H_int2;zeros((N-length(A))*Mr,Mt)];H_f = zeros(Mr,Mt*(N-16));for i = 1:Mtfor j = 1:Mrh_f = fft(H_int2(j:Mr:(N-16-1)*Mr+j,i));for k = 1:(N-16)H_f(j,i+(k-1)*Mt) = h_f(k);endendendH=[H_int2];for i = 1:N-1H=[H,[zeros(Mr*i,Mt);H_int2(1:(N-i)*Mr,:)]];endsvd_decompose_channel.m: Since full channel knowledge is assumed, transmission is across parallel singular value modes. This function decomposes the channel into these modes.function [U, S, V] = svd_decompose_channel(Mt, Mr, h_f, N);% [U S V] = svd_decompose_channel(Mt, Mr, h_f, N);%% Function decomposes the channel at each subcarrier into its SVD components %% Mt - # Tx antennas% Mr - # Rx antennas% h_f - MIMO impulse response - Mr rows, Mt*L columns, where L is the number of% channel taps% N - # subcarriersU = [];S = [];V = [];for i = 1:N[Utmp Stmp Vtmp] = svd(h_f(:,(i-1)*Mt+1:i*Mt));U=[U Utmp];V=[V Vtmp];S=[S Stmp];endS = sum(S,1);BitLoad.m: Apply the bit-loading algorithm to achieve the desired bit and energy allocation for the current channel instance.function [bits_alloc,energy_alloc] =BitLoad(subchan_gains,total_bits,num_subc,gap,noise,M)% Bit Loading Algorithm% ---------------------%% Inputs :% subchan_gains : SubCarrier Gains% total_bits : Total Number of bits% num_subc : Number of Subcarriers% gap : Gap of the system% noise : Noise Power% M : Max Constellation Size% Outputs:% bits_alloc : Bits allocation for each subchannel% power_alloc : Total Power allocation% ---------------------------------------------------------------% Compute SNR's for each channelSNR = ComputeSNR(subchan_gains,noise,gap);% This function just initializes the system with a particular bit% allocation and energy allocation using Chow's Algorithm. This is% further efficientize using Campello's Algorithm[bits_alloc, energy_alloc] = chow_algo(SNR,num_subc,M);% Form the Energy Increment Table based on the present channel% gains for all the subchannels in order to be used by Campello% Algorithmenergytable = EnergyTableInit(SNR,M);% Efficientize the algorithm using the Campello's algorithm[bits_alloc,energy_alloc] =campello_algo(bits_alloc,energy_alloc,energytable,total_bits,num_subc,M );ComputeSNR.m: Given the subcarrier gains, this simple function generates the SNR values of each channel (each singular value on each tone is a separate channel). function SNR = ComputeSNR(subcar_gains,noise,gap)SNR = abs((subcar_gains.^2)./(noise*gap));chow_algo.m: Apply Chow's algorithm to generate a particular bit and energy allocation.% Chow's Algorithm% ----------------% This is based on the paper by Chow et al titled%% A Practical Discrete Multitone Transceiver Loading Algorithm% for Data Transmission over Spectrally Shaped Channels.IEEE Trans% on Communications. Vol. 43, No 2/3/4, pp. 773-775, Feb/Mar/Apr 1995 function [bits_alloc, energy_alloc] = chow_algo(SNR,num_subc,M)for i = 1:num_subc% Assuming each of the subchannels has a flat fading, we get initial estimate % of the bits for each subchanneltempbits = log2(1 + abs(SNR(i))); % bits per two dimension. roundtempbits = round(tempbits); % round the bitsif (roundtempbits > 8) % Limit them between 2 and 15 roundtempbits = 8;endif (mod(roundtempbits,2)== 1 & roundtempbits ~= 1)roundtempbits = roundtempbits -1;endif roundtempbits > 0 % Calculate the Energy required for the subchannelenergy_alloc(i) = (2^roundtempbits-1)/SNR(i) ;elseenergy_alloc(i) = 0;endbits_alloc(i) = roundtempbits; % Update the BitSubChan end% end of functionEnergyTableInit.m: Given the SNR values, form a table of energy increments for each channel.function energytable = EnergyTableInit(SNR,M);% Inputs:% subcar_gains : Subcarrier Gains% M : max Constellation Size% Gap : Gap of the system% Noise : Noise Power% Outputs:% energytable : Energytable%% Based on the Subcarrier Gains, we calculate the energy% increment required by each subcarrier for transmitting% 1,2 ,4 ,6,8 bits.% Energy = 2^(i-1)/subcar_gains;% ------------------------------------------------------%subcar_gains = (subcar_gains.^2)/(Gap*Noise);energytable = abs((1./SNR)'*(2.^([1:M+1]-1)));% Increase the energy value for constellation size of more than M to% a very high value so that it is not assigned.energytable(:,M+1) = Inf*ones(size(energytable(:,M+1)));for i = 3:2:Menergytable(:,i) = (energytable(:,i) +energytable(:,i+1))/2;energytable(:,i+1) = energytable(:,i);end%energytable = [ones(1,size(energytable,1))' energytable];campello_algo.m: Apply Campello's algorithm to converge to the optimal bit and energy allocation for the given channel conditions.% campello_algo.m% --------------% This function is used by Campello's algorithm to allocate bits and energy for% each subchannel optimally.function [bits_alloc, energy_alloc] =campello_algo(bits_alloc,energy_alloc,energytable,total_bits,num_subc,M)bt = sum(bits_alloc);% We can't transmit more than M*(Number of subchannel) bitsif total_bits > M*num_subctotal_bits = M*num_subc;endwhile (bt ~= total_bits)if (bt > total_bits)max_val = 0;max_ind = ceil(rand(1)*num_subc);for i = 1:num_subcif bits_alloc(i) ~= 0temp = energytable(i,bits_alloc(i)) ;elsetemp = 0;endif (temp > max_val)max_val = temp;max_ind = i;endendif (bits_alloc(max_ind) > 0)bits_alloc(max_ind) = bits_alloc(max_ind) -1;energy_alloc(max_ind) = energy_alloc(max_ind) - max_val;bt = bt-1;endelsemin_val = Inf;min_ind = ceil(rand(1)*num_subc);for i = 1:num_subcif bits_alloc(i) ~=0 & bits_alloc(i) <9temp = energytable(i,bits_alloc(i) + 1);elsetemp = Inf;endif (temp < min_val)min_val = temp;min_ind = i;endendif (bits_alloc(min_ind) < 8)bits_alloc(min_ind) = bits_alloc(min_ind) +1;if (min_val==inf)min_val = energytable(min_ind,bits_alloc(min_ind));endenergy_alloc(min_ind) = energy_alloc(min_ind) +min_val;bt = bt+1;endendendfor i = 1:length(bits_alloc)if (mod(bits_alloc(i),2) == 1 & bits_alloc(i) ~=1)[bits_alloc,energy_alloc] =ResolvetheLastBit(bits_alloc,energy_alloc,i,energytable,num_subc);endendResolvetheLastBit.m: An optimal bit-loading of the last bit requires a unique optimization.function [bits_alloc, energy_alloc] =ResolvetheLastBit(bits_alloc,energy_alloc,index,energytable,num_subc) max_val = 0;for i = 1:num_subcif (i ~= index & bits_alloc(i) == 1)if bits_alloc(i) ~= 0temp = energytable(i,bits_alloc(i)) ;endif (temp > max_val)max_val = temp;max_ind = i;endendendmin_val = Inf;for i = 1:num_subcif (i~= index & bits_alloc(i) == 1)if bits_alloc(i) ~=0temp = energytable(i,bits_alloc(i) + 1);endif (temp < min_val)min_val = temp;min_ind = i;endendendif (min_val < max_val)bits_alloc(min_ind) = bits_alloc(min_ind) + 1;bits_alloc(index) = bits_alloc(index) - 1;energy_alloc(index) = energy_alloc(index) - min_val; elsebits_alloc(max_ind) = bits_alloc(max_ind) - 1;bits_alloc(index) = bits_alloc(index) + 1;energy_alloc(index) = energy_alloc(index) + max_val; end。
OFDM发射端matlab仿真代码
![OFDM发射端matlab仿真代码](https://img.taocdn.com/s3/m/1c18a6e52dc58bd63186bceb19e8b8f67c1cefc3.png)
OFDM发射端matlab仿真代码%%%%%%%%%%%%%%%%% Parameters Initial%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%% %%clear;close all;clc% Frequently modified parameters for AWG and ScopeSamplePerSymbol_R=3;SymbolRate_R=10/3*1e9;ScopeSamplingRate=25e9;%接收端的采样频率,可以不用管L=30;f_low1=5e9;f_low2=5.5e9;k_ratio=16;%1,2,4,8,16%%%%%%%%%%%%%%%%% OFDM 符号定义的参数,这一段的参数需要严格的跟发射端保持一致%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N_SCFDM=50;N_fft=1024;M_fft=N_fft;N_cp=8;N_zero=50;N_pilot=8;N_grd=100;N_TrainSeq=4;N_frm=N_fft+N_cp;BitsPerSymbol=2;ModType='QAM';N_band=1;N_syn=64;M=N_fft-N_pilot-N_zero-N_grd;Ns=N_SCFDM*M;Nb=Ns*BitsPerSymbol;Pave=Cal_Pave(ModType,BitsPerSymbol);rand('seed',50);data_tem=randint(1,Nb);mapped_data=data_map(data_tem,BitsPerSymbol,ModType );PSeed=199;Pilot=Generate_Pilot(M_fft,N_pilot,0,0,Ns,BitsPerSymbol,Mo dType,Pave,PSeed);mapped_data=mapped_data/Pave;%%%%%%%%%%%%%%%%% Read Scope Data %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%CurPath=pwdQ_all=[];BER_all=[];% for kk=164:168load('output_ifall.mat');%将发射端的信号load进来% filename=num2str(kk);% output=load ([CurPath,'\data\a110',filename,'_Ch1.dat']);% filename='a10';% output=load ([CurPath,'\datayh\a1',filename,'.dat']);% load OFDM_QPSK.mat;% % % 2.5GHz IF 4.5~5.5过渡% Fs = 15; % Sampling Frequency% Fstop1 = 0.5; % First Stopband Frequency% Fpass1 = 1; % First Passband Frequency% Fpass2 =6.5; % Second Passband Frequency% Fstop2 = 7; 2,Fstop2);% output = conv(output,b);% filter_coeff = [-0.0003,-0.0007,-0.0008,-0.0002,0.0014,0.0033,0.004,0.0022,-0.0018,-0.0061,-0.0075,-0.0046,0.0012,0.0064,0.0076,0.0047,0.0007,-0.0008,0.0013,0.0042,0.0041,-0.0001,-0.0057,-0.0081,-0.0057,-0.0013,0.0001,-0.0036,-0.0092,-0.011,-0.0063,0.0014,0.0054,0.0023,-0.004,-0.0057,0.0012,0.0122,0.018,0.0137,0.0039,-0.0005,0.0066,0.0195,0.0253,0.0161,-0.0019,-0.0129,-0.0071,0.0085,0.0147,-0.0016,-0.0324,-0.0531,-0.0449,-0.0163,0.0002,-0.0238,-0.0816,-0.1265,-0.1041,0.0019,0.1474,0.2515,0.2515,0.1474,0.0019,-0.1041,-0.1265,-0.0816,-0.0238,0.0002,-0.0163,-0.0449,-0.0531,-0.0324,-0.0016,0.0147,0.0085,-0.0071,-0.0129,-0.0019,0.0161,0.0253,0.0195,0.0066,-0.0005,0.0039,0.0137,0.018,0.0122,0.0012,-0.0057,-0.004,0.0023,0.0054,0.0014,-0.0063,-0.011,-0.0092,-0.0036,0.0001,-0.0013,-0.0057,-0.0081,-0.0057,-0.0001,0.0041,0.0042,0.0013,-0.0008,0.0007,0.0047,0.0076,0.0064,0.0012,-0.0046,-0.0075,-0.0061,-0.0018,0.0022,0.004,0.0033,0.0014,-0.0002,-0.0008,-0.0007,-0.0003;];% filter_coeff = [0.0009,0.0038,0.0084,0.0118,0.0099,0.0021,-0.006,-0.007,0.0003,0.0077,0.0057,-0.0043,-0.0102,-0.003,0.0099,0.0116,-0.0027,-0.0165,-0.0099,0.0124,0.0225,0.0025,-0.0267,-0.0251,0.0145,0.0464,0.0193,-0.0519,-0.0791,0.0156,0.2055,0.3612,0.3612,0.2055,0.0156,-0.0791,-0.0519,0.0193,0.0464,0.0145,-0.0251,-0.0267,0.0025,0.0225,0.0124,-0.0099,-0.0165,-0.0027,0.0116,0.0099,-0.003,-0.0102,-0.0043,0.0057,0.0077,0.0003,-0.007,-0.006,0.0021,0.0099,0.0118,0.0084,0.0038,0.0009;];% output = conv(output,filter_coeff);% output = resample(output,10,25);% Q_all=[];plot(abs(output));%a画出接收到的信号的时域波形output1=output(40000:end);% fvtool(output1);% BER_all=[];output1 = IFdown(output1,1);%下变频操作,这个是对应发射端的上变频的Rx_Signal_Orin=output1;% Rx_Signal_Orin=IQBalanceT(Rx_Signal_Orin);Rx_Signal_Orin = lpf(Rx_Signal_Orin,SymbolRate_R*SamplePerSymbol_R,1.5e9,2.4 e9);%经过滤波器,滤波器的参数中1.8和2.4是上下的截止频率,可以设置和优化的%[num,den]=rcosine(SymbolRate_R,SymbolRate_R*SamplePerSy mbol_R,'normal',0.9,1);% output1=filter(num,den,output1);% Rx_Signal_Orin=output1;Rx_Signal_Orin=Rx_Signal_Orin/max(abs(Rx_Signal_Orin));%归一化操作corr=cal_corr(Rx_Signal_Orin,N_syn,SamplePerSymbol_R);%自相关计算,找相关值plot(corr);%画出相关值threshold = 12;Rx_Signal_Syn=Frm_Sync(Rx_Signal_Orin,N_syn,SamplePerSymbol_R,threshold);%根据相关峰找到同步的地点Rx_Signal_Syn=Rx_Signal_Syn(1:SamplePerSymbol_R:end);%对信号进行重采样,发射端是进行了3倍过采样的% % % % % Remove Train SequenceRx_Signal=Rx_Signal_Syn(1+N_syn*2:end);%去掉同步的序列TrainSeq=Rx_Signal(1:N_frm*N_TrainSeq);%取出训练序列Ng_Nu = 5/64; %for nonlinearSNR=100;ChanEstiType='2';ChanEsti=Get_ChanEsti_OFDM(TrainSeq,N_fft,N_frm,N_cp,N _TrainSeq,ChanEstiType,Ng_Nu,SNR,N_band,M_fft);%根据训练序列计算出信道估计函数% ChanEsti3G=ChanEsti;%save('E:\code\16QAM\tx\ChanEsti.mat','ChanEsti');Rx_Data = Rx_Signal(N_frm*N_TrainSeq+1:end);%将训练序列去掉,留下最后的有效信号[Output,Output_Wo_EQ]=OFDM_Decode(Rx_Data,ChanEsti,N_fft,N_grd,N_zero,N_frm,N_cp,ModType,BitsPerSymbol,N_pilot, Pilot,L,N_SCFDM);%利用信道估计函数进行信道均衡并解调a=Output;figure;plot(a,'.');b=mapped_data*Pave;N_eff=length(a);q=sqrt(sum(abs(a-b).^2)/N_eff)/Pave;Q=-20*log10(q)% Q_all=[Q_all,Q];m = 4;if(length(strfind(ModType,'QAM')))h=modem.qamdemod('M', 2^BitsPerSymbol, 'SymbolOrder', 'gray', 'OutputType', 'Bit');elseh=modem.pskdemod('M', 2^BitsPerSymbol, 'SymbolOrder', 'gray', 'OutputType', 'Bit');endOutBit=demodulate(h,Output.').';rand('seed',50); % Fixing the random seedinput=randint(1,Nb);[num,BER1]=biterr(input,OutBit);BER1% BER_all=[BER_all,BER1];% end;。
OFDM信道估计MATLAB代码
![OFDM信道估计MATLAB代码](https://img.taocdn.com/s3/m/c6fbe0a164ce0508763231126edb6f1aff0071c9.png)
echo off; % 关闭回显clear all; % 从内存中清除变量和函数close all; % 关闭所有图形fprintf( '\n OFDM仿真\n \n') ; % 设置显示格式% --------------------------------------------- %% 参数定义%% --------------------------------------------- %IFFT_bin_length = 1024; % 发送端的IFFT变换长度, 接收端的FFT变换长度,R代表接受,T代表发送carrier_count = 200; % 子载波数bits_per_symbol = 2; % 位数/符号symbols_per_carrier = 50; % 符号数/载波cp_length = input('cp length = '); % 输入循环前缀长度d4 = input('d4 = '); % 输入最大多径时延扩展a4 = input('a4 = '); % 输入最大多径时延扩展的系数SNR = input('SNR = '); % 输入信道信噪比(dB) % --------------------------------------------- %% 初始参数设置完毕%% --------------------------------------------- %baseband_out_length = carrier_count * symbols_per_carrier * bits_per_symbol; % 计算发送的二进制序列长度:基带传送长度=载波数×符号数/载波×位数/符号carriers = (1:carrier_count) + (floor(IFFT_bin_length/4) - floor(carrier_count/2)); % 载波(坐标):(1:200) + 256 - 100 = 157:356conjugate_carriers = IFFT_bin_length - carriers + 2; % 载波变换(坐标):1024 - (157:356) + 2 = 1026 - (157:356) = (869:670)%---------------------------------------% 构造共轭时间-载波矩阵,以便应用所谓的RCC,Reduced Computational Complexity算法,即ifft之后结果为实数% 也可以用flipdim函数构造对称共轭矩阵%---------------------------------------% --------------------------------------------- %% 发送信号%% --------------------------------------------- %%---------------------------------------% Generate a random binary output signal:% - a row of uniform random numbers (between 0 and 1), rounded to 0 or 1% - this will be the baseband signal which is to be transmitted.%---------------------------------------baseband_out = round(rand(1,baseband_out_length));%---------------------------------------% round:朝最近的整数取整,rand:产生均匀分布的随机数矩阵(1×baseband_out_length 阶)% Convert to 'modulo N' integers where N = 2^bits_per_symbol% - this defines how many states each symbol can represent% - first, make a matrix with each column representing consecutive bits% from the input stream and the number of bits in a column equal to the% number of bits per symbol% - then, for each column, multiply each row value by the power of 2 that% it represents and add all the rows% - for example: input 0 1 1 0 0 0 1 1 1 0% bits_per_symbol = 2% convert_matrix = 0 1 0 1 1% 1 0 0 1 0% modulo_baseband = 1 2 0 3 2%---------------------------------------convert_matrix = reshape(baseband_out,bits_per_symbol,length(baseband_out)/bits_per_symbol) ;%---------------------------------------% RESHAPE Change size. 把baseband_out变为M×N阶的矩阵% RESHAPE(X,M,N) returns the M-by-N matrix whose elements% are taken columnwise from X. An error results if X does% not have M*N elements.%---------------------------------------for k = 1:(length(baseband_out)/bits_per_symbol)modulo_baseband(k) = 0 ;for i = 1:bits_per_symbolmodulo_baseband(k) = modulo_baseband(k) + convert_matrix(i,k)*2^(bits_per_symbol - i) ; endend%---------------------------------------% Serial to Parallel Conversion 串并转换% - convert the serial modulo N stream into a matrix where each column% represents a carrier and each row represents a symbol% - for example:% serial input stream = a b c d e f g h i j k l m n o p% parallel carrier distribution =% C1/s1=a C2/s1=b C3/s1=c C4/s1=d% C1/s2=e C2/s2=f C3/s2=g C4/s2=h% C1/s3=i C2/s3=j C3/s3=k C4/s3=l% . . . .% . . . .%---------------------------------------carrier_matrix = reshape(modulo_baseband, carrier_count, symbols_per_carrier)'; %生成时间-载波矩阵(carrier_count×symbols_per_carrier)%---------------------------------------% Apply differential coding to each carrier string% - append an arbitrary start symbol (let it be 0, that works for all% values of bits_per_symbol) (note that this is done using a vertical% concatenation [x;y] of a row of zeros with the carrier matrix, sweet!)% - perform modulo N addition between symbol(n) and symbol(n-1) to get the% coded value of symbol(n)% - for example:% bits_per_symbol = 2 (modulo 4)% symbol stream = 3 2 1 0 2 3% start symbol = 0%% coded symbols = 0 + 3 = 3% 3 + 2 = 11 = 1% 1 + 1 = 2% 2 + 0 = 2% 2 + 2 = 10 = 0% 0 + 3 = 3%% coded stream = 0 3 1 2 2 0 3%---------------------------------------% --------------------------------------------- %% QDPSK调制%% --------------------------------------------- %carrier_matrix = [zeros(1,carrier_count);carrier_matrix]; % 添加一个差分调制的初始相位,为0for i = 2:(symbols_per_carrier + 1)carrier_matrix(i,:) = rem(carrier_matrix(i,:)+carrier_matrix(i-1,:),2^bits_per_symbol); % 差分调制(rem除后取余)end%---------------------------------------% Convert the differential coding into a phase% - each phase represents a different state of the symbol% - for example:% bits_per_symbol = 2 (modulo 4)% symbols = 0 3 2 1% phases =% 0 * 2pi/4 = 0 (0 degrees)% 3 * 2pi/4 = 3pi/2 (270 degrees)% 2 * 2pi/4 = pi (180 degrees)% 1 * 2pi/4 = pi/2 (90 degrees)%---------------------------------------carrier_matrix = carrier_matrix * ((2*pi)/(2^bits_per_symbol)); % 产生差分相位%---------------------------------------% Convert the phase to a complex number% - each symbol is given a magnitude of 1 to go along with its phase% (via the ones(r,c) function)% - it is then converted from polar to cartesian (complex) form% - the result is 2 matrices, X with the real values and Y with the imaginary% - each X column has all the real values for a carrier, and each Y column% has the imaginary values for a carrier% - a single complex matrix is then generated taking X for real and% Y for imaginary%---------------------------------------[X,Y] = pol2cart(carrier_matrix, ones(size(carrier_matrix,1),size(carrier_matrix,2))); % 由极坐标向复数坐标转化第一参数为相位第二参数为幅度%---------------------------------------% Carrier_matrix contains all the phase information and all the amplitudes are the same,‘1’% 函数说明:极或柱坐标变为直角坐标% POL2CART Transform polar to Cartesian coordinates.% [X,Y] = POL2CART(TH,R) transforms corresponding elements of data% stored in polar coordinates (angle TH, radius R) to Cartesian% coordinates X,Y. The arrays TH and R must the same size (or% either can be scalar). TH must be in radians.% [X,Y,Z] = POL2CART(TH,R,Z) transforms corresponding elements of% data stored in cylindrical coordinates (angle TH, radius R, height Z)% to Cartesian coordinates X,Y,Z. The arrays TH, R, and Z must be% the same size (or any of them can be scalar). TH must be in radians.%---------------------------------------complex_carrier_matrix = complex(X,Y);%---------------------------------------% 函数说明:% COMPLEX Construct complex result from real and imaginary parts.% C = COMPLEX(A,B) returns the complex result A + Bi, where A and B are% identically sized real N-D arrays, matrices, or scalars of the same data type.%% Assign each carrier to its IFFT bin% - each row of complex_carrier_matrix represents one symbol period, with% a symbol for each carrier% - a matrix is generated to represent all IFFT bins (columns) and all% symbols (rows)% - the phase modulation for each carrier is then assigned to the% appropriate bin% - the conjugate of the phase modulation is then assigned to the% appropriate bin% - the phase modulation bins and their conjugates are symmetric about% the Nyquist frequency in the IFFT bins% - since the first bin is DC, the Nyquist Frequency is located% at (number of bins/2) + 1% - symmetric conjugates are generated so that when the signal is% transformed to the time domain, the time signal will be real-valued% - example% - 1024 IFFT bins% - bin 513 is the center (symmetry point)% - bin 1 is DC% - bin 514 is the complex conjugate of bin 512% - bin 515 is the complex conjugate of bin 511% - ....% - bin 1024 is the complex conjugate of bin 2 (if all bins% were used as carriers)% - So, bins 2-512 map to bins 1024-514%---------------------------------------%--------------------------------------% % 添加训练序列% %--------------------------------------% training_symbols = [ 1 j j 1 -1 -j -j -1 1 j j 1 -1 -j -j -1 1 j j 1 -1 -j -j -1 1 j j 1 -1 -j -j -1 1 j j 1 -1 ...-j -j -1 1 j j 1 -1 -j -j -1 1 j j 1 -1 -j -j -1 1 j j 1 -1 -j -j -1 1 j j 1 -1 -j -j -1 1 j j 1 -1 -j -j -1 ...1 j j 1 -1 -j -j -1 1 j j 1 -1 -j -j -1 1 j j 1 -1 -j -j -1 1 j j 1 -1 -j -j -1 1 j j 1 -1 -j -j -1 1 j j 1 ...-1 -j -j -1 1 j j 1 -1 -j -j -1 1 j j 1 -1 -j -j -1 1 j j 1 -1 -j -j -1 1 j j 1 -1 -j -j -1 1 j j 1 -1 -j -j ...-1 1 j j 1 -1 -j -j -1 1 j j 1 -1 -j -j -1 1 j j 1 -1 -j -j -1 1 j j 1 -1 -j -j -1 ];%---------------------------------------% 25 times "1 j j 1"% 25 times "-1 -j -j -1"% totally 200 symbols as a row%---------------------------------------training_symbols = cat(1, training_symbols, training_symbols) ;training_symbols = cat(1, training_symbols, training_symbols) ;%---------------------------------------% Production of 4 rows of training_symbols% 函数说明:串接成高维数组% CAT Concatenate arrays.% CAT(DIM,A,B) concatenates the arrays A and B along the dimension DIM.% CAT(2,A,B) is the same as [A,B].% CAT(1,A,B) is the same as [A;B].% B = CAT(DIM,A1,A2,A3,A4,...) concatenates the input% arrays A1, A2, etc. along the dimension DIM.%---------------------------------------complex_carrier_matrix = cat(1, training_symbols, complex_carrier_matrix);%---------------------------------------% 训练序列与数据合并,串接成高维数组% block-type pilot symbols%---------------------------------------IFFT_modulation = zeros(4 + symbols_per_carrier + 1, IFFT_bin_length);%---------------------------------------% Here a row vector of zeros is between training symbols and data symbols% 4 training symbols and 1 zero symbol% every OFDM symbol takes a row of "IFFT_modulation"%---------------------------------------IFFT_modulation(:,carriers) = complex_carrier_matrix;IFFT_modulation(:,conjugate_carriers) = conj(complex_carrier_matrix);%---------------------------------------% Find the indices of zeros% Description% ZC = conj(Z) returns the complex conjugate of the elements of Z.% AlgorithmIf Z is a complex array: conj(Z) = real(Z) - i*imag(Z)%---------------------------------------time_wave_matrix = ifft(IFFT_modulation'); % 进行IFFT操作time_wave_matrix = time_wave_matrix'; % 进行矩阵转置cp_add = zeros(4 + symbols_per_carrier + 1,cp_length);for i = 1:4 + symbols_per_carrier + 1cp_add(i,:) = time_wave_matrix(i,(IFFT_bin_length - cp_length + 1) : IFFT_bin_length);endtime_wave_matrix_cp = [cp_add,time_wave_matrix];for i = 1: 4 + symbols_per_carrier + 1 % windowed_time_wave_matrix(i,:) = real(time_wave_matrix(i,:)) .* hamming(IFFT_bin_length)';windowed_time_wave_matrix_cp(i,:) = real(time_wave_matrix_cp(i,:));end%---------------------------------------% Serialize the modulating waveform% - sequentially take each row of windowed_time_wave_matrix and construct a row vector % - the row vector will be the modulating signal% - note that windowed_time_wave_matrix is transposed, this is to account for the way the % Matlab 'reshape' function works (reshape takes the columns of the target matrix and% appends them sequentially)% get the real part of the result of IFFT% 这一步可以省略,因为IFFT结果都是实数% 由此可以看出,只是取了IFFT之后载波上的点,并未进行CP的复制和添加end%---------------------------------------ofdm_modulation = reshape(windowed_time_wave_matrix_cp', 1, (IFFT_bin_length + cp_length)*(4 + symbols_per_carrier+1)); % P2S operation%---------------------------------------Tx_data = ofdm_modulation;%---------------------------------------% 信道模拟%---------------------------------------% The channel model is Gaussian (AWGN) only% - Rayleigh fading would be a useful addition%---------------------------------------d1 = 40; a1 = 0.2; d2 = 50; a2 = 0.3; d3 = 60; a3 = 0.4;%d4 = 160; a4 = 0.9;copy1 = zeros(size(Tx_data)) ;for i = 1 + d1: length(Tx_data)copy1(i) = a1*Tx_data( i - d1) ;endcopy2 = zeros(size(Tx_data) ) ;for i = 1 + d2: length( Tx_data)copy2(i) = a2*Tx_data( i - d2) ;endcopy3 = zeros(size(Tx_data) ) ;for i = 1 + d3: length(Tx_data)copy3(i) = a3*Tx_data ( i - d3) ;endcopy4 = zeros(size(Tx_data) ) ;for i = 1 + d4: length( Tx_data)copy4(i) = a4*Tx_data(i - d4) ;endTx_data = Tx_data + copy1 + copy2 + copy3 + copy4; % 4 multi-pathsTx_signal_power = var(Tx_data);%-------------------------------------------------------------------------% 函数说明:% VAR Variance.% For vectors, Y = VAR(X) returns the variance of the values in X. For% matrices, Y is a row vector containing the variance of each column of% X.%-------------------------------------------------------------------------linear_SNR = 10^(SNR/10);noise_sigma = Tx_signal_power/linear_SNR;noise_scale_factor = sqrt(noise_sigma);%noise = randn(1, length(Tx_data))*noise_scale_factor;Rx_Data = Tx_data + noise;%Rx_Data = Tx_data;%-------------------------------------------------------------------------% 函数说明:产生正态分布的随机函数% Y = randn(m,n) or Y = randn([m n]) returns an m-by-n matrix of random% entries.% The randn function generates arrays of random numbers whose elements are% normally distributed with mean 0 and variance 1.%-------------------------------------------------------------------------% --------------------------------------------- %% 信号接收%% --------------------------------------------- %%-------------------------------------------------------------------------Rx_Data_matrix_cp = reshape(Rx_Data, IFFT_bin_length + cp_length, 4 + symbols_per_carrier + 1);Rx_Data_matrix_cp = Rx_Data_matrix_cp';Rx_Data_matrix = zeros(4 + symbols_per_carrier + 1,IFFT_bin_length);for i = 1:4 + symbols_per_carrier + 1Rx_Data_matrix(i,:) = Rx_Data_matrix_cp(i,(cp_length + 1):(IFFT_bin_length + cp_length)); endRx_Data_matrix = Rx_Data_matrix';%-------------------------------------------------------------------------% Transform each symbol from time to frequency domain% - take the fft of each column%-------------------------------------------------------------------------Rx_spectrum = fft(Rx_Data_matrix);%-------------------------------------------------------------------------% Suppose precise synchronazition between Tx and RxRx_carriers = Rx_spectrum(carriers,:)';Rx_training_symbols = Rx_carriers( (1: 4) , : ) ;Rx_carriers = Rx_carriers((5: 55), : ) ;% --------------------------------------------- %% 信道估计%% --------------------------------------------- %Rx_training_symbols = Rx_training_symbols./ training_symbols;Rx_training_symbols_deno = Rx_training_symbols.^2;Rx_training_symbols_deno = Rx_training_symbols_deno(1,:)+Rx_training_symbols_deno(2,:)+Rx_training_symbols_deno(3,:)+ Rx_training_symbols_deno(4,:) ;Rx_training_symbols_nume = Rx_training_symbols(1, : ) +Rx_training_symbols(2, : ) + Rx_training_symbols(3, : ) +Rx_training_symbols(4, : ) ;Rx_training_symbols_nume = conj(Rx_training_symbols_nume) ;%-------------------------------------------------------------------------% 取4个向量的导频符号是为了进行平均优化% 都是针对“行向量”即单个的OFDM符号进行操作% 原理:寻求1/H,对FFT之后的数据进行频域补偿% 1/H = conj(H)/H^2 because H^2 = H * conj(H)%-------------------------------------------------------------------------Rx_training_symbols = Rx_training_symbols_nume./Rx_training_symbols_deno;Rx_training_symbols_2 = cat(1, Rx_training_symbols,Rx_training_symbols) ;Rx_training_symbols_4 = cat(1, Rx_training_symbols_2,Rx_training_symbols_2) ;Rx_training_symbols_8 = cat(1, Rx_training_symbols_4,Rx_training_symbols_4) ;Rx_training_symbols_16 = cat(1, Rx_training_symbols_8, Rx_training_symbols_8) ;Rx_training_symbols_32 = cat(1, Rx_training_symbols_16, Rx_training_symbols_16) ;Rx_training_symbols_48 = cat(1, Rx_training_symbols_32, Rx_training_symbols_16) ;Rx_training_symbols_50 = cat(1, Rx_training_symbols_48, Rx_training_symbols_2) ;Rx_training_symbols = cat(1, Rx_training_symbols_50,Rx_training_symbols) ;Rx_carriers = Rx_training_symbols.*Rx_carriers;%-------------------------------------------------------------------------% 进行频域单抽头均衡%-------------------------------------------------------------------------Rx_phase = angle(Rx_carriers)*(180/pi);phase_negative = find(Rx_phase < 0);%-------------------------------------------------------------------------% 函数说明:找出非零元素的索引号% FIND Find indices of nonzero elements.% I = FIND(X) returns the linear indices of the array X that are nonzero.% X may be a logical expression. Use IND2SUB(I,SIZE(X)) to calculate% multiple subscripts from the linear indices I.%---------------------------------------------------------------------------Rx_phase( phase_negative );Rx_phase(phase_negative) = rem(Rx_phase(phase_negative) + 360, 360) ;% 把负的相位转化为正的相位Rx_decoded_phase = diff(Rx_phase) ;% 这也是为什么要在前面加上初始相位的原因% “Here a row vector of zeros is between training symbols and data symbols”%-------------------------------------------------------------------------% 函数说明:% DIFF Difference and approximate derivative.% DIFF(X), for a vector X, is [X(2)-X(1) X(3)-X(2) ... X(n)-X(n-1)].% DIFF(X), for a matrix X, is the matrix of row differences,% [X(2:n,:) - X(1:n-1,:)].%------------------------Test Codes --------------------------------------% a = [1 2 3; 4 5 6; 7 8 9; 10 11 12];% b = a;% for i = 2:4% b(i,:) = b(i-1,:) + b(i,:);% end% c = diff(b);%-----------------------Test Result --------------------------------------% a = Modulating signal% 1 2 3% 4 5 6% 7 8 9% 10 11 12% b = Modulated signal% 1 2 3% 5 7 9% 12 15 18% 22 26 30% c = Recovered signal% 4 5 6% 7 8 9% 10 11 12% ----------------------------------------------------------------------------% Name Size Bytes Class% Rx_phase 51x200 81600 double array% Rx_decoded_phase 50x200 80000 double array% ----------------------------------------------------------------------------phase_negative = find(Rx_decoded_phase < 0) ;Rx_decoded_phase(phase_negative)= rem(Rx_decoded_phase(phase_negative) + 360, 360) ;% ----------------------------------------------------------------------------% Extract phase differences (from the differential encoding)% - the matlab diff( ) function is perfect for this operation% - again, normalize the result to be between 0 and 359 degrees% 再次把负的相位转化为正的相位% ----------------------------------------------------------------------------% --------------------------------------------- %% QDPSK解调%% --------------------------------------------- %base_phase = 360 /2^bits_per_symbol;delta_phase = base_phase /2;Rx_decoded_symbols = zeros(size(Rx_decoded_phase,1),size(Rx_decoded_phase,2)) ;%for i = 1: (2^bits_per_symbol - 1)center_phase = base_phase*i;plus_delta = center_phase + delta_phase; % Decision threshold 1minus_delta = center_phase - delta_phase; % Decision threshold 2decoded = find((Rx_decoded_phase <= plus_delta)&(Rx_decoded_phase > minus_delta)) ;Rx_decoded_symbols(decoded) = i;end% ----------------------------------------------------------------------------% 仅仅对三个区域进行判决% 剩下的区域就是零相位的空间了% 这个区域在定义解调矩阵时已经定义为零% ----------------------------------------------------------------------------Rx_serial_symbols = reshape(Rx_decoded_symbols',1,size(Rx_decoded_symbols, 1)*size(Rx_decoded_symbols,2)) ;for i = bits_per_symbol: -1: 1if i ~= 1Rx_binary_matrix(i, : ) = rem(Rx_serial_symbols, 2) ;Rx_serial_symbols = floor(Rx_serial_symbols/2) ;elseRx_binary_matrix( i, : ) = Rx_serial_symbols;endend % Integer to binarybaseband_in = reshape(Rx_binary_matrix, 1,size(Rx_binary_matrix, 1)*size(Rx_binary_matrix, 2) ) ; % --------------------------------------------- %% 误码率计算%% --------------------------------------------- %bit_errors = find(baseband_in ~= baseband_out) ; % find的结果其每个元素为满足逻辑条件的输入向量的标号,其向量长度也就是收发不一样的bit的个数bit_error_count = size(bit_errors, 2) ;total_bits = size( baseband_out, 2) ;bit_error_rate = bit_error_count/ total_bits;fprintf ( '%f \n',bit_error_rate) ;。
Matlab简单的OFDM仿真,信道估计,有BER曲线
![Matlab简单的OFDM仿真,信道估计,有BER曲线](https://img.taocdn.com/s3/m/823a9af484254b35eefd345f.png)
clear all。
close all。
fprintf( '\n OFDM仿真\n \n'> 。
% --------------------------------------------- %% 参数定义%% --------------------------------------------- %IFFT_bin_length = 1024。
carrier_count = 200。
bits_per_symbol = 2。
symbols_per_carrier = 50。
% 子载波数200% 位数/ 符号 2% 符号数/ 载波50% 训练符号数10% 循环前缀长度T/4<作者注明)All-zero CP % 调制方式QDPSK% 多径信道数 2、3、4<缺省)% 信道最大时延7 (单位数据符号>% 仿真条件收发之间严格同步 %SNR=input('SNR='>。
% 输入信噪比参数SNR=3:14。
%定义信噪比范围BER=zeros(1,length(SNR>>。
baseband_out_length = carrier_count * symbols_per_carrier * bits_per_symbol。
% 计算发送的二进制序列长度carriers = (1: carrier_count> + (floor(IFFT_bin_length/4> - floor(carrier_count/2>>。
% 坐标: (1 to 200> + 156 , 157 -- 356conjugate_carriers=IFFT_bin_length-carriers+2。
% 坐标:1024 - (157:356> + 2 = 1026 - (157:356> = (869:670> % 构造共轭时间-载波矩阵,以便应用所谓的RCC,Reduced Computational Complexity算法,即i fft之后结果为实数% Define the conjugate time-carrier matrix% 也可以用flipdim函数构造对称共轭矩阵% --------------------------------------------- %% 信号发射%% --------------------------------------------- %%out = rand(1,baseband_out_length>。
OFDM技术仿真(MATLAB代码)..
![OFDM技术仿真(MATLAB代码)..](https://img.taocdn.com/s3/m/f04f4645be23482fb4da4cb3.png)
第一章绪论1.1简述OFDM是一种特殊的多载波传输方案,它可以被看作是一种调制技术,也可以被当作一种复用技术。
多载波传输把数据流分解成若干子比特流,这样每个子数据流将具有低得多的比特速率,用这样的低比特率形成的低速率多状态符号再去调制相应的子载波,就构成多个低速率符号并行发送的传输系统。
正交频分复用是对多载波调制(MCM,Multi-Carrier Modulation)的一种改进。
它的特点是各子载波相互正交,所以扩频调制后的频谱可以相互重叠,不但减小了子载波间的干扰,还大大提高了频谱利用率。
符号间干扰是多径衰落信道宽带传输的主要问题,多载波调制技术包括正交频分复用(OFDM)是解决这一难题中最具前景的方法和技术。
利用OFDM技术和IFFT方式的数字实现更适宜于多径影响较为显著的环境,如高速WLAN 和数字视频广播DVB等。
OFDM作为一种高效传输技术备受关注,并已成为第4代移动通信的核心技术。
如果进行OFDM系统的研究,建立一个完整的OFDM 系统是必要的。
本文在简要介绍了OFDM 基本原理后,基于MATLAB构建了一个完整的OFDM动态仿真系统。
1.2 OFDM基本原理概述1.2.1 OFDM的产生和发展OFDM的思想早在20世纪60年代就已经提出,由于使用模拟滤波器实现起来的系统复杂度较高,所以一直没有发展起来。
在20世纪70年代,提出用离散傅里叶变换(DFT)实现多载波调制,为OFDM的实用化奠定了理论基础;从此以后,OFDM在移动通信中的应用得到了迅猛的发展。
OFDM系统收发机的典型框图如图1.1所示,发送端将被传输的数字信号转换成子载波幅度和相位的映射,并进行离散傅里叶变换(IDFT)将数据的频谱表达式变换到时域上。
IFFT变换与IDFT变换的作用相同,只是有更高的计算效基于MATLAB实现OFDM的仿真率,所以适用于所有的应用系统。
其中,上半部分对应于发射机链路,下半部分对应于接收机链路。
Matlab简单的OFDM仿真-信道估计-有BER曲线
![Matlab简单的OFDM仿真-信道估计-有BER曲线](https://img.taocdn.com/s3/m/a8297abda76e58fafbb00371.png)
close all;fprintf( '\n OFDM 仿真\n \n') ;% -------------------------------------------- %% 参数定义%% -------------------------------------------- %IFFT_bin_length = 1024; carrier_count = 200;bits_per_symbol = 2; symbols_per_carrier = 50;% 子载波数200% 位数/ 符号2% 符号数/ 载波50% 训练符号数10% 循环前缀长度T/4 (作者注明) All-zero CP% 调制方式QDPSK% 多径信道数 2 、3、4(缺省)% 信道最大时延7 ( 单位数据符号)% 仿真条件收发之间严格同步%SNR=input('SNR='); % 输入信噪比参数SNR=3:14;淀义信噪比范围BER=zeros(1,length(SNR));baseband_out_length = carrier_count * symbols_per_carrier * bits_per_symbol;% 计算发送的二进制序列长度carriers = (1: carrier_count) + (floor(IFFT_bin_length/4) - floor(carrier_count/2)); % 坐标:(1 to 200) + 156 , 157 -- 356 conjugate_carriers=IFFT_bin_length-carriers+2; % 坐标:1024 - (157:356) + 2 = 1026 - (157:356) = (869:670)% 构造共轭时间-载波矩阵,以便应用所谓的RCC,Reduced Computational Complexity 算法,即i fft 之后结果为实数% Define the conjugate time-carrier matrix% 也可以用flipdim 函数构造对称共轭矩阵% -------------------------------------------- %% 信号发射%% -------------------------------------------- % %out = rand(1,baseband_out_length);%baseband_out1 = round(out) ;%baseband_out2 = floor(out*2) ;%baseband_out3 = ceil(out*2)-1 ;%baseband_out4 = randint(1,baseband_out_length);% 四种生成发送的二进制序列的方法,任取一种产生要发送的二进制序列%if (baseband_out1 == baseband_out2 & baseband_out1 == baseband_out3 )% fprintf('Transmission Sequence Generated \n \n');% baseband_out = baseband_out1 ;%else% fprintf('Check Code!!!!!!!!!!!!!!!!!!!!! \n \n');% 验证四种生成发送的二进制序列的方法baseband_out=round( rand(1,baseband_out_length)); convert_matrixreshape(baseband_out,bits_per_symbol,length(baseband_out)/bits_per_sy mbol); for k = 1length(baseband_out)/bits_per_symbol), modulo_baseband(k) = 0;for i = 1:bits_per_symbolmodulo_baseband(k) = modulo_baseband(k) + convert_matrix(i,k)*2A(bits_per_symbol - i);endend% 每2 个比特转化为整数0 至3%采用'left-msb' 方式% ------------------------------------------------------------------- % Test by lavabin% A built-in function of directly change binary bits into decimal numbers% ------------------------------------------------------------------- %convert_matrix1zeros(length(baseband_out)/bits_per_symbol,bits_per_symbol);%convert_matrix1 = convert_matrix' ;%Test_convert_matrix1 bi2de(convert_matrix1,bits_per_symbol,'left-msb');%Test_convert_matrix2 bi2de(convert_matrix1,bits_per_symbol,'right-msb');% 函数说明:% BI2DE Convert binary vectors to decimal numbers.% D = BI2DE(B) converts a binary vector B to a decimal value D. When Bis% a matrix, the conversion is performed row-wise and the output D is a% column vector of decimal values. The default orientation of thebinary% input is Right-MSB; the first element in B represents the least significant bit.%if (modulo_baseband == Test_convert_matrix1')% fprintf('modulo_baseband = Test_convert_matrix1 \n\n\n');%else if (modulo_baseband == Test_convert_matrix2')% fprintf('modulo_baseband = Test_convert_matrix2 \n\n\n');% else% fprintf('modulo_baseband ~= any Test_convert_matrix \n\n\n');% end%end% we get the result "modulo_baseband = Test_convert_matrix1".% ------------------------------------------------------------------- carrier_matrixreshape(modulo_baseband,carrier_count,symbols_per_carrier)'; % 生成时间-载波矩阵% -------------------------------------------- %% QDPSK 调制%% -------------------------------------------- % carrier_matrix = [zeros(1,carrier_count); carrier_matrix]; % 添加一个差分调制的初始相位,为0 for i = 2symbols_per_carrier + 1)carrier_matrix(i, = rem(carrier_matrix(i, + carrier_matrix (i-1,,2Abits_per_symbol) ; % 差分调制carrier_matrix = carrier_matrix*((2*pi)/(2A bits_per_symbol)) ; % 产生差分相位[X, Y]=pol2cart(carrier_matrix,ones(size(carrier_matrix,1),size(carrier_matrix,2))); % 由极坐标向复数坐标转化第一参数为相位第二参数为幅度%Carrier_matrix contains all the phase information and all the amplitudes are the same ‘1'.complex_carrier_matrix = complex(X, Y) ;%添加训练序列'training_symbols = [ 1 j j 1 -1 -j -j -1 1 j j 1 -1 -j -j -1 1 j j 1 -1-j -j -1 1 j j 1 -1 -j -j -1 1 j j 1 -1 ...-j -j -1 1 j j 1 -1 -j -j -1 1 j j 1 -1 -j -j -1 1 j j 1 -1 -j -j -1 1j j 1 -1 -j -j -1 1 j j 1 -1 -j -j -1 ...1 j j 1 -1 -j -j -1 1 j j 1 -1 -j -j -1 1 j j 1 -1 -j -j -1 1 j j 1 -1-j -j -1 1 j j 1 -1 -j -j -1 1 j j 1 ...-1 -j -j -1 1 j j 1 -1 -j -j -1 1 j j 1 -1 -j -j -1 1 j j 1 -1 -j -j -11 j j 1 -1 -j -j -1 1 j j 1 -1 -j -j ...-1 1 j j 1 -1 -j -j -1 1 j j 1 -1 -j -j -1 1 j j 1 -1 -j -j -1 1 j j 1-1 -j -j -1 ]; % 25 times "1 j j 1" , 25 times "-1 -j -j -1", totally 200 symbols as a row training_symbols = cat(1, training_symbols, training_symbols) ;training_symbols = cat(1, training_symbols, training_symbols) ; % Production of 4 rows of training_symbols complex_carrier_matrix = cat(1,training_symbols,complex_carrier_matrix) ; % 训练序列与数据合并% block-type pilot symbolsIFFT_modulation = zeros(4 + symbols_per_carrier + 1,IFFT_bin_length) ;% Here a row vector of zeros is between training symbols and data symbols!!!% 4 training symbols and 1 zero symbol% every OFDM symbol takes a row of "IFFT_modulation"IFFT_modulation(: , carriers) = complex_carrier_matrix;IFFT_modulation(: , conjugate_carriers) = conj(complex_carrier_matrix)% -------------------------------------------------------------------% Test by lavabin -- Find the indices of zeros%index_of_zeros = zeros(symbols_per_carrier,IFFT_bin_length 2*carrier_count);%IFFT_modulation1 = zeros(4 + symbols_per_carrier +1,IFFT_bin_length); %IFFT_modulation2 = zeros(4 + symbols_per_carrier +1,IFFT_bin_length); %IFFT_modulation1(6:symbols_per_carrier+5,IFFT_modulation(6:symbols_per_carrier+5,==0 ;%for i = 1:symbols_per_carrier %index_of_zeros(i, =find(IFFT_modulation1(i+5,==1);%end% -------------------------------------------------------------------time_wave_matrix = ifft(IFFT_modulation') ; % 进行IFFT 操作time_wave_matrix = time_wave_matrix'; %If X is a matrix, ifft returns the inverse Fourier transform of each column of the matrix.for i = 1: 4 + symbols_per_carrier + 1windowed_time_wave_matrix( i, : ) = real(time_wave_matrix( i, : )) end% get the real part of the result of IFFT% 这一步可以省略,因为IFFT 结果都是实数% 由此可以看出,只是取了IFFT 之后载波上的点,并未进行CP 的复制和添加end ofdm_modulation = reshape(windowed_time_wave_matrix',1, IFFT_bin_length*(4 + symbols_per_carrier + 1) ) ;% P2S operation% -------------------------------------------------------------------% Test by lavabin% Another way of matrix transition%ofdm_modulation_tmp = windowed_time_wave_matrix.'; %ofdm_modulation_test = ofdm_modulation_tmp(';%if (ofdm_modulation_test == ofdm_modulation)% fprintf('ofdm_modulation_test == ofdm_modulation \n\n\n');%else%fprintf('ofdm_modulation_test ~= ofdm_modulation \n\n\n');%end% We get the result "ofdm_modulation_test == ofdm_modulation" .% -------------------------------------------------------------------Tx_data=ofdm_modulation;% -------------------------------------------- %% 信道模拟%% -------------------------------------------- % d1= 4; a1 = 0.2; d2 = 5; a2 = 0.3; d3 = 6; a3 = 0.4; d4 = 7; a4 = 0.5; % 信道模拟copy1 = zeros(size(Tx_data)) ;for i = 1 + d1: length(Tx_data) copy1(i) = a1*Tx_data( i - d1) ;endcopy2 = zeros(size(Tx_data) ) ;for i = 1 + d2: length( Tx_data)copy2(i) = a2*Tx_data( i - d2) ;endcopy3 = zeros(size(Tx_data) ) ;for i = 1 + d3: length(Tx_data)copy3(i) = a3*Tx_data ( i - d3) ;endcopy4 = zeros(size(Tx_data) ) ;for i = 1 + d4: length( Tx_data)copy4(i) = a4*Tx_data(i - d4) ;endTx_data = Tx_data + copy1 + copy2 + copy3 + copy4; % 4 multi-pathsTx_signal_power = var(Tx_data);for idx=1:length(SNR)%monte carlo 仿真模拟lin ear_SNR = 10A( SNR(idx) /10);noise_sigma = Tx_signal_power / linear_SNR; noise_scale_factor =sqrt(noise_sigma) ;noise = randn(1, length(Tx_data) )*noise_scale_factor;Rx_Data = Tx_data + noise;% -------------------------------------------- %% 信号接收%% -------------------------------------------- %Rx_Data_matrix = reshape(Rx_Data, IFFT_bin_length, 4 + symbols_per_carrier + 1) ;Rx_spectrum = fft(Rx_Data_matrix) ;% Suppose precise synchronazition between Tx and Rx Rx_carriers = Rx_spectrum( carriers, : )';Rx_training_symbols = Rx_carriers( (1: 4) , : ) ; Rx_carriers = Rx_carriers((5: 55), : ) ; % -------------------------------------------- % % 计% % -------------------------------------------- %Rx_training_symbols = Rx_training_symbols./ training_symbols; Rx_trai nin g_symbols_de no = Rx_trai nin g_symbols42; Rx_training_symbols_deno=Rx_training_symbols_deno(1,+Rx_training_symbols_deno(2,+Rx_training_s ymbols_deno(3,+Rx_training_symbols_deno(4, ;Rx_training_symbols_nume = Rx_training_symbols(1, : ) +Rx_training_symbols(2, : ) + Rx_training_symbols(3, : )+Rx_training_symbols(4, : ) ;Rx_training_symbols_nume = conj(Rx_training_symbols_nume) ; % 取 4 个向量的导频符号是为了进行平均 优化%都是针对 “行向量”即单个的OFDM 符号 进行操作%原理:寻求1/H ,对FFT 之后的数据进行频域补偿 % 1/H = conj(H)/H A 2 because 屮2 = H * conj(H) Rx_training_symbols = Rx_training_symbols_nume./Rx_training_symbols_deno; Rx_training_symbols = Rx_training_symbols_nume./Rx_training_symbols_deno; Rx_training_symbols_2 = cat(1, Rx_training_symbols,Rx_training_symbols) ; Rx_training_symbols_4 = cat(1, Rx_training_symbols_2,Rx_training_symbols_2) ; Rx_training_symbols_8 = cat(1, Rx_training_symbols_4,Rx_training_symbols_4) ; Rx_training_symbols_16 Rx_training_symbols_8) ; Rx_training_symbols_32 Rx_training_symbols_16) ; Rx_training_symbols_48 Rx_training_symbols_16) ; Rx_training_symbols_50 Rx_training_symbols_2) ;Rx_training_symbolsRx_training_symbols_50,Rx_training_symbols) ; Rx_carriers = Rx_training_symbols.*Rx_carriers; % Rx_phase = angle(Rx_carriers)*(180/pi) ; phase_negative = find(Rx_phase < 0) ;cat(1, Rx_training_symbols_8, cat(1, Rx_training_symbols_16, cat(1, Rx_training_symbols_32, cat(1, Rx_training_symbols_48, 信道估 cat(1, 进行频域单抽头均衡% --------------------- Test of Using"rem" --------------------------------%Rx_phase1 = Rx_phase;%Rx_phase2 = Rx_phase;%Rx_phase1(phase_negative) = rem(Rx_phase1(phase_negative) + 360,360) ; %Rx_phase2(phase_negative) = Rx_phase2(phase_negative) + 360 ;%if Rx_phase2(phase_negative) == Rx_phase1(phase_negative)% fprintf('\n There is no need using rem in negative phase transition.\n')%else% fprintf('\n We need to use rem in negative phase transition.\n')%end% -------------------------------------------------------------------Rx_phase(phase_negative) = rem(Rx_phase(phase_negative) + 360, 360) ; % 把负的相位转化为正的相位Rx_decoded_phase = diff(Rx_phase) ;% 这也是为什么要在前面加上初始相位的原因% “ Here a row vector of zeros is between training symbols and data symbols!!! ”phase_negative = find(Rx_decoded_phase < 0) ;Rx_decoded_phase(phase_negative)= rem(Rx_decoded_phase(phase_negative)+ 360, 360) ; % 再次把负的相位转化为正的相位% -------------------------------------------- %% QDPSK 解调%% -------------------------------------------- % base_phase = 360 /2A bits_per_symbol;delta_phase = base_phase /2;Rx_decoded_symbols = zeros(size(Rx_decoded_phase,1),size(Rx_decoded_phase,2)) ;for i = 1: (2Abits_per_symbol - 1)center_phase = base_phase*i;plus_delta = center_phase + delta_phase; % Decision threshold 1minus_delta = center_phase - delta_phase; % Decision threshold 2 decoded = find((Rx_decoded_phase <= plus_delta)&(Rx_decoded_phase > minus_delta)) ;Rx_decoded_symbols(decoded) = i;end% 仅仅对三个区域进行判决% 剩下的区域就是零相位的空间了% 这个区域在定义解调矩阵时已经定义为零Rx_serial_symbols = reshape(Rx_decoded_symbols',1,size(Rx_decoded_symbols, 1)*size(Rx_decoded_symbols,2)) ;for i = bits_per_symbol: -1: 1if i ~= 1Rx_binary_matrix(i, : ) = rem(Rx_serial_symbols, 2) ;Rx_serial_symbols = floor(Rx_serial_symbols/2) ;elseRx_binary_matrix( i, : ) = Rx_serial_symbols;endend% Integer to binarybaseband_in = reshape(Rx_binary_matrix, 1,size(Rx_binary_matrix,1)*size(Rx_binary_matrix, 2) ) ;% -------------------------------------------- %% 误码率计算%% -------------------------------------------- %%bit_ error s(idx) = find(baseband_in ~= baseband_out) ;% find 的结果其每个元素为满足逻辑条件的输入向量的标号,其向量长度也就是收发不一样的bit 的个数%bit_error_count(idx) = size(bit_errors, 2) ;%total_bits = size( baseband_out, 2) ; %bit_error_rate = bit_error_count/ total_bits; %fprintf ( '%f \n',bit_error_rate) ;[number_err(idx),BER(idx)] = biterr(baseband_out,baseband_in ) ;endsemilogy(SNR,BER,'r*');legend('OFDM BER-SNR'); xlabel('SNR (dB)'); ylabel('BER'); title('OFDM');grid on;% -------------------------------------------- %% The END %% -------------------------------------------- %% %1•该程序进行了简单的LMS信道估计,没有加入与MMS等其他信道估计算法的比较;%%2.仿真条件为系统处于理想同步情况下Fife £dit Vjew [rsert T CJO I S Desktop Window tJelp□固怎|脣皑凹®運掃打口| □罔|・口血m In |OFDM1010'2ccLUw310InnJI5 6 7 6 9 10 11吕忖R (dB) Matlab itiL(i 10'1。
基于MATLAB的OFMD仿真实验-OFDM关键技术
![基于MATLAB的OFMD仿真实验-OFDM关键技术](https://img.taocdn.com/s3/m/34007655a55177232f60ddccda38376baf1fe036.png)
Remove short trainings
test_fine_time_sync.m
Coarse vs. Fine Time Sync
Coarse sync:
Large Range (Rc) Multiplication: 2Rc
Fine sync:
Small Range (Rf) Multiplication: Rf NL
Fine Timing Synchronization
Tx training sequence c0, c1,......, cLTB 1
Rx match filter with
c0*
,
c1*
,
......,
c* LTB
1
OFDM Signal
c0*
Tsample c1*
Tsample ……
Tsample c*
LTB 1
Start index
Max()
Fine Timing Synchronization
conj
sum
Max
Cross correlation with long training sequence
Find the maximum correlated point
CFO has been compensated
test_channel_est.m test_channel_equ.m
Zero Forcing Equalization
Phase Compensation
test_phase_track.m
做补偿:*exp(-j*Phase) 这部分可以不作为重点
freq_data [52,Nsym]
Data subcarriers freq_data_syms [48, Nsym]
ofdm matlab代码
![ofdm matlab代码](https://img.taocdn.com/s3/m/936b7623453610661ed9f452.png)
end
%********************** Output result ***************************
per=eop/nop;
ber=noe/nod;
fprintf('%f\t%e\t%e\t%d\t\n',ebn0,ber,per,nloop);
% direct wave.
itau = [0];
% Mean power for each multipath normalized by direct wave.
% If you would like to simulate under one path fading model, you have only to set
% You can insert your favorite value
fd=320;
% You can decide two mode to simulate fading by changing the variable flat
% flat : flat fading or not
rx=ich5+qch5.*i;
ry=fft(rx); % fft : built in function
ich6=real(ry); % real : built in function
qch6=imag(ry); % imag : built in function
%***************** demoduration *******************
ich7=ich6./kmod;
qch7=qch6./kmod;
[demodata]=qpskdemod(ich7,qch7,para,nd,ml);
OFDM完整仿真过程及解释(MATLAB)
![OFDM完整仿真过程及解释(MATLAB)](https://img.taocdn.com/s3/m/92f378b7d1d233d4b14e852458fb770bf78a3bf6.png)
OFDM完整仿真过程及解释(MATLAB)OFDM(正交频分复用)是一种多载波调制技术,在无线通信系统中得到广泛应用。
其基本原理是将高速数据流分成多个较低速的子载波,使得每个子载波的传输速率降低,从而提高了系统的可靠性和抗干扰性能。
以下是OFDM的完整仿真过程及解释。
1. 生成数据:首先,在MATLAB中生成需要传输的二进制数据,可以使用随机数生成函数randi(生成0和1的二进制序列。
2.编码:将生成的二进制数据进行编码,例如使用卷积码、块码等编码方式。
编码可以提高数据传输的可靠性,对抗信道中的噪声和干扰。
3.映射:将编码后的数据映射到调制符号,例如使用QPSK、16-QAM 等调制方式。
调制方式决定了每个符号所携带的比特数,不同调制方式具有不同的抗噪声和传输速率性能。
4.并行-串行转换:将映射后的调制符号进行并行-串行转换,将多个并行的调制符号转换为串行的数据流。
这是OFDM的关键步骤,将高速数据流分成多个较低速的子载波。
5. 添加保护间隔:为了消除多径传播引起的码间干扰,需要在串行数据流中插入保护间隔(Guard Interval),通常是循环前缀。
保护间隔使得子载波之间相互正交,从而避免了码间干扰。
6.IFFT:对添加保护间隔后的数据进行反快速傅里叶变换(IFFT),将时域信号转换为频域信号。
IFFT操作将子载波映射到频域,每个子载波代表系统的一个子信道。
7.添加导频:在OFDM符号的频域信号中添加导频,用于估计信道的频率响应和相位差。
导频通常位于频谱的首尾或者分布在整个频谱中,用于信道估计和均衡。
8.加载子载波:将导频和数据子载波合并,形成完整的OFDM符号。
数据子载波携带着编码后的数据,导频子载波用于信道估计。
9.加性高斯白噪声(AWGN)信道:将OFDM符号通过加性高斯白噪声信道进行传输。
AWGN信道是一种理想化的信道模型,可以模拟实际信道中的噪声和干扰。
10.解调:接收端对接收到的OFDM符号进行解调,包括载波恢复、频偏补偿、信道估计和均衡等操作。
基于matlab实现OFDM的编码.
![基于matlab实现OFDM的编码.](https://img.taocdn.com/s3/m/89db471576c66137ee061947.png)
clc;clear all;close all;fprintf('OFDM系统仿真\n');carrier_count=input('输入系统仿真的子载波数: \n');%子载波数128,64,32,16 symbols_per_carrier=30;%每子载波含符号数bits_per_symbol=4;%每符号含比特数,16QAM调制IFFT_bin_length=1024;%FFT点数PrefixRatio=1/4;%保护间隔与OFDM数据的比例1/6~1/4GI=PrefixRatio*IFFT_bin_length ;%每一个OFDM符号添加的循环前缀长度为1/4*IFFT_bin_length ,即256beta=1/32;%窗函数滚降系数GIP=beta*(IFFT_bin_length+GI);%循环后缀的长度40SNR=10; %信噪比dB%================信号产生=================================== baseband_out_length=carrier_count*symbols_per_carrier*bits_per_symbol;%所输入的比特数目carriers=(1:carrier_count)+(floor(IFFT_bin_length/4)-floor(carrier_count/2));%共轭对称子载波映射复数数据对应的IFFT点坐标conjugate_carriers = IFFT_bin_length - carriers + 2;%共轭对称子载波映射共轭复数对应的IFFT点坐标rand( 'twister',0); %每次产生不相同得伪随机序列baseband_out=round(rand(1,baseband_out_length));%产生待调制的二进制比特流figure(1);stem(baseband_out(1:50));title('二进制比特流')axis([0, 50, 0, 1]);%==============16QAM调制==================================== complex_carrier_matrix=qam16(baseband_out);%列向量complex_carrier_matrix=reshape(complex_carrier_matrix',carrier_count,symbols_per_carrier)';%串并转换,转换为symbols_per_carrier*carrier_count 矩阵figure(2);plot(complex_carrier_matrix,'*r');%16QAM调制后星座图title('16QAM调制后星座图')axis([-4, 4, -4, 4]);grid on%==========分配载波到指定的IFFT位置========================== IFFT_modulation=zeros(symbols_per_carrier,IFFT_bin_length);%添0组成IFFT 运算IFFT_modulation(:,carriers ) = complex_carrier_matrix ;%未添加导频信号,子载波映射在此处IFFT_modulation(:,conjugate_carriers) =conj(complex_carrier_matrix);%共轭复数映射figure(3);stem(0:IFFT_bin_length-1, abs(IFFT_modulation(2,1:IFFT_bin_length)),'b*-')grid onaxis ([0 IFFT_bin_length -0.5 4.5]);ylabel('幅值');xlabel('频率');title('OFDM载波幅度谱');figure(4);plot(0:IFFT_bin_length-1,(180/pi)*angle(IFFT_modulation(2,1:IFFT_bin_length)),'go')hold onstem(0:carriers-1, (180/pi)*angle(IFFT_modulation(2,1:carriers)),'b*-');stem(0:conjugate_carriers-1,(180/pi)*angle(IFFT_modulation(2,1:conjugate_carriers)),'b*-');axis ([0 IFFT_bin_length -200 +200])grid onylabel('相位')xlabel('频率')title('OFDM载波相位谱')%========通过IFFT将频域转化为时域,得到时域信号=============== signal_after_IFFT=ifft(IFFT_modulation,IFFT_bin_length,2);%OFDM调制即IFFT time_wave_matrix =signal_after_IFFT;%时域波形矩阵,行为每载波所含符号数,列ITTF点数,子载波映射在其内,每一行即为一个OFDM符号figure(5);plot(0:IFFT_bin_length-1,time_wave_matrix(2,:));axis([0, 700, -0.2, 0.2]);grid on;ylabel('振幅');xlabel('时间');title('一个符号周期的时域OFDM信号');%==========添加循环前缀与后缀==========================XX=zeros(symbols_per_carrier,IFFT_bin_length+GI+GIP);for k=1:symbols_per_carrier;for i=1:IFFT_bin_length;XX(k,i+GI)=signal_after_IFFT(k,i);endfor i=1:GI;XX(k,i)=signal_after_IFFT(k,i+IFFT_bin_length-GI);%添加循环前缀endfor j=1:GIP;XX(k,IFFT_bin_length+GI+j)=signal_after_IFFT(k,j);%添加循环后缀endendtime_wave_matrix_cp=XX;%添加了循环前缀与后缀的时域信号矩阵,此时一个OFDM符号长度为IFFT_bin_length+GI+GIPfigure(6);plot(0:length(time_wave_matrix_cp)-1,time_wave_matrix_cp(2,:));axis([0, 700, -0.2, 0.2]);grid on;ylabel('振幅');xlabel('时间');title('加入循环前缀后缀的OFDM波形');%==============OFDM符号加窗======================windowed_time_wave_matrix_cp=zeros(1,IFFT_bin_length+GI+GIP);for i = 1:symbols_per_carrierwindowed_time_wave_matrix_cp(i,:) = real(time_wave_matrix_cp(i,:)).*rcoswindow(beta,IFFT_bin_length+GI)';%加窗升余弦窗endfigure(7);plot(0:IFFT_bin_length-1+GI+GIP,windowed_time_wave_matrix_cp(2,:));axis([0, 700, -0.2, 0.2]);grid on;ylabel('振幅');xlabel('时间');title('加窗之后OFDM信号的波形');%========================生成发送信号======================== windowed_Tx_data=zeros(1,symbols_per_carrier*(IFFT_bin_length+GI)+GIP); windowed_Tx_data(1:IFFT_bin_length+GI+GIP)=windowed_time_wave_matrix_cp( 1,:);for i = 1:symbols_per_carrier-1 ;windowed_Tx_data((IFFT_bin_length+GI)*i+1:(IFFT_bin_length+GI)*(i+1)+GIP)= windowed_time_wave_matrix_cp(i+1,:);%循环后缀与循环前缀相叠加end%=======================并串转换=========================Tx_data_withoutwindow=reshape(time_wave_matrix_cp',(symbols_per_carrier)*(IFFT_bin_length+GI+GIP), 1)'; %不加窗,循环前缀与后缀不叠加的串行信号Tx_data=reshape(windowed_time_wave_matrix_cp',(symbols_per_carrier)*(IFFT_bi n_length+GI+GIP),1)';%加窗后,循环前缀与后缀不叠加的串行信号temp_time1 = (symbols_per_carrier)*(IFFT_bin_length+GI+GIP);%加窗后循环前缀与后缀不叠加发送总位数figure (8)subplot(2,1,1);plot(0:temp_time1-1,Tx_data);%循环前缀与后缀不叠加发送的信号波形axis([0, 8000, -0.4, 0.4]);grid onylabel('振幅');xlabel('时间');title('循环前后缀不叠加的OFDM信号')temp_time2 =symbols_per_carrier*(IFFT_bin_length+GI)+GIP;subplot(2,1,2);plot(0:temp_time2-1,windowed_Tx_data);%循环后缀与循环前缀相叠加发送信号波形axis([0, 8000, -0.4, 0.4]);grid onylabel('振幅'); xlabel('时间');title('循环前后缀叠加的OFDM信号')%=================未加窗发送信号频谱========================= symbols_per_average = ceil(symbols_per_carrier/5);avg_temp_time = (IFFT_bin_length+GI+GIP)*symbols_per_average;averages = floor(temp_time1/avg_temp_time);average_fft(1:avg_temp_time) = 0;for a = 0:(averages-1)subset_ofdm= Tx_data_withoutwindow (((a*avg_temp_time)+1):((a+1)*avg_temp_time)); subset_ofdm_f = abs(fft(subset_ofdm));average_fft = average_fft + (subset_ofdm_f/averages);endaverage_fft_log = 20*log10(average_fft);figure (9)subplot(2,1,1);plot((0:(avg_temp_time-1))/avg_temp_time, average_fft_log)hold onplot(0:1/IFFT_bin_length:1, -35, 'rd')grid onaxis([0 0.5 -40 max(average_fft_log)])ylabel('幅值(dB)')xlabel('归一化频率(0.5 = fs/2)')title('OFDM不加窗信号频谱')%===============加窗的发送信号频谱======================= symbols_per_average = ceil(symbols_per_carrier/5);%符号数的1/5avg_temp_time = (IFFT_bin_length+GI+GIP)*symbols_per_average;%点数averages = floor(temp_time1/avg_temp_time);average_fft(1:avg_temp_time) = 0;%分成5段for a = 0:(averages-1)subset_ofdm = Tx_data(((a*avg_temp_time)+1):((a+1)*avg_temp_time));%利用循环前缀后缀未叠加的串行加窗信号计算频谱subset_ofdm_f = abs(fft(subset_ofdm));%分段求频谱average_fft = average_fft + (subset_ofdm_f/averages);%总共的数据分为5段,分段进行FFT,平均相加endaverage_fft_log = 20*log10(average_fft);subplot(2,1,2)plot((0:(avg_temp_time-1))/avg_temp_time, average_fft_log)%归一化0/avg_temp_time : (avg_temp_time-1)/avg_temp_timehold onplot(0:1/IFFT_bin_length:1, -35, 'rd')grid onaxis([0 0.5 -40 max(average_fft_log)])ylabel('幅值(dB)')xlabel('归一化频率(0.5 = fs/2)')title('OFDM加窗信号频谱')%====================添加噪声=================================Tx_signal_power = var(windowed_Tx_data);%发送信号功率linear_SNR=10^(SNR/10);%线性信噪比noise_sigma=Tx_signal_power/linear_SNR;noise_scale_factor = sqrt(noise_sigma);%标准差sigmanoise=randn(1,((symbols_per_carrier)*(IFFT_bin_length+GI))+GIP)*noise_scale_fac tor;%产生正态分布噪声序列Rx_data=windowed_Tx_data +noise;%接收到的信号加噪声%============接收信号串并变换去除前缀与后缀===================Rx_data_matrix=zeros(symbols_per_carrier,IFFT_bin_length+GI+GIP);for i=1:symbols_per_carrier;Rx_data_matrix(i,:)=Rx_data(1,(i-1)*(IFFT_bin_length+GI)+1:i*(IFFT_bin_length+ GI)+GIP);%串并变换endRx_data_complex_matrix=Rx_data_matrix(:,GI+1:IFFT_bin_length+GI);%去除循环前缀与循环后缀,得到有用信号矩阵% OFDM解码%=================FFT变换=================================Y1=fft(Rx_data_complex_matrix,IFFT_bin_length,2);%OFDM解码即FFT变换Rx_carriers=Y1(:,carriers);%除去IFFT/FFT变换添加的0,选出映射的子载波Rx_phase =angle(Rx_carriers);%接收信号的相位Rx_mag = abs(Rx_carriers);%接收信号的幅度figure(10);polar(Rx_phase, Rx_mag,'bd');%极坐标中接收信号的星座图title('极坐标中接收信号的星座图')[M, N]=pol2cart(Rx_phase, Rx_mag);Rx_complex_carrier_matrix = complex(M, N);figure(11);plot(Rx_complex_carrier_matrix,'*r');%直角坐标系中接收信号的星座图title('直角坐标系中接收信号的星座图')axis([-4, 4, -4, 4]);grid on%====================并串转换,16qam解调====================== Rx_serial_complex_symbols=reshape(Rx_complex_carrier_matrix',size(Rx_complex _carrier_matrix, 1)*size(Rx_complex_carrier_matrix,2),1)' ;Rx_decoded_binary_symbols=demoduqam16(Rx_serial_complex_symbols); baseband_in = Rx_decoded_binary_symbols;figure(12);subplot(2,1,1);stem(baseband_out(1:100));title('输出待调制的二进制比特流')subplot(2,1,2);stem(baseband_in(1:100));title('接收解调后的二进制比特流')%================误码率计算=======================bit_errors=find(baseband_in ~=baseband_out);bit_error_count = size(bit_errors, 2)ber=bit_error_count/baseband_out_length。
OFDM技术仿真(MATLAB代码)
![OFDM技术仿真(MATLAB代码)](https://img.taocdn.com/s3/m/82b054aad4d8d15abe234ed9.png)
第一章绪论1.1简述OFDM是一种特殊的多载波传输方案,它可以被看作是一种调制技术,也可以被当作一种复用技术。
多载波传输把数据流分解成若干子比特流,这样每个子数据流将具有低得多的比特速率,用这样的低比特率形成的低速率多状态符号再去调制相应的子载波,就构成多个低速率符号并行发送的传输系统。
正交频分复用是对多载波调制(MCM,Multi-Carrier Modulation)的一种改进。
它的特点是各子载波相互正交,所以扩频调制后的频谱可以相互重叠,不但减小了子载波间的干扰,还大大提高了频谱利用率。
符号间干扰是多径衰落信道宽带传输的主要问题,多载波调制技术包括正交频分复用(OFDM)是解决这一难题中最具前景的方法和技术。
利用 OFDM技术和IFFT方式的数字实现更适宜于多径影响较为显著的环境,如高速 WLAN 和数字视频广播 DVB等。
OFDM作为一种高效传输技术备受关注,并已成为第4代移动通信的核心技术。
如果进行OFDM系统的研究,建立一个完整的OFDM系统是必要的。
本文在简要介绍了OFDM 基本原理后,基于MATLAB构建了一个完整的OFDM 动态仿真系统。
1.2 OFDM基本原理概述1.2.1 OFDM的产生和发展OFDM的思想早在20世纪60年代就已经提出,由于使用模拟滤波器实现起来的系统复杂度较高,所以一直没有发展起来。
在20世纪70年代,提出用离散傅里叶变换(DFT)实现多载波调制,为OFDM的实用化奠定了理论基础;从此以后,OFDM在移动通信中的应用得到了迅猛的发展。
OFDM系统收发机的典型框图如图1.1所示,发送端将被传输的数字信号转换成子载波幅度和相位的映射,并进行离散傅里叶变换(IDFT)将数据的频谱表达式变换到时域上。
IFFT变换与IDFT变换的作用相同,只是有更高的计算效率,1基于MATLAB 实现OFDM 的仿真2所以适用于所有的应用系统。
其中,上半部分对应于发射机链路,下半部分对应于接收机链路。
OFDM-MATLAB仿真程序资料
![OFDM-MATLAB仿真程序资料](https://img.taocdn.com/s3/m/c82dc7597c1cfad6185fa770.png)
OFDM.m : OFDM Simulator (outer function)clear all;A = [1 1/exp(1) 1/exp (2) ]; % power delay profileN = 64; % number of symbols in a single OFDM symbolGI = 16; % guard in tervalMt = 1; % n umber of Tx antennasMr = 1; % n umber of Rx antennassig2 = 1e-3; % no ise varia neeM = 8; % max eon stellati on bit n umberMgap = 10.A(1:(1.7/10):2.7); % gapBtot = 100*Mt; % total # bits per OFDM symbolTransmitIter = 50; % # iterations of symbol transmissions for each channel instanee Channeliter = 100; % # iterations of independent identically distributed channel instances Gapiter = len gth(Mgap);load ENC2.matload ENC4.matload ENC16.matload ENC64.matload ENC256.matTotEbNo =[];Errors =[];EbNo =[];for lGap = 1:GaplterlGapgap = Mgap(lGap);totalErrors = 0;for lCha n = 1:Cha nn ellter% create cha nnel[H h_f]=create_cha nn el(Mt, Mr, A, N+GI);% decompose each subcha nnel in the freque ncy doma in[U S V] = svd_decompose_cha nn el(Mt, Mr, h_f, N);% bitloadi ng[bits_alloc,e nergy_alloc] = BitLoad(S,Btot,Mt*N,gap,sig2,M);%en ergy_alloc=e nergy_alloc/(mea n(e nergy_alloc));%e nergy_alloc=o nes(1,128);for lTra ns = 1:Tra nsmitlter% bits to tra nsmitx = (ra ndn (1,Btot)>0);% modulatex_mod = modulate(x,bits_alloc,e nergy_alloc, S2,S4,S16,S64,S256);% precode modulated sig nal x_pre = precode(Mt, x_mod, V, N);% ifft, with cyclic prefix for each antennaofdm_symbol =[];for i=1:Mtofdm_symbol = [ofdm_symbol; ifft_cp_tx_blk(x_pre(i:Mt:Mt*(N-1)+i),N,GI)];endofdm_symbol2 = reshape(ofdm_symbol,Mt*(N+GI),1);% cha nnely = transpose(channel(sig2, Mt, Mr, ofdm_symbol2, H, N+GI));% fftrec_symbol =[];for i=1:Mtrec_symbol = [rec_symbol; fft_cp_rx_blk(y(i:Mt:Mt*(N+GI-1)+i),N,GI)];endrec_symbol2 = reshape(rec_symbol,1,Mt*N);% shape received sig nalshaped_vals = shape(rec_symbol2, Mr, U, N);% demodulatey_demod = demodulate(shaped_vals, bits_alloc, en ergy_alloc, S, s2,s4,s16,s64,s256, c2,c4,c16,c64,c256);% comparis ontotalErrors = totalErrors + sum(xor(y_demod,x));endEbNo = [EbNo sum(e nergy_alloc)/Btot/sig2];endErrors = [Errors totalErrors/Btot/Cha nn elIter/Tra nsmitlter]TotEbNo = [TotEbNo mea n(EbNo)]EbNo =[];endsemilogx(TotEbNo, Errors);xlabel('Eb/No');ylabel('BER');title( 'SISO link, adaptive rate and power')save SISO_adaptive2.mat Errors EbNocreate cha nn el.m : Gen erates a Rayleigh fadi ng freque ncy-selective cha nn el, parametrized by the antenna con figurati on, the OFDM con figurati on, and the power-delay profile.fun cti on [H, H_f]=create_cha nn el(Mt, Mr, A, N);% function [H, H_f]=create_channel(Mt, Mr, A, N);% - -% A - vector containing the power-delay profile (real values)% Mt - n umber of Tx antennas% Mr - n umber of Rx antennas% N - n umber of vector symbols to be sent in a sin gle OFDM symbol Tx% ie: N MIMO tran smissio ns in one OFDM symbol% This is for Rayleigh freque ncy-selective fading, which assumes complex% Gaussia n matrix eleme nts with in-phase and quadrature comp onentsin depe ndent.% Assume iid matrix channel elements, and further, independent channel taps% defi ne the cha nnel tapsH」nt = 1/sqrt(2)*(ra ndn( Mr*le ngth(A),Mt) + j*ra ndn (Mr*le ngth(A),Mt));H_in t2=[];for i = 1:le ngth(A)H」nt2 = [H」n t2;sqrt(A(i))*H _in t((i-1)*M r+1:i*Mr,:)];end%h_f = fft(H_in t2',64);%%H = H」n t2';H」nt2 = [H」n t2;zeros((N-le ngth(A))*Mr,Mt)];H_f = zeros(Mr,Mt*(N-16));for i = 1:Mtfor j = 1:Mrh_f = fft(H _in t2(j:Mr:(N-16-1)*Mr+j,i));for k = 1:(N-16)H_f(j,i+(k-1)*Mt) = h_f(k);endendendH=[H」n t2];for i = 1:N-1H=[H,[zeros(Mr*i,Mt);H」n t2(1:(N-i)*Mr,:)]];endsvd_decompose_channel.m : Since full channel knowledge is assumed, transmissionis across parallel singular value modes. This function decomposes the channel into these modes.fun cti on [U, S, V] = svd_decompose_cha nn el(Mt, Mr, h_f, N);% [U S V] = svd_decompose_cha nn el(Mt, Mr, h_f, N);%% Function decomposes the channel at each subcarrier into its SVD components %% Mt - # Tx antennas% Mr - # Rx antennas% h_f - MIMO impulse response - Mr rows, Mt*L columns, where L is the numberof% cha nnel taps% N - # subcarriersU =[];S =[];V =[];for i = 1:N[Utmp Stmp Vtmp] = svd(h_f(:,(i-1)*Mt+1:i*Mt));U=[U Utmp]; -V=[V Vtmp];S=[S Stmp]; endS = sum(S,1);BitLoad.m : Apply the bit-loading algorithm to achieve the desired bit andallocati on for the curre nt cha nnel in sta nee. fun cti on [bits_alloc,e nergy_alloc]=BitLoad(subcha n_gain s,total_bits ,n um_subc,gap ,no ise,M) % Bit Loading Algorithm% ........................%% In puts :subchan_gains : SubCarrier Gains total_bits : Total Number of bits n um_subc : Number of Subcarriers gap : Gap of the system no ise : Noise PowerM : Max Con stellation Size % Outputs:% bits alloc : Bits allocation for each subchannel % power_alloc : Total Power allocati on% ................................................................... % Compute SNR's for each cha nnel SNR = ComputeSNR(subcha n_gains,no ise,gap);% This fun cti on just in itializes the system with a particular bit % allocation and energy allocation using Chow's Algorithm. This is % further efficientize using Campello's Algorithm[bits_alloc, en ergy_alloc] = chow_algo(SNR ,n um_subc,M);% Form the En ergy In creme nt Table based on the prese nt cha nnel % gains for all the subcha nn els in order to be used by Campello % Algorithmen ergytable = En ergyTablel ni t(SNR,M);% Efficientize the algorithm using the Campello's algorithm [bits_alloc,e nergy_alloc]=campello_algo(bits_alloc,e nergy_alloc,e nergytable,total_bits, num_subc,M ); _ _ _ - -ComputeSNR.m : Give n the subcarrier gains, this simple fun ctio n gen erates the SNR values of each cha nn el (each sin gular value on each tone is a separate cha nn el).fun cti on SNR = ComputeSNR(subcar_ga ins,no ise,gap)SNR = abs((subcar_ga in s.A 2)./( noise*gap));en ergy% % %% %chow_algo.m : Apply Chow's algorithm to gen erate a particular bit anden ergy% Chow's Algorithm% ..................% This is based on the paper by Chow et al titled%% A Practical Discrete Multit one Tran sceiver Loadi ng Algorithm% for Data Tran smissi on over Spectrally Shaped Chann els .I EEE Tra ns% on Communications. Vol. 43, No 2/3/4, pp. 773-775, Feb/Mar/Apr 1995fun cti on [bits_alloc, en ergy_alloc] = chow_algo(SNR, num_subc,M) for i = 1:n um_subc% Assuming each of the subchannels has a flat fading, we get initial estimate% of the bits for each subcha nneltempbits = log2(1 + abs(SNR(i))); % bits per two dime nsion.rou ndtempbits = roun d(tempbits); % round the bitsif (rou ndtempbits > 8)% Limit them betwee n 2 and 15 rou ndtempbits = 8;end if (mod(rou ndtempbits,2)== 1 & rou ndtempbits ~= 1) roundtempbits = roundtempbits -1;endif rou ndtempbits > 0for the subcha nnelenergy_alloc(i) = (2A roundtempbits-1)/SNR(i);elseen ergy_alloc(i) = 0;endbits_alloc(i) = roun dtempbits;end % end of fun cti on En ergyTable In it.m : Give n the SNR values, form a table of en ergy in creme nts for eachcha nn el.fun cti on en ergytable = En ergyTablel ni t(SNR,M);% In puts:subcar_ga ins : Subcarrier Gains% M : max Con stellati on Size % Gap : Gap of the system % Noise : Noise Power % Outputs: % en ergytable : En ergytable % Based on the Subcarrier Gai ns, we calculate the en ergy % in creme nt required by each subcarrier for tran smitt ing % 1,2 ,4 ,6,8 bits.% En ergy = 2A(i-1)/subcar_ga ins;% Calculate the En ergy required % Update the BitSubChan% ...............................................................%subcar_ga ins = (subcar_ga in s.A2)/(Gap*Noise);en ergytable = abs((1./SNR)'*(2.A([i:M+1]-1)));% In crease the en ergy value for con stellati on size of more tha n M to % a very high value so that it is not assig ned.en ergytable(:,M+1) = lnf*on es(size(e nergytable(:,M+1)));for i = 3:2:Men ergytable(:,i) = (en ergytable(:,i) +en ergytable(:,i+1))/2;en ergytable(:,i+1) = en ergytable(:,i);end%en ergytable = [on es(1,size(e nergytable,1))' en ergytable];campello algo.m : Apply Campello's algorithm to con verge to the optimal en ergy allocati on for the give n cha nnel con diti ons.% campello_algo.m% ................% This function is used by Campello's algorithm to allocate bits andfor% each subcha nnel optimally.fun cti on [bits_alloc, en ergy_alloc]=campello_algo(bits_alloc,e nergy_alloc,e nergytable,total_bits, num_subc,M) _ _ _ - -bt = sum(bits_alloc);% We can't tran smit more tha n M*(Number of subcha nn el) bitsif total_bits > M*n um_subctotal_bits = M*n um_subc;endwhile (bt ~= total_bits)if (bt > total_bits)max_val = 0;max_i nd = ceil(ra nd(1)* num_subc);for i = 1:n um_subcif bits_alloc(i) ~= 0temp = en ergytable(i,bits_alloc(i));elsetemp = 0;endif (temp > max_val)max_val = temp;max_i nd = i;end bit and en ergyendif (bits_alloc(max_i nd) > 0) bits_alloc(max_i nd) = bits_alloc(max_i nd) -1; en ergy_alloc(max_i nd) = en ergy_alloc(max_i nd) - max_val; bt = bt-1;endelsemin_val = Inf;min_ind = ceil(ra nd(1)* num_subc);for i = 1:n um_subcif bits_alloc(i) ~=0 & bits_alloc(i) <9temp = en ergytable(i,bits_alloc(i) + 1);elsetemp = Inf;endif (temp < min_val)min_val = temp;min_i nd = i;endendif (bits_alloc(min_i nd) < 8)bits_alloc(min_i nd) = bits_alloc(min_i nd) +1;if (min_val==i nf)min_val = en ergytable(min_i nd,bits_alloc(min_i nd));enden ergy_alloc(min_i nd) = en ergy_alloc(min_i nd) +min_val;bt = bt+1;endendendfor i = 1:le ngth(bits_alloc)if (mod(bits_alloc(i),2) == 1 & bits_alloc(i) ~=1)[bits_alloc,e nergy_alloc]=ResolvetheLastBit(bits_alloc,e nergy_alloc,i,e nergytable, num_subc);endendResolvetheLastBit.m : An optimal bit-loading of the last bit requires optimizati on.a unique fun cti on [bits_alloc, en ergy_alloc]=ResolvetheLastBit(bits_alloc,e nergy_alloc,i ndex,e nergytable, num_subc)max_val = 0;for i = 1:n um_subcif (i ~= index & bits_alloc(i) == 1)if bits_alloc(i) ~= 0 temp = energytable(i,bits_alloc(i)) ;endif (temp > max_val) max_val = temp;max_ind = i;end end end min_val = Inf;for i = 1:num_subcif (i~= index & bits_alloc(i) == 1) if bits_alloc(i) ~=0temp = energytable(i,bits_alloc(i) + 1); end if (temp < min_val)min_val = temp;min_ind = i;endendend if (min_val < max_val)bits_alloc(min_ind) = bits_alloc(min_ind) + 1; bits_alloc(index) = bits_alloc(index) - 1;energy_alloc(index) = energy_alloc(index) - min_val;elsebits_alloc(max_ind) = bits_alloc(max_ind) - 1;bits_alloc(index) = bits_alloc(index) + 1;energy_alloc(index) = energy_alloc(index) + max_val;end。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1.1简述
OFDM是一种特殊的多载波传输方案,它可以被看作是一种调制技术,也可以被当作一种复用技术。多载波传输把数据流分解成若干子比特流,这样每个子数据流将具有低得多的比特速率,用这样的低比特率形成的低速率多状态符号再去调制相应的子载波,就构成多个低速率符号并行发送的传输系统。正交频分复用是对多载波调制(MCM,Multi-Carrier Modulation)的一种改进。它的特点是各子载波相互正交,所以扩频调制后的频谱可以相互重叠,不但减小了子载波间的干扰,还大大提高了频谱利用率。
1.2.2 串并变换
数据传输的典型形式是串行数据流,符号被连续传输,每一个数据符号的频谱可占据整个可以利用的带宽。但在并行数据传输系统中,许多符号同时传输,减少了那些在串行系统中出现的问题。在OFDM系统中,每个传输符号速率的大小大约在几十bit/s到几十kbit/s之间,所以必须进行串并变换,将输入串行比特流转换成为可以传输的OFDM符号。由于调试模式可以自适应调节,所以每个子载波的调制模式是可以变化的,因为而每个子载波可传输的比特数也是可以变化的,所以串并变换需要分配给每个子载波数据段的长度是不一样的。在接收端执行相反的过程,从各个子载波出来的数据长度不一样。在接收端执行相反的过程,从各个子载波处来的数据被转换回原来频分复用(OFDM)技术就是在频域内将给定信道分成许多正交子信道 ,在每个子信道上使用一个子载波进行调制,并且各子载波并行传输。尽管总的信道是非平坦的,具有频率选择性,但是每个子信道是相对平坦的,在每个子信道上进行的是窄带传输,信号带宽小于信道的相应带宽,因此大大消除了信号波形间的干扰。而且子信道的载波相互正交,一个OFDM符号包括多个经过 PSK调制或QAM调制的子载波的合成信号,每个子载波的频谱相互重叠,从而又提高了频谱利用率。用 N 表示子载波个数,T 表示 OFDM 符号的持续时间,di( i = 0,1 , …, N - 1)为分配给每个子信道的数据符号,fi为第i 个子载波的载波频率,从 t = ts开始的OFDM符号的等效基带信号可表示为(模拟信号表示式) :
OFDM系统收发机的典型框图如图1.1所示,发送端将被传输的数字信号转换成子载波幅度和相位的映射,并进行离散傅里叶变换(IDFT)将数据的频谱表达式变换到时域上。IFFT变换与IDFT变换的作用相同,只是有更高的计算效率,所以适用于所有的应用系统。其中,上半部分对应于发射机链路,下半部分对应于接收机链路。由于FFT操作类似于IFFT,因此发射机和接收机可以使用同一硬件设备。当然,这种复杂性的节约则意味着接收发机不能同时进行发送和接收操作。
1.2 OFDM基本原理概述
1.2.1
OFDM的思想早在20世纪60年代就已经提出,由于使用模拟滤波器实现起来的系统复杂度较高,所以一直没有发展起来。在20世纪70年代,提出用离散傅里叶变换(DFT)实现多载波调制,为OFDM的实用化奠定了理论基础;从此以后,OFDM在移动通信中的应用得到了迅猛的发展。
s(t)的实部和虚部分别对应于OFDM符号的同相分量和正交分量,在实际系统中可分别与相应子载波的余弦分量和正弦分量相乘,构成最终的子信道。其相应的数字表示式如下:令 ts= 0 ,采样速率为 N/ T ,则发送速率的第 k ( k =:0 ,1 , …, N - 1)个采样表示为:
(1-2)
显然式上式恰好为IDFT的表达式,可知OFDM的调制和解调可以通过 IDFT 和DFT或(IFFT 和FFT)来实现。如图1.2所示,在一个OFDM符号内包含四个载波的实例。其中,所有的子载波都具有相同的幅度和相位,但在实际应用中,根据数据符号的调制方式,每个子载波都有相同的幅度和相位是不可能的。从图1.2可以看出每个子载波在一个OFDM符号周期内都包含整数倍个周期,而且各个相邻的子载波之间相差1个周期。这一特性可以用来解释子载波之间的正交性,即:
当一个OFDM符号在多径无线信道中传输时,频率选择性衰落会导致某几组子载波收到相当大的的衰减,从而引起比特错误。这些在信道频率响应的零点会造成在邻近的子载波上发射的信息受到破坏,导致在每个符号中出现一连串的比特错误。与一大串错误连续出现的情况相比较,大多数前向纠错编码(FEC,Forward Error Correction)在错误分布均与的情况下会工作得更有效。所以,为了提高系统的性能,大多数系统采用数据加扰作为串并变换工作的一部分。这可以通过把每个连续的数据比特随机地分配到各个子载波上来实现。在接收机端,进行一个对应的逆过程解出信号。这样,不仅可以还原出数据比特原来的顺序,同时还可以分散由于信号衰落引起的连串的比特错误使其在时间上近似均匀分布。这种将比特错误位置的随机化可以提高前向纠错编码(FEC)的性能,并且系统的总的性能也得到改善。
符号间干扰是多径衰落信道宽带传输的主要问题,多载波调制技术包括正交频分复用(OFDM)是解决这一难题中最具前景的方法和技术。利用 OFDM技术和 IFFT方式的数字实现更适宜于多径影响较为显著的环境,如高速 WLAN 和数字视频广播 DVB等。OFDM作为一种高效传输技术备受关注,并已成为第4代移动通信的核心技术。如果进行OFDM系统的研究,建立一个完整的OFDM系统是必要的。本文在简要介绍了OFDM 基本原理后,基于MATLAB构建了一个完整的OFDM动态仿真系统。
(1-3)
如对式1-3中的第j个子载波进行调制,然后在时间长度T内进行积分,即:
根据对式1-4可以看到,对第J个子载波进行解调可以恢复出期望的符号。而对其他载波来说,由于积分间隔内,频率差别(I-J)/T可以产生整数倍个周期,所以积分结果为零。这种正交性还可以从频率角度来解释。根据式1-2 ,每个OFDM符号在其周期T内包含多个非零子载波。因此其频谱可以看作是周期为T的矩形脉冲的频谱与一组位于各个子载波频率上的δ函数的卷积。矩形脉冲频谱幅度值为sinc(ƒT)函数,这种函数的零点出现在频率为1/T整数倍的位置上。
图1.1 OFDM系统收发机的典型框图
接收端进行发送相反的操作,将射频(RF,Radio Frequency)信号与基带信号进行混频处理,并用FFT变换分解频域信号。子载波幅度和相位被采集出来并转换回数字信号。IFFT和FFT互为反变换,选择适当的变换将信号接收或发送。但信号独立于系统时,FFT变换和IFFT变换可以被交替使用。