?? liuguifen.m
字號:
1 模塊Simatar.m
set_sim_consts;
%設定輸入數據長度
plen=2;
%生成輸入數據
inf_bits = randn(1, plen*8) > 0;
%根據輸入選擇映射方式
MOD=“16QAM”
start_time=clock;
%填充位
rdy_to_mod_bits = make_int_num_ofdm_syms(inf_bits, MOD);
%調制映射
mod_syms=modulate(rdy_to_mod_bits,MOD);
%加導頻
mod_ofdm_syms =add_pilot_syms(mod_syms);
% IFFT頻域到時域變換 (OFDM調制)
time_syms = freqd_to_timed(mod_ofdm_syms);
% 加循環前綴(CP)
time_signal = add_cyclic_prefix(time_syms);
stop_time = clock;
elapsed_time = etime(stop_time,start_time);
fprintf('仿真用時: %g 秒\n',elapsed_time);
%圖表顯示
stem(inf_bits);title('輸入序列');
figure
scatterplot(abs(mod_syms));title('調制映射后序列(星座圖)');ylabel('實部');xlabel('虛部')
figure
compass(mod_syms);title('調制映射后序列(相位圖)');
figure
stem(abs(mod_syms));title('調制映射后序列');ylabel('實部');xlabel('虛部')
figure
stem(abs(mod_ofdm_syms));title('調制映射后序列加導頻');ylabel('實部');xlabel('虛部')
figure
stem(abs(time_syms));title('OFDM調制后輸出');ylabel('幅度');xlabel('序列')
figure
stem(abs(time_signal));title('OFDM調制后加CP時域輸出');ylabel('幅度');xlabel('序列')
2 模塊sim_const.m
function sim_consts = set_sim_consts
global sim_consts;
%抽樣頻率
sim_consts = struct('SampFreq' , 20e6, ...
'ConvCodeGenPoly', [1 0 1 1 0 1 1;1 1 1 1 0 0 1 ], ...
'NumSubc', 52, ... %子載波數
'UsedSubcIdx', [7:32 34:59]', ...%子載波位置
'ShortTrainingSymbols', sqrt(13/6)*[0 0 1+j 0 0 0 -1-j 0 0 0 1+j 0 0 0 -1-j 0 0 0 -1-j 0 0 0 1+j 0 0 0 0 0 0 -1-j 0 0 0 -1-j 0 0 0 ...
1+j 0 0 0 1+j 0 0 0 1+j 0 0 0 1+j 0 0], ...
'LongTrainingSymbols', [1 1 -1 -1 1 1 -1 1 -1 1 1 1 1 1 1 -1 -1 1 1 -1 1 -1 1 1 1 1 ...
1 -1 -1 1 1 -1 1 -1 1 -1 -1 -1 -1 -1 1 1 -1 -1 1 -1 1 -1 1 1 1 1], ...
'ExtraNoiseSamples', 500, ...
%導頻極性序列
'PilotScramble', [1 1 1 1 -1 -1 -1 1 -1 -1 -1 -1 1 1 -1 1 -1 -1 1 1 -1 1 1 -1 1 1 1 1 ...
1 1 -1 1 1 1 -1 1 1 -1 -1 1 1 1 -1 1 -1 -1 -1 1 -1 1 -1 -1 1 -1 -1 1 1 1 1 1 -1 -1 1 ...
1 -1 -1 1 -1 1 -1 1 1 -1 -1 -1 1 1 -1 -1 -1 -1 1 -1 -1 1 -1 1 1 1 1 -1 1 -1 1 -1 1 -1 ...
-1 -1 -1 -1 1 -1 1 1 -1 1 -1 1 1 1 -1 -1 1 -1 -1 -1 1 1 1 -1 -1 -1 -1 -1 -1 -1], ...
'NumDataSubc', 48, ...%數據載波數
'NumPilotSubc' , 4, ...% 導頻數
'DataSubcIdx', [7:11 13:25 27:32 34:39 41:53 55:59]', ... %數據載波位置
'PilotSubcIdx', [12 26 40 54]', ...% 導頻位置
'PilotSubcPatt', [6 20 33 47]', ...%導頻插入方式
'DataSubcPatt', [1:5 7:19 21:26 27:32 34:46 48:52]', ...%數據載波規格
'PilotSubcSymbols' , [1;1;1;-1]);%插入的導頻數據
3 模塊Modulate.m:
function mod_symbols = tx_modulate(bits_in, modulation)
full_len = length(bits_in);
if ~isempty(findstr(modulation, '16QAM'))
% 生成 16QAM 符號
m=1;
for k=-3:2:3
for l=-3:2:3
table(m) = (k+j*l)/sqrt(10); % 功率歸一化
m=m+1;
end;
end;
table=table([0 1 3 2 4 5 7 6 12 13 15 14 8 9 11 10]+1); % 按照格雷編碼星座圖順序定義16-QAM映射矩陣
inp=reshape(bits_in,4,full_len/4);%以4個比特為一列調整輸入序列
mod_symbols=table([8 4 2 1]*inp+1); % 將輸入序列進行16QAM映射
else
error('未定義的調制方式');
end
4 模塊make_int_num_ofdm_syms.m:
function out_bits = make_int_num_ofdm_syms(tx_bits, MOD)
global sim_consts;
n_tx_bits = length(tx_bits);
n_syms = sim_consts.NumDataSubc;
%根據映射方式計算一個OFDM符號需要的比特數
n_bits_per_sym = get_bits_per_symbol(MOD);
%計算OFDM符號數 總比特數/(定義子載波數*每個符號所需比特數)
n_ofdm_syms = ceil(n_tx_bits/(n_syms*n_bits_per_sym));
%根據OFDM符號中的比特數進行填充(填充隨機0 1)
%802.11a中填充比特均為0 最后再與數據加擾 此仿真中使用隨機生成數據代替加擾
%符號數*一個符號的載波數*一個載波的比特數-輸入比特數=需要填充的比特數
pad_bits = randn(1, n_ofdm_syms*n_syms*n_bits_per_sym - n_tx_bits) > 0;
%根據OFDM符號中的比特數進行全0填充
%pad_bits = zeros(1, n_ofdm_syms*n_syms*n_bits_per_sym - n_tx_bits)
%輸出
out_bits = [tx_bits pad_bits];
4 模塊get_bits_per_symbol:
function num_bits = get_bits_per_symbol(mod_order)
%根據調制方式定義一個符號的比特數
if ~isempty(strmatch(mod_order, '16QAM','exact'))
num_bits=4;
else
error('未定義的調制方式');
end
5 模塊freqd_to_timed.m:
function time_syms = freqd_to_timed(mod_ofdm_syms)
global sim_consts;
% OFDM符號數統計
num_symbols = size(mod_ofdm_syms, 2)/sim_consts.NumSubc;
%IFFT抽樣形式
resample_patt=[33:64 1:32];
%生成時域信號0矩陣
time_syms = zeros(1, num_symbols*64);
% 將信號轉為時域 64點IFFT
syms_into_ifft = zeros(64, num_symbols);
%將一個OFDM符號中的子載波以列的形式按照 UsedSubcIdx [7:32 34:59]放置到IFFT調制矩陣中 (52行 OFDM符號數列)
syms_into_ifft(sim_consts.UsedSubcIdx,:) = reshape(mod_ofdm_syms, ...
sim_consts.NumSubc, num_symbols);
%按resample_patt=[33:64 1:32]抽取syms_into_ifft中子載波以列的方式進行IFFT變換
syms_into_ifft(resample_patt,:) = syms_into_ifft;
%IFFT
ifft_out = ifft(syms_into_ifft);
%轉換為行的形式
time_syms = ifft_out(:).';
6 模塊add_pilot_syms:
function mod_ofdm_syms = add_pilot_syms(mod_syms, sim_options)
global sim_consts;
%獲取信號數
n_mod_syms = size(mod_syms,2);
%獲取OFDM符號數
n_ofdm_syms = n_mod_syms/sim_consts.NumDataSubc;
%估計數據長度是否大于P序列,若大于則重復P序列
scramble_patt = repmat(sim_consts.PilotScramble,1,ceil(n_ofdm_syms/length(sim_consts.PilotScramble)));
%每個OFDM符號與一個P序列元素對應 列出需要用到的P序列元素
scramble_patt = scramble_patt(1:n_ofdm_syms);
%生成一個列為一個OFDM符號 行為48個數據載波的0矩陣
mod_ofdm_syms = zeros(sim_consts.NumSubc, n_ofdm_syms);
% 一列為一個OFDM符號 行為48個數據載波 將數據以DataSubcPatt[1:5 7:19 21:26 27:32 34:46 48:52]的形式填入
mod_ofdm_syms(sim_consts.DataSubcPatt,:) = reshape(mod_syms, sim_consts.NumDataSubc, n_ofdm_syms);
%將導頻載波形式PilotSubcSymbols填入 并與極性序列相乘 PilotSubcPatt為填入位置
mod_ofdm_syms(sim_consts.PilotSubcPatt,:) = repmat(scramble_patt, sim_consts.NumPilotSubc,1).* ...
repmat(sim_consts.PilotSubcSymbols, 1, n_ofdm_syms);
%將矩陣轉為序列
mod_ofdm_syms = mod_ofdm_syms(:).';
7 模塊add_cyclic_prefix.m:
function time_signal = add_cyclic_prefix(time_syms)
%OFDM信號數統計
num_symbols = size(time_syms, 2)/64;
%生成時域信號0矩陣 80為加CP后的總長 取決于CP長(CP長為16)
%協議規定GI長度為0.8μs IFFT周期為3.2μs
%即GI長為1/4的64點IFFT長 為16
time_signal = zeros(1, num_symbols*80);
%添加循環前綴CP
symbols = reshape(time_syms, 64, num_symbols);
%設定提取冗余數據長度 49:64(16)
tmp_syms = [symbols(49:64,:); symbols];
time_signal = tmp_syms(:).';
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -