2016.04.22 – 04.25
个人理解笔记。(无通信基础且急躁,片面/错误概率大大的。已待纠正)
PSK/QAM过程将时域数据sdData映射到频域得到PSK/QAM符号pqSym。OFDM过程生成正交的子载波并将PSK/QAM符号(pqSym)调制各子载波上得到时域的OFDM符号[这个过程可通过ifft变换来完成];对该时域OFDM符号进行fft变换能得到pqSym符号,对这pqSym符号再进行PSK/QAM逆映射就可得到时域数据sdData。该过程可表述如下:
Figure 1. 一个OFDM符号的生成与解析过程
在matlab中描述一个OFDM符号的生成与解析过程如下:
an_ofdm_sym.m
% an_ofdm_sym.m
% 一个ofdm符号的生成和解析过程描述
clear
% --------OFDM信号生成---------------------------------------------------
Nbps = 4; % Nbps = 1/2/4/6对应BPSK/QPSK/16QAM/64QAM调制
M = 2 ^ Nbps; % 相应的调制只能调制M进制数
Nfft = 64; % Nfft点ifft/fft变换
NsdData = Nfft; % 每个OFDM信号发送的数据个数
% 生成Nframe * NsdData个M进制数
sdData = randi([0, M - 1], 1, NsdData);
% @@@@@@@@ MPSK/MQAM映射(时-->频) - 发送的数据与波形振幅、相位的映射关系 @@@@@@@@
if Nbps > 2
mapObj = modem.qammod(M);
else
mapObj = modem.pskmod(M);
end % 构建映射对象
sdMapSym = modulate(mapObj, sdData); % 得到映射符号
% @@@@@@@@ 用ifft变换生成ofdm符号(频-->时) @@@@@@@@
sdOfdmSym = ifft(sdMapSym);
% --------OFDM信号解析---------------------------------------------------
rvOfdmSym = sdOfdmSym;
% @@@@@@@@ 用fft将ofdm信号变换为原映射符号(时-->频) @@@@@@@@
rvMapSym = fft(rvOfdmSym);
% @@@@@@@@ 解析QAM符号恢复原有数据(频-->时) @@@@@@@@
rvData = qamdemod(rvMapSym, M);
运行an_ofdm_sym,rvData和sdData相等。
Nframe个OFDM符号的多径信道链路包括:生成Nframe个OFDM符号的模块、多径信道模块以及解析Nframe个OFDM符号的模块。
分析/打算:
[1] 先忽略关于多径信道的细节直接挪用参考书 [1] 中的多径信道模型(米要理解它可能会是一个曲折的过程);
[2] 在多径信道模型中同时传输Nframe个OFDM符号。
[1] matlab将要描述的Nframe个OFDM符号的多径信道链路框图
Figure 3. Nframe个OFDM符号的多径信道链路模型
[2] Nframe个ofdm多径信道链路matlab描述
Nframe_ofdm_multi_ch_link.m
% Nframe_ofdm_multi_ch_link.m
% 生成ofdm信号;ofdm在多径信道中传输;解析经多径信道后的ofdm信号
clear
% --------OFDM信号生成模块---------------------------------------------------
Nbps = 4; % Nbps = 1/2/4/6对应BPSK/QPSK/16QAM/64QAM调制
M = 2 ^ Nbps; % 相应的调制只能调制M进制数
Nfft = 64; % Nfft点ifft/fft变换
NsdData = Nfft; % 每个OFDM信号发送的数据个数
Nframe = 3; % 每次发送Nframe个OFDM信号
% 生成Nframe * NsdData个M进制数
sdData = randi([0, M - 1], 1, Nframe * NsdData);
% @@@@@@@@ MPSK/MQAM映射(时-->频) - 发送的数据与波形振幅、相位的映射关系 @@@@@@@@
if Nbps > 2
mapObj = modem.qammod(M);
else
mapObj = modem.pskmod(M);
end % 构建映射对象
sdSerMapSym = modulate(mapObj, sdData); % 得到映射符号
% @@@@@@@@ PSK/QAM符号串转并 @@@@@@@@
sdParMapSym = zeros(Nframe, NsdData);
for i = 1 : Nframe
s2pIndex = (i - 1) * NsdData + 1 : i * NsdData;
sdParMapSym(i, :) = sdSerMapSym(s2pIndex);
end
% @@@@@@@@ 用ifft变换生成ofdm符号(频-->时) @@@@@@@@
sdOfdmSym = zeros(Nframe, NsdData);
for i = 1 : Nframe
sdOfdmSym(i, :) = ifft(sdParMapSym(i, :));
end
% @@@@@@@@ Nframe个ofdm符号并转串 @@@@@@@@
sdSerOfdmSym = zeros(1, Nframe * NsdData);
for i = 1 : Nframe
p2sIndex = (i - 1) * NsdData + 1 : i * NsdData;
sdSerOfdmSym(p2sIndex) = sdOfdmSym(i, :);
end
% --------Nframe个OFDM符号经过多径信道模块---------------------------------
powerdB = [0 -8 -17 -21 -25]; % 信道抽头功率分布(dB)
delay = [0 3 5 6 8]; % 信道延迟样本
power = 10.^(powerdB / 10); % 信道抽头功率分布(线性)
ntap = length(powerdB); % 信道抽头数
lch = delay(end)+1; % 信道长度
% 多径信道模型
channel = (randn(1, ntap) + 1i * randn(1, ntap)).* sqrt(power / 2);
h = zeros(1, lch);
h(delay + 1) = channel; % 信道脉冲响应
% 多径信道对Nframe个ofdm符号的影响
y = conv(sdSerOfdmSym, h);
% --------OFDM符号解析模块---------------------------------------------------
rvSerOfdmSym = y;
% @@@@@@@@ 对Nframe个ofdm符号串转并 @@@@@@@
rvOfdmSym = zeros(Nframe, NsdData);
for i = 1 : Nframe
s2pIndex = (i - 1) * NsdData + 1 : i * NsdData;
rvOfdmSym(i, :) = rvSerOfdmSym(s2pIndex);
end
% 频域信道补偿
ofdmIndex = 1 : NsdData;
fresp = fft([h zeros(1, Nfft - lch)]);
fch_cpenst(ofdmIndex) = fresp(ofdmIndex);
% @@@@@@@@ 用fft将ofdm信号变换为原映射符号(时-->频) @@@@@@@@
rvParMapSym = zeros(Nframe, NsdData);
for i = 1 : Nframe
temp = fft(rvOfdmSym(i, :));
rvParMapSym(i, :) = temp./fch_cpenst;
end
% @@@@@@@@ PSK/QAM符号并转串 @@@@@@@@
rvSerMapSym = zeros(1, Nframe * NsdData);
for i = 1 : Nframe
p2sIndex = (i - 1) * NsdData + 1 : i * NsdData;
rvSerMapSym(p2sIndex) = rvParMapSym(i, :);
end
% @@@@@@@@ 解析QAM符号恢复原有数据(频-->时) @@@@@@@@
rvData = qamdemod(rvSerMapSym, M);
运行Nframe_ofdm_multi_ch_link,sdData和rvData部分元素不同,这是因为OFDM信号受到了多径信道的干扰。为正确接收到所发送的数据,需要避免多径信道对OFDM符号的干扰。
04.25
在多径信道干扰下,发送数据和解析数据有部分不同,为了解决这个问题,可以往ofdm中添加保护间隔来解决[见以下程序中保护间隔的含义;多径信道对ofdm的干扰暂停留在该层次]。
Nframe_ofdm_multi_channel_link.m
% Nframe_ofdm_multi_channel_link.m
% 生成ofdm信号;
% 为ofdm添加保护间隔,ofdm在多径信道中传输;
% 解析经多径信道后的ofdm信号。
clear
NgType = 1;
Ch = 1; % Ch=0/1对应AWGN/多径信道
% --------OFDM符号生成模块-------------------------------------------------
Nbps = 4; % Nbps = 1/2/4/6对应BPSK/QPSK/16QAM/64QAM调制
M = 2 ^ Nbps; % 相应的调制只能调制M进制数
Nfft = 64; % Nfft点ifft/fft变换
Ngi = Nfft / 4; % GI (保护间隔) 长度 (Ng=0 for no GI)
Nsym = Nfft + Ngi; % OFDM符号长度
Ndata = Nfft; % OFDM符号中的实际数据的长度
Nframe = 3; % 每次发送Nframe个OFDM符号
% @@@@@@@@ 生成Ndata * Nframe个M进制数据 @@@@@@@@
DataSource = randi([0, M - 1], 1, Ndata * Nframe);
% @@@@@@@@ 将数据映射为QAM符号(时-->频) @@@@@@@@
MapObj = modem.qammod(M);
ModSym = modulate(MapObj, DataSource);
% @@@@@@@@ QAM符号串转并 @@@@@@@@
ModSymSrl2PrlIndx = 1 : Ndata;
ModPrlSym = zeros(Nframe, Ndata);
for i = 1 : Nframe
ModPrlSym(i, :) = ModSym(ModSymSrl2PrlIndx);
ModSymSrl2PrlIndx = ModSymSrl2PrlIndx + Ndata;
end
% @@@@@@@@ 利用ifft变换生成OFDM符号 @@@@@@@@
OfdmSym = zeros(Nframe, Ndata);
for i = 1 : Nframe
OfdmSym(i, :) = ifft(ModPrlSym(i, :));
end
% @@@@@@@@ 为每个OFDM符号添加保护间隔 @@@@@@@@
GIOfdmSymIndx = 1 : Nsym;
OfdmSym_GI = zeros(Nframe, Nsym);
for i = 1 : Nframe
OfdmSym_GI(i, :) = guard_interval(Ngi, Ndata, NgType, OfdmSym(i,:));
end
% @@@@@@@@ 带保护间隔的OFDM符号并转串 @@@@@@@@
GIOfdmSrlSymIndx = 1 : Nsym;
OfdmSrlSym_GI = zeros(1, Nframe * Nsym);
for i = 1 : Nframe
OfdmSrlSym_GI(GIOfdmSrlSymIndx) = OfdmSym_GI(i, :);
GIOfdmSrlSymIndx = GIOfdmSrlSymIndx + Nsym;
end
% --------OFDM符号经过多径信道模块-----------------------------------------
PowerdB = [0 -8 -17 -21 -25]; % 信道抽头功率分布(dB)
Delay = [0 3 5 6 8]; % 信道延迟样本
Power = 10.^(PowerdB / 10); % 信道抽头功率分布(线性
Ntap = length(PowerdB); % 信道抽头数
Lch = Delay(end) + 1; % 信道长度
channel = (randn(1, Ntap) + 1i * randn(1, Ntap)).*sqrt(Power / 2);
h = zeros(1, Lch);
h(Delay+1) = channel; % 信道脉冲响应
y = conv(OfdmSrlSym_GI,h);
% --------OFDM符号解析模块---------------------------------------------
rvOfdmSrlSym_GI = y;
OfdmSymIndx = 1 : Ndata;
H = fft([h zeros(1, Nfft - Lch)]); % 信道频域响应
ChFrqRep = H(OfdmSymIndx);
% @@@@@@@@ 带保护间隔的OFDM符号串转并 @@@@@@@@
rvOfdmSym_GI = zeros(Nframe, Nsym);
GIOfdmSrlSymIndx = 1 : Nsym;
for i = 1 : Nframe
rvOfdmSym_GI(i, :) = rvOfdmSrlSym_GI(GIOfdmSrlSymIndx);
GIOfdmSrlSymIndx = GIOfdmSrlSymIndx + Nsym;
end
% @@@@@@@@ 去掉OFDM符号的保护间隔 @@@@@@@@
rvOfdmSym = zeros(Nframe, Ndata);
for i = 1 : Nframe
rvOfdmSym(i, :) = remove_GI(Ngi, Nsym, NgType, rvOfdmSym_GI(i, :));
end
% @@@@@@@@ 用fft变换将OFDM符号变为QAM符号(时-->频),并进行信道补偿 @@@@@@@@
rvModPrlSym = zeros(Nframe, Ndata);
for i = 1 : Nframe
temp = fft(rvOfdmSym(i, :));
rvModPrlSym(i, :) = temp./ChFrqRep;
end
% @@@@@@@@ QAM符号并转串 @@@@@@@@
rvModSym = zeros(1, Nframe * Ndata);
ModSymPrl2SrlIndx = 1 : Ndata;
for i = 1 : Nframe
rvModSym(ModSymPrl2SrlIndx) = rvModPrlSym(i, :);
ModSymPrl2SrlIndx = ModSymPrl2SrlIndx + Ndata;
end
rvData = qamdemod(rvModSym, M);
guard_interval.m
function y = guard_interval(Ngi, Ndata, NgType, OfdmSym)
% 为OFDM添加保护间隔 - 循环前缀
if Ngi ~= 0
if NgType == 1
y = [OfdmSym(Ndata - Ngi + 1 : Ndata) OfdmSym(1 : Ndata)];
end
else
y = OfdmSym;
end
end
remove_GI.m
function y = remove_GI(Ngi, Nsym, NgType, OfdmSym)
% 去掉OFDM的保护间隔 - 循环前缀
if Ngi ~= 0
if NgType == 1
y = OfdmSym(Ngi + 1 : Nsym); % 丢掉OFDM符号的循环前缀
end
else
y = OfdmSym;
end
end
运行Nframe_ofdm_multi_channel_link,在Ngi=0时,DataSource和rvData仍有部分元素不同;在Ngi=Nfft / 4(该值要大于多径信道的最大延迟长度,本Rayleigh信道的最大延迟为15)时,DataSource和rvData完全相同。
在探索OFDM多径链路的性能指标时再返回到多径信道了解它相关的详细信息。
[2016.04.22 - 22:08]