ofdm tutorial.txt
来自「CDMA系统中使用OFDM调制方式下的系统性能仿真以及结果波形」· 文本 代码 · 共 491 行 · 第 1/2 页
TXT
491 行
% - NOTE THAT WINDOWING IS CURRENTLY COMMENTED OUT, i.e. NO WINDOWING
% - each time waveform (row of time_wave_matrix) represents one symbol
% period for all carriers
% - the IFFT result has discontinuities at each end
% - when the time waveforms are serialized (concatenated), the discontinuites
% will introduce unwanted frequency components
% - the window function deemphasizes the signal at the end
% points (at the discontinuites)
% - this reduces the effects of the discontinuities
% - it also distorts the desired frequency response (undesired side effect)
% - between Blackman, Hanning, and Hamming: Hamming introduces less distortion
% - note that the transpose of the Hamming function is
% used (because a row vector is needed)
%
% Since all imaginary values of time_wave_matrix are practically equal to zero,
% only the real part is retained for windowing.
%
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
%
% 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)
%
ofdm_modulation = reshape(windowed_time_wave_matrix', 1, IFFT_bin_length*(symbols_per_carrier+1));
%
% PLOT OFDM SIGNAL (time)
%
%temp_time = IFFT_bin_length*(symbols_per_carrier+1);
%figure (5)
%plot(0:temp_time-1,ofdm_modulation)
%grid on
%ylabel('Amplitude (volts)')
%xlabel('Time (samples)')
%title('OFDM Time Signal')
%
% PLOT OFDM SIGNAL (spectrum)
%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('Magnitude (dB)')
%xlabel('Normalized Frequency (0.5 = fs/2)')
%title('OFDM Signal Spectrum')
%
% ENDPLOT
%
%--------1---------2---------3---------4---------5---------6---------7---------8
%
% Upconversion to RF
%
% For this model, the baseband will be inserted directly into the channel
% without conversion to RF frequencies.
%
Tx_data = ofdm_modulation;
%
%--------1---------2---------3---------4---------5---------6---------7---------8
%
% CHANNEL ======================================================================
%
% The channel model is Gaussian (AWGN) only
% - Rayleigh fading would be a useful addition
%
Tx_signal_power = var(Tx_data);
%
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;
%
%
% RECEIVE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
%
%
% Convert the serial input data stream to parallel (according to symbol length
% and number of symbols)
% - each column is a symbol period
% - the length of each symbol (samples per symbol) is the length of the
% IFFT that was used to generate it
%
Rx_Data_matrix = reshape(Rx_Data, IFFT_bin_length, symbols_per_carrier + 1);
%
% Transform each symbol from time to frequency domain
% - take the fft of each column
%
Rx_spectrum = fft(Rx_Data_matrix);%
% PLOT BASIC FREQUENCY DOMAIN REPRESENTATION
%
%--------1---------2---------3---------4---------5---------6---------7---------8
%
%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('Magnitude')
%xlabel('FFT Bin')
%title('OFDM Receive Spectrum, Magnitude')
%figure (8)
%plot(0:IFFT_bin_length-1, (180/pi)*angle(Rx_spectrum(1:IFFT_bin_length,2)), '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('Phase (degrees)')
%xlabel('FFT Bin')
%title('OFDM Receive Spectrum, Phase')
%
% END OF PLOTTING
%--------1---------2---------3---------4---------5---------6---------7---------8
%
% Extract the carrier FFT bins
% - only keep the fft bins that are used as carriers
% - take the transpose of the result so that each column will represent
% a carrier
% - this is in preparation for using the diff( ) function later to decode
% differential encoding
% - format following this operation is:
%
% C1-s1 C2-s1 C3-s1 ...
% C1-s2 C2-s2 C3-s2 ...
% C1-s3 C2-s3 C3-s3 ...
% . . .
% . . .
%
% - IMPORTANT MATLAB NOTE CONCERNING TRANSPOSING AND CONJUGATION
% - it appears that each time a matrix is transposed, the conjugate of
% each value is taken
% - if an even number of transposes are done, then it is transparent
% - obviously, this does not affect real numbers
%
Rx_carriers = Rx_spectrum(carriers,:)';
%
%--------1---------2---------3---------4---------5---------6---------7---------8
%
% PLOT EACH RECEIVED SYMBOL
%
figure (9)
Rx_phase_P = angle(Rx_carriers);
Rx_mag_P = abs(Rx_carriers);
polar(Rx_phase_P, Rx_mag_P,'bd');
%
% END PLOT
%
% Find the phase (angle) of each FFT bin (each carrier)
% - convert from radians to degrees
% - normalize phase to be between 0 and 359 degrees
%
Rx_phase = angle(Rx_carriers)*(180/pi);
phase_negative = find(Rx_phase < 0);
Rx_phase(phase_negative) = rem(Rx_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
%
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);
%
%--------1---------2---------3---------4---------5---------6---------7---------8
%
% Convert phase to symbol
% - calculate the base phase which is the phase difference between each
% consecutive symbol
% - for example, if there are 2 bits per symbol, base phase is 90 and the
% symbols are represented by 0, 90, 180, and 270 degrees
% - calculate the maximum deviation from the base phase that will still be
% decoded as base phase
% - for example, if base phase is 90, then delta phase is 45, and anything
% within 45 degrees of base phase is accepted as base phase
% - continuing the above example, a symbol represented by 180 will be
% decoded as 180 as long as it is within the range 180+45 and 180-45
% - generate a symbol matrix where the results of the phase decode
% will be placed
% - note that since the matrix is created as a zero matrix, then the zero
% values do not have to be decoded
% - zero is therefore the default value after decoding, if a value is not
% decoded as anything else, then it is zero
% - this actually save alot of trouble since the zero phase spans the
% lowest and highest phase values and therefore requires special
% processing
% - it is also efficient in that it eliminates a pass through the loop
%
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
%
% Convert the matrix into a serial symbol stream
%
Rx_serial_symbols = reshape(Rx_decoded_symbols',1,size(Rx_decoded_symbols,1)*size(Rx_decoded_symbols,2));
%
% Convert the symbols to binary
%
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));
%
% Find bit errors
%
bit_errors = find(baseband_in ~= baseband_out);
bit_error_count = size(bit_errors,2);
%--------1---------2---------3---------4---------5---------6---------7---------8
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?