logo资料库

MATLAB OFDM.doc

第1页 / 共16页
第2页 / 共16页
第3页 / 共16页
第4页 / 共16页
第5页 / 共16页
第6页 / 共16页
第7页 / 共16页
第8页 / 共16页
资料共16页,剩余部分请下载后查看
%a_run_design.m 文件 setup QAM OFDM Analysis %系统设置 %QAM 调制方式 %OFDM 调制方式 %QAM 和 OFDM 两种方式对比 %初始化部分 1setup % setup disp(' '), disp('------------------------------------------------------------') disp('Simulation Setup') % OFDM Setup ----------------------------------------------------------- fft_size = 128 % should be a power of 2 for fast computation % more points = more time domain samples (smoother & more cycles) num_carriers = 32 % should be <= fft_size/4 % number of carriers used for each data chunk % new var - denotes even spacing or variations of carriers among fft points input_type = 2; % 1 = test input test_input_type = 1; % 1 = bit specified (binary) binary_data = [0 1 0 1 0 1 0 1]; % 2 = random data stream (samples in the range of 0-255) num_symbols = 9; % 3 = sinusoidal frequency = 2; num_samples = 50; % 2 = external file input file_name = 'shortest.wav'; file_input_type = 3; % Name of input file % 1 = binary (not implemented) % 2 = text % 3 = sound % 4 = image (not implemented) % Demo file: 'text.txt' % Demo files: 'shortest.wav' & 'shorter.wav' % QAM Setup ------------------------------------------------------------ do_QAM = 1; QAM_periods = 10; % (1=on, 0=off) % defines the number of periods per QAM Symbos (1=2*pi) % Channel Simulation Parameters -------------------------------------------- channel_on = 1; clip_level = 1.0; % 1=on, 0=off % 0.0 - 1.0 (0-100%) % Max magnitude of the signal is 'clip_level' times the full magnitude of the signal noise_level = 0.0; % 0.0 - 1.0 (0-100%) 1
% Magnitude of noise is 'noise_level' times the magnitude of the signal % Multipath Channel Simulation % Good defaults when fft_size = 128 and num_carriers = 32: % d1=6; a1=0.30; d2=10; a2=0.25 d1 = 6; a1 = 0.30; d2 = 10; a2 = 0.25; % delay in units % attenuation factor - multipath signal is x% of size or original signal % delay for second multipath signal % attenuation factor for second multipath signal % ****************** TEST INPUT SETUP - DO NOT MODIFY ************************** if input_type == 1 if test_input_type == 1 %specify BINARY input bit-by-bit data_in = binary_data; end if test_input_type == 2 %random input defined by parameters num_levels = 255; %number of possible levels of a symbol %must be integer between 1-255 data_samples = round(rand(1,num_symbols)*(num_levels-1)); data_in = zeros(1,8*length(data_samples)); for i = 1:length(data_samples) data_in(1 + (i-1)*8:(i-1)*8 + 8) = eight2bin(data_samples(i)); end end if test_input_type == 3 %data stream represents sine wave samples t = linspace(0,1,num_symbols); %evenly space number of samples %take 8-bit samples of sine wave data_samples = round(127.5*sin(frequency*2*pi*t) +127.5); data_in = zeros(1,8*length(data_samples)); for i = 1:length(data_samples) data_in(1 + (i-1)*8:(i-1)*8 + 8) = eight2bin(data_samples(i)); end end end already_made_noise = 0; % initialization (don't change) 2、QAM.m % QAM.m compares OFDM (multicarrier) to multi-level QAM (single carrier) % when they transmit the same # of bits in a given time period read % read data for QAM - does not affect OFDM 2
data_in_pol = bin2pol(data_in); % Converts binary data to polar data % check to see if num_carriers is a power of 2 is_pow_2 = num_carriers; temp_do_QAM = 0; if is_pow_2 ~= 2 while temp_do_QAM == 0 temp_do_QAM = rem(is_pow_2,2); is_pow_2 = is_pow_2/2; if is_pow_2 == 2 temp_do_QAM = -99; % it is a power of 2 -> can do QAM end end else temp_do_QAM = -99; % 2 is a power of 2 end if temp_do_QAM ~= -99 do_QAM = 0; % don't do it if it's not possible disp(' '),disp('ERROR: Cannot run QAM because num_carriers is not valid.') disp(' Please see "setup.m" for details.') end if do_QAM == 1 tic % Start stopwatch to calculate how long QAM simulation takes disp(' '), disp('------------------------------------------------------------') disp('QAM simulation'), disp('Transmitting') % Pad with zeros so data can be divided evenly data_length = length(data_in_pol); r = rem(data_length,num_carriers); if r ~= 0 for i = 1:num_carriers-r data_in_pol(data_length+i) = 0; %pad input with zeros to complete last data set end %speed improve possible end data_length = length(data_in_pol); %update after padding num_OFDM_symbols = ceil(data_length / (2*num_carriers)); % num QAM symbols that represent equal amount of data to one OFDM symbol num_QAM_symbols = num_carriers / 2; % num samples per QAM symbol num_symbol_samples = fft_size / num_QAM_symbols; % convert polar data [-1, 1] to 4 level data [-3, -1, 1, 3] 3
data_in_4 = zeros(1,data_length/2); for i = 1:2:data_length data_in_4(i - (i-1)/2) = data_in_pol(i)*2 + data_in_pol(i+1); end % define sample points between 0 and 2*pi ts = linspace(0, 2*pi*QAM_periods, num_symbol_samples+1); % Generate 16-QAM data % total length of 16-QAM transmission tx_length = num_OFDM_symbols * num_QAM_symbols * num_symbol_samples; QAM_tx_data = zeros(1,tx_length); for i = 1:2:data_length/2 for k = 1:num_symbol_samples QAM_tx_data(k+((i-1)/2)*num_symbol_samples) = data_in_4(i)*cos(ts(k)) + data_in_4(i+1)*sin(ts(k)); end end % ch uses 'xmit' data and returns 'recv' % Do channel simulation on QAM data xmit = QAM_tx_data; ch QAM_rx_data = recv; clear recv clear xmit % save QAM data after channel % remove 'recv' so it won't interfere with OFDM % remove 'xmit' so it won't interfere with OFDM % Recover Binary data (Decode QAM) disp('Receiving') cos_temp = zeros(1,num_symbol_samples); sin_temp = cos_temp; xxx = zeros(1,data_length/4); yyy = xxx; QAM_data_out_4 = zeros(1,data_length/2); % % % Initialize to zeros for speed % % for i = 1:2:data_length/2 % "cheating" for k = 1:num_symbol_samples % multiply by carriers to produce high frequency term and original data cos_temp(k) = QAM_rx_data(k+((i-1)/2)*num_symbol_samples) * cos(ts(k)); sin_temp(k) = QAM_rx_data(k+((i-1)/2)*num_symbol_samples) * sin(ts(k)); end % LPF and decide - we will do very simple LPF by averaging xxx(1+(i-1)/2) = mean(cos_temp); yyy(1+(i-1)/2) = mean(sin_temp); % Reconstruct data in serial form QAM_data_out_4(i) = xxx(1+(i-1)/2); QAM_data_out_4(i+1) = yyy(1+(i-1)/2); end 4
% Make decision between [-3, -1, 1, 3] for i = 1:data_length/2 if QAM_data_out_4(i) >= 1, QAM_data_out_4(i) = 3; elseif QAM_data_out_4(i) >= 0, QAM_data_out_4(i) = 1; elseif QAM_data_out_4(i) >= -1, QAM_data_out_4(i) = -1; else QAM_data_out_4(i) = -3; end end % Convert 4 level data [-3, -1, 1, 3] back to polar data [-1, 1] QAM_data_out_pol = zeros(1,data_length); % "cheating" for i = 1:2:data_length switch QAM_data_out_4(1 + (i-1)/2) case -3 QAM_data_out_pol(i) = -1; QAM_data_out_pol(i+1) = -1; case -1 QAM_data_out_pol(i) = -1; QAM_data_out_pol(i+1) = 1; case 1 QAM_data_out_pol(i) = 1; QAM_data_out_pol(i+1) = -1; case 3 QAM_data_out_pol(i) = 1; QAM_data_out_pol(i+1) = 1; otherwise disp('Error detected in switch statment - This should not be happening.'); end end QAM_data_out = pol2bin(QAM_data_out_pol); % convert back to binary % Stop stopwatch to calculate how long QAM simulation takes QAM_simulation_time = toc; if QAM_simulation_time > 60 disp(strcat('Time for QAM simulation=', num2str(QAM_simulation_time/60), ' minutes.')); disp(strcat('Time for QAM simulation=', num2str(QAM_simulation_time), ' seconds.')); else end end 3 % Run OFDM simulation tic % Start stopwatch to calculate how long QAM simulation takes disp(' '),disp('------------------------------------------------------------') disp('OFDM Simulation') 5
tx ch rx % Stop stopwatch to calculate how long QAM simulation takes OFDM_simulation_time = toc; if OFDM_simulation_time > 60 disp(strcat('Time for OFDM simulation=', num2str(OFDM_simulation_time/60), ' minutes.')); disp(strcat('Time for OFDM simulation=', num2str(OFDM_simulation_time), ' seconds.')); else end 3.1 发送 % tx disp('Transmitting') read data_in_pol = bin2pol(data_in); tx_chunk %read original data % Converts binary data to polar data %convert polar data into chunks. % perform ifft to create time domain waveform representing data td_sets = zeros(num_chunks,fft_size); for i = 1:num_chunks td_sets(i,1:fft_size) = real(ifft(spaced_chunks(i,1:fft_size))); end tx_dechunk % Construct signal to transmit by placing time domain sets in series 3.1.1 % tx_chunk %双极性数组转化成 OFDM 字符串 data_length = length(data_in_pol) num_carriers num_chunks = ceil(data_length/(2*num_carriers)) r = rem(data_length,2*num_carriers) if r ~= 0 %number of symbols in original input %2 data on each carrier (real and imaginary) for i = 1:num_carriers*2-r data_in_pol(data_length+i) = 0; %pad input with zeros to complete last data set %speed improve possible end end % break data into chunks chunks = zeros(num_chunks,num_carriers); % for speed for i = 1:num_chunks % *********************chunk done for k = 1:num_carriers chunks(i,k) = data_in_pol(2*num_carriers*(i-1)+k) + data_in_pol(2*num_carriers*(i-1)+k+num_carriers)*j; end end 6
chunks % Padding chunks with zeros so num_carriers and fft_size are compatible % Once compatible, further spacing is simplified num_desired_carriers = num_carriers; num_zeros = 0; thinking = 1; while thinking == 1 % Continue if num_carriers and fft_size are not compatible if rem(fft_size/2,num_desired_carriers) == 0 thinking = 0; num_desired_carriers = num_desired_carriers + 1; num_zeros = num_zeros + 1; else end end padded_chunks = zeros(num_chunks,num_carriers + num_zeros); % for speed padded_chunks(1:num_chunks,num_zeros + 1:num_carriers + num_zeros) = chunks; %compute zeros_between zeros_between = ((fft_size/2) - (num_carriers + num_zeros))/(num_carriers + num_zeros); spaced_chunks = zeros(num_chunks,fft_size); % for speed - extra room for folding later %add zeros_between i = 1; for k = zeros_between +1:zeros_between +1:fft_size/2 spaced_chunks(1:num_chunks,k) = padded_chunks(1:num_chunks,i); i = i+1; end % folding data to produce an odd function for ifft input for i = 1:num_chunks % Note: index = 1 is actually DC freq for ifft -> it does not get copied over y-axis spaced_chunks(i,fft_size:-1:fft_size/2+2) = conj(spaced_chunks(i,2:fft_size/2)); end 3.1.2 tx_dechunk % tx_dechunk % Construct signal to transmit by placing time domain sets in series xmit = zeros(1,num_chunks*fft_size); for i = 1:num_chunks for k = 1:fft_size xmit(k + (i-1)*fft_size) = td_sets(i,k); end 7
end 3.2 %ch.m % ch recv = xmit; % channel is applied to recv, don't modify transmitted data if channel_on == 1 disp('Simulating Channel') norm_factor = max(abs(recv)); % Normalize all data before applying recv = (1/norm_factor) * recv; ch_clipping ch_multipath ch_noise recv = norm_factor * recv; %clipp data % % % channel for a fair comparison % Restore data magnitude for proper decoding end 3.2.1 %ch_clipping.m % ch_clipping for i = 1:length(recv) if recv(i) > clip_level recv(i) = clip_level; end if recv(i) < -clip_level recv(i) = -clip_level; end end 3.2.2 % ch_multipath copy1=zeros(size(recv)); for i=1+d1:length(recv) copy1(i)=a1*recv(i-d1); end copy2=zeros(size(recv)); for i=1+d2:length(recv) copy2(i)=a2*recv(i-d2); end recv=recv+copy1+copy2; % 产生多经的方法 3.2.3、%ch_noise %施加信道噪声 % ch_noise (operate on recv) % random noise defined by noise_level amplitude if already_made_noise == 0 % only generate once and use for both QAM and OFDM noise = (rand(1,length(recv))-0.5)*2*noise_level; already_made_noise = 1; end recv = recv + noise; 8
分享到:
收藏