OFDM仿真程序
clc
clear allIFFT_bin_length= 128 ; % IFFT点数128 个
carrier_count= 50 ; % 子信道(子载波)数目
bits_per_symbol= 2 ; % 4 进制符号
symbols_per_carrier= 200 ; % 每个子信道或者说子载波有200 个符号
SNR= 0 : 1 : 40 ;
for num= 1 : 41 baseband_out_length= carrier_count* symbols_per_carrier* bits_per_symbol; % 总bit数
% 下面是载波位置,为了满足得到的是实数信号,载波的位置要满足共轭对称
carriers= ( 1 : carrier_count) + ( floor ( IFFT_bin_length/ 4 ) - floor ( carrier_count/ 2 ) ) ; % floor函数是朝负无穷大四舍五入
conjugate_carriers= IFFT_bin_length- carriers+ 2 ; % baseband_out= round ( rand ( 1 , baseband_out_length) ) ; % 20000 个0 - 1 信源符号, round函数为四舍五入为最近的小数
baseband_out= randi ( 2 , 1 , baseband_out_length) - 1 ; % 返回一个介于1 和2 之间的1 * 20000 的数组
% 将一行20000 的数据交叉转换为2 行10000 的数据
convert_matrix= reshape ( baseband_out, bits_per_symbol, length ( baseband_out) / bits_per_symbol) ;
% 不如写个函数将值映射成0 - 3 ,如00 - 0 ,01 - 1 ,10 - 2 ,11 - 3
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) ; end
end% 串并转换
% 将本次的模4 的串行数据流转换为并行数据流,其中,每行整体是一个OFDM符号,每一个OFDM符号由所有载波在该采样点叠加产生,每列代表一个子载波
carrier_matrix= reshape ( modulo_baseband, symbols_per_carrier, carrier_count) ; % 采用了差分相移键控调制
carrier_matrix= [ zeros ( 1 , carrier_count) ; carrier_matrix] ; % 补了一行全0 ,作为编码的参考起点
for i= 2 : ( symbols_per_carrier+ 1 ) carrier_matrix ( i, : ) = rem ( carrier_matrix ( i, : ) + carrier_matrix ( i- 1 , : ) , 2 ^ bits_per_symbol) ; % rem函数是除后的余数
end% 将差分编码转换为相位变化
carrier_matrix= carrier_matrix* ( ( 2 * pi) / ( 2 ^ bits_per_symbol) ) ; % 将相位转换为一个复数
% 这句代码保证幅值都是1
[ X, Y] = pol2cart ( carrier_matrix, ones ( size ( carrier_matrix, 1 ) , size ( carrier_matrix, 2 ) ) ) ;
% 构造映射,将相位的值转换为极坐标上的一个复数点0 - 1 ,pi/ 2 - j. pi-- 1 , 3 pi/ 2 -- j
complex_carrier_matrix= complex ( X, Y) ; % 将每个子载波分配到之前定义好的IFFT输入端,根据IFFT的对称性,这样可以得到实值序列
IFFT_modulation= zeros ( symbols_per_carrier+ 1 , IFFT_bin_length) ;
IFFT_modulation ( : , carriers) = complex_carrier_matrix;
IFFT_modulation ( : , conjugate_carriers) = conj ( complex_carrier_matrix) ; % 画出未经过IFFT的离散幅度谱, 总共有50 + 50 个输入端有数据,所以频谱图显示为两个矩形形状
% figure ( 1 )
% stem ( 0 : IFFT_bin_length- 1 , abs ( IFFT_modulation ( 2 , 1 : IFFT_bin_length) ) , 'b*-' )
% grid on; axis ( [ 0 , IFFT_bin_length - 0.5 1.5 ] ) ; xlabel ( 'IFFT BIN' ) ; ylabel ( 'Magnitude' ) ;
% title ( 'OFDM Carrier Frequency Magnitude' ) ;
% 画出未经过IFFT的离散相位谱
% figure ( 2 )
% 所有128 个点的相位图
% plot ( 0 : IFFT_bin_length- 1 , ( 180 / pi) * angle ( IFFT_modulation ( 2 , 1 : IFFT_bin_length) ) , 'go' ) ;
% hold on;
% 带数据的100 个点的相位图
% stem ( carriers- 1 , ( 180 / pi) * angle ( IFFT_modulation ( 2 , carriers) ) , 'b*-' ) ;
% stem ( conjugate_carriers- 1 , ( 180 / pi) * angle ( IFFT_modulation ( 2 , conjugate_carriers) ) , 'b*-' ) ;
% axis ( [ 0 IFFT_bin_length - 200 200 ] ) ; grid on; ylabel ( 'Phase' ) ; xlabel ( 'IFFT Bin' ) ;
% title ( 'OFDM Carrier Phase' ) ; % IFFT变换
time_wave_matrix= ifft ( IFFT_modulation, [ ] , 2 ) ; % 对列进行离散傅里叶反变换
% time_wave_matrix= time_wave_matrix; % 作图
figure ( 3 )
plot ( 0 : IFFT_bin_length- 1 , time_wave_matrix ( 2 , : ) ) ;
grid on;
ylabel ( '幅度' ) ; xlabel ( '时间' ) ;
title ( '一个OFDM符号时域信号波形图' ) ; % colors= [ 'r' 'g' 'b' 'k' ]
% for f= 1 : 4 % temp_bins ( 1 : IFFT_bin_length) = 0 + 0 j; % temp_bins ( carriers ( f) ) = IFFT_modulation ( 2 , carriers ( f) ) ; % temp_bins ( conjugate_carriers ( f) ) = IFFT_modulation ( 2 , conjugate_carriers ( f) ) ; % temp_time= ifft ( temp_bins') ; % figure ( 4 ) % plot ( 0 : IFFT_bin_length- 1 , temp_time, colors ( f) ) ; % hold on;
% end
% grid on; ylabel ( '幅度' ) ; xlabel ( '时间' ) ; title ( '分离出的时域波形' ) ; % 添加一个窗函数,就是滤波器,减弱信号的不连续点
% 每一个时间波形表示所有载波的一个符号周期
% 因为时域矩阵中所有虚部都等于0 ,所以利用Hamming窗时,只保留实部用于加窗
for i= 1 : symbols_per_carrier+ 1 windowed_time_wave_matrix ( i, : ) = real ( time_wave_matrix ( i, : ) ) . * hamming ( IFFT_bin_length) ';
% windowed_time_wave_matrix ( i, : ) = real ( time_wave_matrix ( i, : ) ) ;
end% 将调制波形序列化( 并串转换)
ofdm_modulation= reshape ( time_wave_matrix, 1 , IFFT_bin_length* ( symbols_per_carrier+ 1 ) ) ; % 作图
% temp_time= IFFT_bin_length* ( symbols_per_carrier+ 1 ) ;
% figure ( 5 )
% plot ( 0 : temp_time- 1 , ofdm_modulation) ;
% grid on;
% ylabel ( '幅度' ) ; xlabel ( '时间(采样)' ) ; title ( 'OFDM时间信号' ) ; % 频谱图
% symbols_per_average= ceil ( symbols_per_carrier/ 5 ) ;
% avg_temp_time= IFFT_bin_length* symbols_per_average;
% averages= floor ( temp_time/ avg_temp_time) ;
% average_fft ( 1 : avg_temp_time) = 0 ;
% for a= 0 : ( averages- 1 )
% subset_ofdm= ofdm_modulation ( ( ( 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) ;
% end
% average_fft_log= 20 * log10 ( average_fft) ;
% figure ( 6 )
% plot ( ( 0 : ( avg_temp_time- 1 ) ) / avg_temp_time, average_fft_log) ;
% hold on;
% plot ( 0 : 1 / IFFT_bin_length: 1 , - 35 , 'rd' ) ; grid on;
% axis ( [ 0 0.5 - 40 max ( average_fft_log) ] ) ; ylabel ( '幅度(dB)' ) ; xlabel ( '标准化频率(0.5=fs/2)' ) ;
% title ( 'OFDM 信号频谱' ) ;
Tx_data= ofdm_modulation; % 上变频,不一定用得到% 经过信道
Rx_data= awgn ( Tx_data, SNR ( num) ) ;
% Rx_data= Tx_data; % % % % % % % % % % % % % % % % % % 接收端% % % % % % % % % % % % % % % % % % % % % % % % % 串并转换
Rx_data_matrix= reshape ( Rx_data, symbols_per_carrier+ 1 , IFFT_bin_length) ; % FFT变换
Rx_spectrum= fft ( Rx_data_matrix, [ ] , 2 ) ; % 经过FFT的频域相应图
figure ( 7 )
stem ( 0 : IFFT_bin_length- 1 , abs ( Rx_spectrum ( 1 : IFFT_bin_length, 2 ) ) , 'b*-' ) ;
grid on; axis ( [ 0 IFFT_bin_length - 0.5 1.5 ] ) ; ylabel ( '幅度' ) ; xlabel ( 'FFT Bin' ) ;
title ( 'OFDM 接收频谱,幅度' ) ;
% figure ( 8 )
% plot ( 0 : IFFT_bin_length- 1 , ( 180 / pi) * angle ( Rx_spectrum ( 1 : IFFT_bin_length) ) , 'go' ) ;
% hold on;
% stem ( carriers- 1 , ( 180 / pi) * angle ( Rx_spectrum ( carriers, 2 ) ) , 'b*-' ) ;
% stem ( conjugate_carriers- 1 , ( 180 / pi) * angle ( Rx_spectrum ( conjugate_carriers, 2 ) ) , 'b*-' ) ;
% axis ( [ 0 IFFT_bin_length - 200 200 ] ) ;
% grid on; ylabel ( '相位谱' ) ; xlabel ( 'FFT Bin' ) ;
% title ( 'OFDM 接受信号相位谱' ) ; % 将128 中真正含有数据的50 个载波提取出来
Rx_carriers= Rx_spectrum ( : , carriers) ; % 画出每一个接收符号
% figure ( 9 )
% Rx_phase_P= angle ( Rx_carriers) ;
% Rx_mag_P= abs ( Rx_carriers) ;
% polar ( Rx_phase_P, Rx_mag_P, 'rd' ) ; % 对每个FFT点,解映射出对应的相位值
Rx_phase= angle ( Rx_carriers) * ( 180 / pi) ;
phase_negative= find ( Rx_phase< 0 ) ;
Rx_phase ( phase_negative) = rem ( Rx_phase ( phase_negative) + 360 , 360 ) ; % 将负的相位对应为0 - 2 pi内的值% 从差分相移编码中,提取相位差值,这里利用diff ( ) 函数
Rx_decoded_phase= diff ( Rx_phase) ;
phase_negative= find ( Rx_decoded_phase< 0 ) ;
Rx_decoded_phase ( phase_negative) = rem ( Rx_decoded_phase ( phase_negative) + 360 , 360 ) ; % 解映射,将不同的相位转换为0 - 3 的信源符号,0 的相位范围为- 45 ,45 ,1 的相位范围为45 - 135 ,依此类推
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; minus_delta= center_phase- delta_phase; decoded= find ( ( Rx_decoded_phase<= plus_delta) & ( Rx_decoded_phase> minus_delta) ) ; Rx_decoded_symbols ( decoded) = i;
end
% Rx_decoded_symbols= Rx_decoded_symbols';
% 并串转换
Rx_serial_symbols= reshape ( Rx_decoded_symbols, 1 , size ( Rx_decoded_symbols, 1 ) * size ( Rx_decoded_symbols, 2 ) ) ; % 将4 进制的符号解码为二进制符号
for i= bits_per_symbol: - 1 : 1 if i~ = 1 Rx_binary_matrix ( i, : ) = rem ( Rx_serial_symbols, 2 ) ; Rx_serial_symbols= floor ( Rx_serial_symbols/ 2 ) ; else Rx_binary_matrix ( i, : ) = Rx_serial_symbols; end
end
baseband_in= reshape ( Rx_binary_matrix, 1 , size ( Rx_binary_matrix, 1 ) * size ( Rx_binary_matrix, 2 ) ) ; % 求误码率
bit_errors= find ( baseband_in~ = baseband_out) ;
bit_error_count ( num) = size ( bit_errors, 2 ) ;
BER ( num) = bit_error_count ( num) / baseband_out_length;
end
figure ( 10 )
semilogy ( SNR, BER, '-ob' , 'MarkerFaceColor' , 'b' , 'MarkerSize' , 5 , 'LineWidth' , 2 ) ; hold on; grid on;
title ( 'DPSK-OFDM信噪比与误码率曲线' ) ; xlabel ( 'SNR(dB)' ) ; ylabel ( 'BER' ) ;
plot ( [ 0 35 ] , [ 3.8e-3 , 3.8e-3 ] , 'r' , 'LineWidth' , 1 ) ; hold on;
legend ( 'DPSK-OFDM' , 'FEC(3.8x10^-^3)' ) ;