文章目录
- 前言
- 一、OFDM 同步技术
- 二、MATLAB 仿真
- 1、STO 估计技术
- ①、核心源码
- ②、仿真结果
- 2、CFO 估计技术
- ①、核心源码
- ②、仿真结果
- 三、资源自取
前言
本文对 OFDM 同步技术以思维导图的形式呈现,有关仿真部分进行了讲解实现。
一、OFDM 同步技术
OFDM 同步技术思维导图如下图所示,如有需求请到文章末尾端自取。
二、MATLAB 仿真
1、STO 估计技术
①、核心源码
%基于CP,采用最大相关和最小距离算法完成STO的估计
clear, figure(1), clf, figure(2), clf
nSTOs = [-3 -3 2 2]; % 对应 STO 的采样数 提前、提前、滞后、滞后
CFOs = [0 0.5 0 0.5]; % CFO 向量
SNRdB = 30; % SNR
MaxIter = 10; % 迭代次数
%CFOs = [0 0 0 0];
Nfft = 128; % FFT 大小
Ng = Nfft/4; % GI 长度
Nofdm = Nfft + Ng; % OFDM 符号长度
Nbps = 2; % 2/4 对应 QPSK/16QAM
M = 2^Nbps; % 符号对应的可能性数量
Es = 1;
A = sqrt(3/2/(M-1)*Es); % QAM 归一化因子
N = Nfft;
com_delay = Nofdm/2; % 公共时延
Nsym = 100; % 一共有一百个 OFDM 符号
rand('seed',1); % 设置种子
randn('seed',1);
for i = 1:length(nSTOs) % 对于每一个不同的 \delta STO
nSTO = nSTOs(i);
CFO = CFOs(i);
x = []; % 初始化信号块,最后 x 就是发送出来的 OFDM 模块
for m = 1:Nsym % 随机位生成
msgint=randi([0 M-1], 1, N); % 生成传输符号,1*128 个 0-3 的数
Xf = A .* qammod(msgint, M, 'UnitAveragePower', true);% 调制成复数
%***********************缺少了倒置的过程***********************%
xt = ifft(Xf, Nfft); % 发送
x_sym = add_CP(xt, Ng); % 加 CP
x = [x x_sym];
end
%*********************** 信道 ************************%
%%%%%在这里根据需求添加信道,先假设是没有信道
y = x; % 没有信道影响
sig_pow = y*y' / length(y); % 计算能量,sig_pow= mean(mean(y.*conj(y),2))
% 频率偏移 + 符号定时偏移
y_CFO = add_CFO(y, CFO, Nfft); % 加 CFO
y_CFO_STO = add_STO(y_CFO, -nSTO); % 加STO,这是加在整个信号上的,因此头尾补零就行了;但是取-是因为:δ<0 是提前,δ>0是滞后
v_ML = zeros(1, Ng); % 初始化
v_Cl = zeros(1, Ng);
Mag_cor = 0; % arg的结果
Mag_dif = 0;
%%添加加性高斯白噪声
for iter = 1:MaxIter
% 加噪声
y_aw = awgn(y_CFO_STO, SNRdB, 'measured');
%%%%%%%符号定时获取
[STO_cor, mag_cor] = STO_by_correlation(y_aw, Nfft, Ng, com_delay); % 书中自带
[STO_cor_temp,mag_cor_temp] = STO_by_correlation_sim1(y_aw,Nfft,Ng,com_delay); % 我自己编写
%%%%%经验证,以上两者函数结果一致
[STO_dif,mag_dif] = STO_by_difference(y_aw,Nfft,Ng,com_delay); %书中自带
[STO_dif_temp,mag_dif_temp] = STO_by_difference_sim1(y_aw,Nfft,Ng,com_delay); %我自己编写
%%%%%经验证,以上两者函数结果一致
% 计数
% 这里取反了,返回了符合"左加右减"的直觉的STO
v_ML(-STO_cor+Ng/2)= v_ML(-STO_cor+Ng/2)+1;
v_Cl(-STO_dif+Ng/2)= v_Cl(-STO_dif+Ng/2)+1;
Mag_cor= Mag_cor + mag_cor;
Mag_dif= Mag_dif + mag_dif;
end % End of for loop of iter
%%%%%%% Probability
v_ML_v_Cl = [v_ML; v_Cl]*(100/MaxIter); % 取百分数
figure(1+i-1);
set(gca,'fontsize',9); % 将当前坐标轴的字体大小设置为9
% subplot(220+i)
bar(-Ng/2+1:Ng/2,v_ML_v_Cl');
hold on, grid on
str = sprintf('nSTO Estimation: nSTO=%d, CQFO=%1.2f, SNR=%3d[dB]',nSTO,CFO,SNRdB);
title(str);
xlabel('Sample'), ylabel('Probability');
legend('ML','Classen');
axis([-Ng/2-1 Ng/2+1 0 100])
%%%%%%% Time metric
Mag_cor = Mag_cor/MaxIter;
[Mag_cor_max,ind_max] = max(Mag_cor);
nc= ind_max-1-com_delay;
Mag_dif = Mag_dif/MaxIter;
[Mag_dif_min,ind_min] = min(Mag_dif);
nd= ind_min-1-com_delay
nn= -Nofdm/2 + [0:length(Mag_cor)-1]; % -80~79
% nt= nSTO;
% figure(2);
% subplot(220+i);
figure(5+i-1);
plot(nn,Mag_cor,nn,1.5*Mag_dif,'r:','markersize',1);
hold on
stem(nc,Mag_cor_max,'b','markersize',5);
stem(nSTO,Mag_cor(nSTO+com_delay+1),'k.','markersize',5); % Estimated/True Maximum value
str1 = sprintf('STO Estimation - ML(b-)/Classen(r:) for nSTO=%d, CFO=%1.2f',nSTO,CFO); %,SNRdB);
title(str1);
xlabel('Sample'), ylabel('Magnitude');
%stem(n1,Mag_dif_min,'r','markersize',5)
stem(nd,Mag_dif(nd+com_delay+1),'r','markersize',5);
stem(nSTO,Mag_dif(nSTO+com_delay+1),'k.','markersize',5); % Estimated/True Minimum value
set(gca,'fontsize',9, 'XLim',[-32 32], 'XTick',[-10 -3 0 2 10]); %, xlim([-50 50]),
legend('基于相关的','基于差值最小的');
end % End of for loop of i
完整源码文末自取
②、仿真结果
由上两个图所示,当 STO = -3,CFO = 0时,可以看到基于差值最小的方法估计的 STO 更为准确。
由上两个图所示,当 STO = -3,CFO = 0.5时,可以看到基于差值最小的方法和基于相关估计的 STO 都很准确。
由上两个图所示,当 STO = 2,CFO = 0 时,可以看到基于差值最小的方法和基于相关估计的 STO 都很准确。
由上两个图所示,当 STO = 2,CFO = 0.5 时,可以看到基于差值最小的方法估计的 STO 更为准确。
2、CFO 估计技术
①、核心源码
%完成时域基于CP的方法和频域的Moose/Classen方法,用于后续CFO补偿
clear, clf
CFO = 0.15; % CFO(载波频率偏移)大小
% CFO = 0;
Nfft=128; % FFT采样数
Nbps=2; % QPSK或QAM
M=2^Nbps; % 每个符号代表几比特
Es=1; % 能量
A=sqrt(3/2/(M-1)*Es); % QAM归一化
N=Nfft; % 发送的符号长度,为了方便,和Nfft保持一致
Ng=Nfft/4; % GI长度
Nofdm=Nfft+Ng; % 一个OFDM符号的长度
Nsym=3; % 一共发送了3个OFDM符号,前两个是导频,最后一个是真正发送的数据符号
% h=complex(randn,randn)/sqrt(2);
% %h=[1 zeros(1,5)];
% channel(h,0);
%Transmit signal
x=[];
for m=1:Nsym % 前两个是导频,最后一个是真正发送的数据符号
msgint=randi([0 M-1],1,N); % 生成要发送的符号
if m<=2 %
Xp = add_pilot(zeros(1,Nfft),Nfft,4); % 生成导频
Xf=Xp; % add_pilot
else %Xf= QAM(msgint((i-1)*N+1:i*N),Nbps); % constellation mapping. average power=1
Xf = A.*qammod(msgint,M,'UnitAveragePower',true);
end
xt = ifft(Xf,Nfft); % ifft
x_sym = add_CP(xt,Ng); % 加CP
x= [x x_sym]; % 将三个OFDM符号依次拼接
end
%channel 可添加所需信道
y=x; % No channel effect
%Signal power calculation
sig_pow= y*y'/length(y); % Signal power calculation
%%%%
SNRdBs= 0:3:30;
% SNRdBs= 100; 设100是为调试程序
MaxIter = 100;
for i=1:length(SNRdBs)
SNRdB = SNRdBs(i);
MSE_CFO_CP = 0;
MSE_CFO_Moose = 0;
MSE_CFO_Classen = 0;
rand('seed',1); % 设置种子来保证每次仿真结果一致
randn('seed',1);
y_CFO= add_CFO(y,CFO,Nfft); % 增加CFO,此处是在时域添加的,因此是×相位
% 多次迭代取平均
for iter=1:MaxIter
%y_aw=add_AWGN(y_CFO,sig_pow,SNRdB,'SNR',Nbps); % AWGN added, signal power=1
y_aw = awgn(y_CFO,SNRdB,'measured'); % 增加高斯白噪声
Est_CFO_CP = CFO_CP(y_aw,Nfft,Ng); % CP-based % 根据CP测算CFO
MSE_CFO_CP = MSE_CFO_CP + (Est_CFO_CP-CFO)^2; % 平方累计
Est_CFO_Moose = CFO_Moose(y_aw,Nfft); % Moose估计
MSE_CFO_Moose = MSE_CFO_Moose + (Est_CFO_Moose-CFO)^2;% 平方累计
Est_CFO_Classen = CFO_Classen(y_aw,Nfft,Ng,Xp); % Classen (Pilot-based)
MSE_CFO_Classen = MSE_CFO_Classen + (Est_CFO_Classen-CFO)^2;
end % the end of for (iter) loop
MSE_CP(i) = MSE_CFO_CP/MaxIter;
MSE_Moose(i) = MSE_CFO_Moose/MaxIter;
MSE_Classen(i) = MSE_CFO_Classen/MaxIter;
end%ebn0 end
semilogy(SNRdBs, MSE_CP,'-+');
grid on, hold on
semilogy(SNRdBs, MSE_Moose,'-x'); semilogy(SNRdBs, MSE_Classen,'-*');
xlabel('SNR[dB]'), ylabel('MSE'); title('CFO Estimation'); %axis([0 30 10e-8 10e-2])
% str=sprintf('CFO = %1.2f',CFO);
legend('CP-based technique','Moose (Preamble-based)','Classen (Pilot-based)');
% legend(str);
完整源码文末自取
②、仿真结果
可以观察到,随着接收信号的 SNR 增大,CFO 估计的 MSE 减小。估计技术的性能取决于用于 CFO 估计的 CP 中的采样数、前导数和导频数。
三、资源自取
链接:OFDM同步技术
我的qq:2442391036,欢迎交流!