📄 tbjh_20080407_runprog.m
字号:
%########## 基于欧洲数字视频地面广播(DVB-T)标准,多载波调制系统 ###########%
%################ DVB-T:2K模式(2048个子载波),1/4保护间隔 ###############%
%#################### 均衡器设计:包括同步和均衡两部分 #####################%
clc;
clear all;
fs=64/7*1e6; %采样频率
ts=1/fs; %采样周期
Tu=224e-6; %OFDM符号有效长度
Ts=Tu/2048; %采样周期:Ts=ts=7/64us=1/(64/7MHz)
gu=1/4; %保护间隔模式
delta=gu*Tu; %保护间隔长度
T_symbol=delta+Tu; %一个OFDM符号总长度
FS=2048; %IFFT/FFT的点数
GI=gu*FS; %保护间隔点数
Ns=FS+GI; %一个OFDM符号的点数
frame_min=0;
frame_max=67;
Kmin=0;
Kmax=1704;
N_carrier=Kmax+1; %有效载波数
symbols=10; %符号数
Num=2e5; %数据处理点数
t=ts*Num; %数据处理时间
fc=80*1e6;
%--------------------------------------------------------------------------
%% 载入数据 %%
load dvb_20080407.mat data_7; %载入实际采集DVB_T数据
rx=data_7;
symbols=fix(length(rx)/Ns)-1; %实际数据符号个数
%--------------------------------------------------------------------------
%% 分散导频信号产生 %%
for frame_no=0:3 %frame_no为符号标号,每四个符号为一个周期
p=0:floor(1704/12);
pilot_loca=3*mod(frame_no,4)+12*p;
pilot_loca=pilot_loca(find(pilot_loca<=1704&pilot_loca~=0&pilot_loca~=1704));
pilot_loca=[0 pilot_loca 1704];
pilot_pos{frame_no+1,1}=pilot_loca; %所产生的分散导频位置信息放置在元胞数组pilot_pos中
end
flag1=zeros(symbols,N_carrier); %flag1为信息位与分散导频位标志数组,1代表分散导频,0代表信息位
for frame_no=0:3
flag1_cycle(frame_no+1,pilot_pos{frame_no+1}+1)=1; %所生成的flag1_cycle位4行1705列,与一个周期的符号相对应
end
flag1_rep=repmat(flag1_cycle,ceil(symbols/4),1);
flag1=flag1_rep(1:symbols,:); %生成symbols行1705列的分散导频标志数组
%--------------------------------------------------------------------------
%% 连续导频信号产生 %%
CP=[0 48 54 87 141 156 192 201 255 279 282 333 432 450 483 525 531 618,...
636 714 759 765 780 804 873 888 918 939 942 969 984 1050 1101 1107,... %45个连续导频位置
1110 1137 1140 1146 1206 1269 1323 1377 1491 1683 1704];
flag2=zeros(symbols,N_carrier); %flag2为信息位与连续导频位标志数组,1代表连续导频,0代表信息位
for frame_no=0:symbols-1
flag2(frame_no+1,CP+1)=1; %生成symbols行1705列的连续导频标志数组
end
%--------------------------------------------------------------------------
%% 随机导频位数据产生 %%
register=ones(1,11); %生成随机导频位数据
for j=1:N_carrier
temp=mod(register(11)+register(9),2);
prbs(j)=register(11);
for i=1:10
register(11-i+1)=register(11-i);
end
register(1)=temp;
end
pilot_cycle=(4/3)*2*(1/2-prbs); %导频数据幅度变为4/3
pilot=repmat(pilot_cycle,symbols,1);
%##########################################################################
%################################ 同步部分 ##############################
%##########################################################################
%% 采样定时同步 %%
rx=data_7;
delta_cyjz=1; %预设采样时钟偏移(归一化后)
num_cytb=0;
%##########################################################################
while delta_cyjz~=0 %##################################################### %开始采样定时同步循环
len_cy=Ns*(symbols+1); %所有OFDM符号点数
Num_cy=10000; %内插数据数目
rx_cy=zeros(1,len_cy); %重新采样后的数据
if delta_cyjz>0
for i=1:len_cy-1
rx_cy(i)=delta_cyjz/Num_cy*rx(i)+(1-delta_cyjz/Num_cy)*rx(i+1); %内插后,左移位,重新采样,补偿采样定时偏差
end
rx_cy(len_cy)=rx(len_cy);
else
rx_cy(1)=rx(1);
for i=2:len_cy
rx_cy(i)=(1+delta_cyjz/Num_cy)*rx(i-1)-delta_cyjz/Num_cy*rx(i); %内插后,右移位,重新采样,补偿采样定时偏差
end
end
%--------------------------------------------------------------------------
%% FFT前粗同步 %%
N=FS;
G=GI;
T=1:3*N+2*G;
for i=1:length(T) %FFT窗移动的距离
data1=rx_cy(i:G+i-1); %data1对应一个符号的前GI个数据
data2=rx_cy(N+i:N+G+i-1); %data2对应一个符号的最后GI个数据
s(i)=data2*data1'; %求互相关值
ctb_cor(i)=abs(s(i)); %相关幅值
e(i)=1/(2*pi)*angle(s(i)); %小数频偏估计
end
%% 粗符号校正 %%
[Max_cor start_place]=max(ctb_cor(1:Ns)); %start_place对应一个符号的第一个数据
rx_ctb=rx(start_place:symbols*Ns+start_place-1); %以start_place所在处为数据起点
%% 分数频偏校正 %%
len_tx=length(rx);
tt = (1:len_tx)*ts;
rx_fpjz=rx.*exp(-1j*e(start_place)*1/Tu*2*pi*tt); %小数频偏旋转相位补偿
%--------------------------------------------------------------------------
%% 精符号同步 %%
delta_symbol=1; %预置一个精同步符号定时偏移值,进入循环
num_jtb=0; %精同步循环次数
while delta_symbol~=0 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %开始精符号同步循环
start_jtb=start_place-delta_symbol; %符号精同步后起始位置
rx_jtb=rx_fpjz(start_jtb:symbols*Ns+start_jtb-1); %以start_jtb所在处为数据起点
%--------------------------------------------------------------------------
%% 串并变换 %%
carriers_jtb=reshape(rx_jtb,Ns,symbols).'; %过信道后的数据还原回原来的symbols行2560列
%--------------------------------------------------------------------------
%% 去保护间隔 %%
carriers_subguard=carriers_jtb(:,FS*gu+1:end); %去掉保护间隔
%--------------------------------------------------------------------------
%% FFT %%
receiv_fft=(1/FS).*fft(carriers_subguard,FS,2); %接收信息作OFDM解调(2048点)
receiv_zpp=receiv_fft;
%--------------------------------------------------------------------------
%% 整数频偏估计与校正 %%
ppi=4;
e_cor=zeros(1,64);
for s=-32:1:31
e_cp1=receiv_zpp(ppi,(find(flag2(4,:)~=0))+172); %待校正符号连续导频位置值
e_cp2=receiv_zpp(ppi+1,(find(flag2(4,:)~=0))+172); %比较符号连续导频位置值
e_mov1=receiv_zpp(ppi,(find(flag2(4,:)~=0))+172+s); %取待校正符号导频位置左右平移后的值
e_mov2=receiv_zpp(ppi+1,(find(flag2(4,:)~=0))+172+s); %取比较符号导频位置左右平移后的值
e_cor(s+33)=abs(e_mov2*e_mov1'); %%利用导频自相关特性估计
end
[Max_cor start_cor]=max(e_cor(1:end)); %求利用自相关估计的最大值
receiv_zpjz=zeros(size(receiv_zpp));
zpp=start_cor-33;
if zpp>0
receiv_zpjz=[receiv_zpp(:,zpp+1:end),receiv_zpp(:,1:zpp)]; %zpp为正,则频域数据整体向左平移zpp个单位(频域循环移位)
else
receiv_zpjz=[receiv_zpp(:,end+zpp+1:end),receiv_zpp(:,1:end+zpp)]; %zpp为负,则频域数据整体向右平移zpp个单位(频域循环移位)
end
%--------------------------------------------------------------------------
%% 精同步前判断符号位置 %%
receiv_use=receiv_zpjz(:,(1:N_carrier)+172); %从解调符号中舍去作OFDM所加零点位
s_cor=zeros(4,2*1705-1); %存放4次相关的相关值
p_max=zeros(1,4); %存放4次相关的最大值
for i=1:4
symbols_first=receiv_use(1,:); %选取要处理数据第一个符号
pilot_select=flag1_cycle(i,:); %在4个分散导频符号周期内依次选取分散导频所在符号
cor=xcorr(abs(symbols_first),abs(pilot_select)); %对上述两组数据做互相关
s_cor(i,:)=abs(cor);
[Max_cor p_max(i)]=max(s_cor(i,:)); %得到相关峰值位置
end
[Min pilot_start]=min(abs((p_max-1705))); %取4个峰值位置离理想值1705最近的点
%% 导频位置校正(位置对应) %%
flag1_jz=[flag1_cycle(pilot_start:4,:);flag1_rep(1:symbols-(5-pilot_start),:)];
flag_jz=flag1_jz; %flag为信息位与所有导频位标志数组,1代表导频(分散和连续导频),0代表信息位
for frame_no=0:symbols-1
flag_jz(frame_no+1,CP+1)=1; %所生成的flag_jz位symbols行1705列
end
%--------------------------------------------------------------------------
%% 精同步估计(利用分散导频)
receiv_jtb=receiv_zpjz;
Tao=zeros(1,symbols);
for j=1:symbols
pilot_scat=find(flag1_jz(j,:)~=0); %分散导频位置向量
fi=angle(receiv_use(j,pilot_scat)); %分散导频相位向量
L=length(pilot_scat); %分散导频个数
for n=1:L-1
delta_fi=fi(n+1)-fi(n);
delta_p=pilot_scat(n+1)-pilot_scat(n);
Tao(j)=Tao(j)+delta_fi/delta_p;
end
Tao(j)=N/(2*pi)*Tao(j)/(L-1);
Td(j)=fix(Tao(j)); %符号定时偏移整数部分:符号定时偏移
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -