gusucode.com > MIMO与SISO仿真程序 > MIMO-OFDM/results_SISO_v1.m
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Student: Benjamin Pham % ID: 25957066 % % Version: Final % Changes: % Description: a 1x1 SISO OFDM System % % Simulates a 1x1 SISO OFDM system. This system includes the % Transmitter: % QAM Modulation, S/P converter, Pilot Insertion IFFT, Add Cyclic Prefix, % P/S converter % Channel: % Frequency flat fading Channel modelled by Complex number, AWGN, % Time Offset % Receiver: % S/P converter, Removal of Cyclic Prefix, DFT, Channel estimation, % Channel equalisation, P/S converter, QAM Demodulation % % Simulation performs a BER test vs SNR when various time offsets are % inputted by sending binary data through the system and measuring the % amount of errors at the receiver. Time offsets can be changed beginning % on line 138 for different channels. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% clc; clear all; close all; warning off %% Input parameters % data points data = 2^16; % fft size n_fft = 64; % cyclic prefix length n_cp = 0.25*n_fft; % CP length 25% of FFT size % Pilot Symbols PS = 1; % Data Symbols DS = n_fft - PS; % OFDM frame length OFDM = n_fft + n_cp; % Signal to Noise Ratios for AWGN snr = [0:1:30]; % Channel modelled by random complex number h = [randn()+randn()*1i]; % Initialise variables errors = zeros(size(snr)); ber = zeros(size(snr)); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% TRANSMITTER %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Generate binary data binary_data = round(rand(data,1)); %% Run BER test for 4QAM, 16QAM and 64 QAM for mod_type = 1:3 % Quadrature Amplitude Modulation if mod_type == 1 % Modulation Type: 4QAM symbols = 2; % Bits per symbol pilot = [0 1]'; % Padding for symbol mapping while floor(length(binary_data)/symbols) ~= length(binary_data)/symbols binary_data = [binary_data; zeros(1,1)]; end % Padding for subcarriers mapping while floor(length(binary_data)/symbols/DS) ~= length(binary_data)/symbols/DS binary_data = [binary_data; zeros(1,1)]; end elseif mod_type == 2 % Modulation Type: 16QAM symbols = 4; pilot = [0 0 0 1]'; % Padding for symbol mapping while floor(length(binary_data)/symbols) ~= length(binary_data)/symbols binary_data = [binary_data; zeros(1,1)]; end % Padding for subcarriers mapping while floor(length(binary_data)/symbols/DS) ~= length(binary_data)/symbols/DS binary_data = [binary_data; zeros(1,1)]; end elseif mod_type == 3 % Modulation Type: 64QAM symbols = 6; pilot = [0 0 0 0 0 1]'; % Padding for symbol mapping while floor(length(binary_data)/symbols) ~= length(binary_data)/symbols binary_data = [binary_data; zeros(1,1)]; end % Padding for subcarriers mapping while floor(length(binary_data)/symbols/DS) ~= length(binary_data)/symbols/DS binary_data = [binary_data; zeros(1,1)]; end end % Mapping binary data onto constellation maps mod_method = 2^symbols; mod_data = qammod(binary_data,mod_method,'unitaveragepower',true,'inputtype','bit'); pilot = qammod(pilot,mod_method,'unitaveragepower',true,'inputtype','bit'); Tx1 = mod_data; %% Serial to Parallel Conversion % serial stream into subcarriers Xk1 = reshape(Tx1,DS,length(Tx1)/DS); %% Pilot Insertion Xk1_p = [ones(1,length(Xk1))*pilot;Xk1]; %% Inverse Fast Fourier Transform Xn1 = ifft(Xk1_p); %% Cyclic prefix Xn1_cp = [Xn1((end - n_cp + 1):end,:);Xn1]; %% Parallel to Serial Conversion xn1 = Xn1_cp(:); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Channel %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% BER test for different SNR for k = 1:length(snr) %% Data passing through Channel % y time, receiver yn11 = xn1*h(1,1); % Tx1 to Rx1 %% add noise dB = snr(k); yn11 = awgn(yn11,dB,'measured'); %% offset added to between transmitter and receiver % CP length is 16, input time offset of 15 to match CP length of 16 % offset greater than CP length, 15, introduces ISI and increased BER % time offset is equal to duration of one symbol length delay11 = 0; % offset between Tx1 and Rx1 % next OFDM symbol becomes superposition of delayed previous symbol % tail of previous symbol added to front of next symbol - ISI %% inter-symbol interference for i = 0:(length(yn11)/(OFDM))-2 % ISI between transmitter 1 and receiver 1 if delay11 ~= 0 if delay11 == 1 yn11(1+OFDM+OFDM*i) = yn11(1+OFDM+OFDM*i) + yn11(OFDM-delay11+OFDM*i); else yn11(1+OFDM+OFDM*i:1+OFDM+delay11+OFDM*i) = yn11(1+OFDM+OFDM*i:1+OFDM+delay11+OFDM*i) ... + yn11(OFDM-delay11+OFDM*i:OFDM+OFDM*i); end end end % Time offset transmitter 1 and receiver 1 if delay11 ~= 0 if delay11 == 1 yn11(1:OFDM) = [zeros(delay11,1);yn11(1:OFDM-delay11)]; else yn11(1:OFDM) = [zeros(delay11+1,1);yn11(1:OFDM-delay11-1)]; end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% RECEIVER %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Serial to Parallel Conversion yn1_sp = reshape(yn11,OFDM,size(Xn1_cp,2)); %% Remove cyclic prefix yn1_rcp = yn1_sp((n_cp + 1):end,:); %% Discrete fourier transform Yk1_block = fft(yn1_rcp); %% Channel Estimation % because we send pilot symbols, we can estimate the channel. symbols that % are known beforehand. So its the received signal divided by the pilot % symbol. Yk1_DS = Yk1_block(2:64,:); Yk1_pilot = Yk1_block(1,:); H_hat = Yk1_pilot./pilot; %% Channel equalisation % zero forcing / Least Squares method H_hate = mean(H_hat); % average of estimated channel Yk1_block2 = Yk1_DS./H_hate; % cancelling out the channel effects %% Parallel to serial conversion Yk1 = Yk1_block2(:); %% QAM demodulation X_demod = qamdemod(Yk1,mod_method,'unitaveragepower',true,'outputtype','bit'); output = X_demod(:).'; %% Calculating BER errors(mod_type,k) = 0; for i = 1:length(binary_data)-n_fft*symbols if output(i+n_fft*symbols) ~= binary_data(i+n_fft*symbols) errors(mod_type,k) = errors(mod_type,k) + 1; end end ber(mod_type,k) = errors(mod_type,k)/length(binary_data); end % Plotting BER vs Eb/No semilogy(snr-10*log10(symbols),ber(mod_type,:),'-'); title('Single transmitter Single Receiver'); legend('4QAM','16QAM','64QAM'); xlabel('E_b/N_o (dB)'); ylabel('BER'); grid on; hold on end