第10讲 802.11a OFDM基带接收端帧同步算法设计与验证
OFDM基带的接收端不是简单的发送端的逆运算。由于通过DAC数模变换、射频的调制变频、信道、射频解调变频、ADC采样,以上过程可以称为广义的信道,带来了信号的非线性畸变。接收系统如果想恢复出原始发送码流根据功能分成两大部分,信道补偿和比特逆运算。信道补偿主要是利用发送端的帧结构特性(比如训练序列、导频、循环前缀等)进行帧同步(寻找信号帧的起始点)、载波频偏补偿(消除收发系统载波的偏差)、信道估计与均衡(消除多径效应与信道衰落)、解星座映射等;比特逆运算是指,解交织、信道译码、解扰等,基本是发送端的逆处理。接收系统的框图如图10-1,由图可知,接收端的处理算法要比发送端复杂得多。
10.1实验目的
学习帧同步算法原理,通过软件仿真与实际YunSDR信道接收信号分别对同步算法验证。
10.2 实验条件
YunSDR平台一套,Matlab软件环境,天线或射频电缆回环。
10.3实验要求
使用Matlab编写粗同步与细同步模块,通过软件仿真与实际信道验证。,通过Matlab程序验证同步算法。
10.4实验原理
IEEE802.11a系统是信道应答脉冲响应在数据突发期间没有发生显著变化的假定前提下设计的,这样的假定在发送数据分组的极短时间内可以证明是合理的他通常是几毫秒,因为发射机和接收机在大多数应用中互相间移动是较小的。该假设下大部分WLAN接收机的同步可以在前导期间完成并且在数据分组期间不需要改变。需要考虑的同步有三种,即:定时同步、频率同步和采样时间同步。本讲对定时同步进行介绍。
定时同步是估计出OFDM符号的起始位置,它主要包括两个部分:分组同步(粗同步)和符号同步(细同步)。如果符号后FFT的起始位置在循环前缀(CP)的长度内,那么子载波间的正交性依然能够保持,在这种情况下,符号同步偏差可以看做是信道引起的相位旋转,这一旋转可以由信道估计求出并通过信道均衡消除。如果符号同步的偏差超过了保护间隔,就会引入载波间干扰(ICI)。导致无法正确计算出FFT窗口位置,误码率成倍提高。因此,OFDM系统对定时同步的要求相对宽松,但是在多径环境中,为了获得最佳的系统性能,需要确定最佳的定时估计。尽管定时估计的起点可以在保护间隔内任意选取,但是容易得知,任何定时估计起点的变化,都会增加OFDM系统对实验扩展的敏感程度,因此系统所能容忍的时延扩展会低于其设计值。为了尽量减小这种负面影响,需要尽量减小定时同步的估计误差。
系统定时估计算法可以分为两步完成,第一步通过分组检测进行粗同步(分组同步估计),第二步采用符号同步进行细同步(符号同步估计)。这两部同步估计都才用前导序列来完成。分组检测是指判断出数据分组到达的准确位置,这是一种粗同步同时也是随后进行频率同步和符号同步的基础,剩下的同步过程都依赖于分组检测完成的优劣在分组检测中以下声明代表是否出现了分组:
通常的方法是采用双滑动分组检测技术,基本原理如下:双滑动窗口的分组检测算法计算了两个连续滑动窗口的能量,分别是后面窗口的自相关能量和前后窗口的互相关能量因为短训练序列的特性是10个连续相同的符号进行重复,所以当窗口移动到信号的开始时互相关的能量和自相关的能量应该相差很小。信号运算流程图如图10-2:
IEEE802.11a系统中的符号同步通常实在分组同步之后进行,当分组估计提供数据分组起始界限后,因为频偏会影响符号同步,先进行粗频偏估计,然后再进行符号同步,符号同步估计算法将该估计精确到量化等级。符号同步能够找到长训练序列的起始点,符号同步的方法是通过计算接收信号r(n)和本地长训练序列参考信号t(n)之间的互相关性实现的。如下:
其中L为滑动窗口的长度,L只要大于短训练序列的长度就可以,因为分组检测到短训练序列的起始点,所以这里取L=200即可。N为参考信号t(n)的采样点数目,N=64。通过计算出滑动窗口中不同n的ts,找出最大ts对应的n,作为符号定时的结果。
10.5参考设计
分组同步与定时同步例程分为以下几部分:
- 获取接收信号
接收信号可以有几个来源:
(1) 读取Matlab发端保存的txt文件
[a9 a10]=textread('E:\code\ieee802_11a\data\trans_frame.dat','%f%f');
frame=a9+1i*a10;
rx_signal_40m =frame./4;
rx_signal=rx_signal_40m(1:2:end).';
1.读取YunSDR接收的数据
data = fread(data_link,buff_size*1024,'uint8');
%% data 8bit to 16bit
datah=data(2:2:end);
datal=data(1:2:end);
datah_hex=dec2hex(datah,2);
datal_hex=dec2hex(datal,2);
data_hex(:,1:2)=datah_hex;
data_hex(:,3:4)=datal_hex;
dataun=hex2dec(data_hex);
datain=dataun-(dataun>32767)*65536;
a1=datain(1:2:end);
a2=datain(2:2:end);
meani=mean(a1);
meanq=mean(a2);
rx_signal_40m=(a1+1i*a2);
rx_signal=rx_signal_40m(1:2:end).';
2.抽取
IEEE802.11a标准规定20MHz采样率,实际硬件采集的采样率是40MHz,所以需要从接收到的数据中抽取,参考例程采用最简单的方法二选一,代码见“1 获取接收信号”。
3. 增加仿真频偏
%% 添加频偏
phase_offset=620e3;
rad_offset = 2*pi*phase_offset/20000000;
time_base=0:length(rx_signal)-1;
dds_offset=exp(-j*rad_offset*time_base);
rx_signal = rx_signal.*dds_offset;
4. 加入仿真实多径
%% 添加多径
r=3;%多径数
a=[0.1 0.2 0.3];%多径幅度
d=[5 10 15];%多径延时
rx1=rx_signal;
channel1=zeros(1,length(rx1));
channel1(1+d(1):end)=a(1)*rx1(1:end-d(1));
channel2=zeros(1,length(rx1));
channel2(1+d(2):end)=a(2)*rx1(1:end-d(2));
channel3=zeros(1,length(rx1));
channel3(1+d(3):end)=a(3)*rx1(1:end-d(3));
rx_signal=rx1+channel1+channel2+channel3;
5. 加入仿真噪声
rx_signal=awgn(rx_signal,14,'measured');
6. 分组同步(粗同步)
采用双滑动窗口法,计算互相关与自相关,并判断比值是否超过阈值,实际操作中由于信道的不确定性和噪声的随机性,将判断连续超过阈值一段时间才认为同步成功。
Nrx=size(rx_signal,2);
Ns=size(rx_signal,1);
L=16;
for i=1:Nrx
for j=1:Ns-L*2
rx_delay_corr(j,i) = abs(sum(rx_signal(j:j+L-1,i).*conj(rx_signal(j+L:j+L*2-1,i))));
rx_self_corr(j,i) = sum(rx_signal(j+L:j+L*2-1,i).*conj(rx_signal(j+L:j+L*2-1,i)));
end
end
rx_corr_ratio=rx_delay_corr./rx_self_corr;
pass=0;
for i=1:Ns-L*2
rx_corr(i)=sum(rx_corr_ratio(i,1:Nrx));
if rx_corr(i)>=0.75*Nrx
pass=pass+1;
else
pass=0;
end
if pass==64
thres_idx=i-63;
break
end
End
7. 定时同步(细同步)
在粗频偏估计之后,将本地长训练序列与接收长训练序列相关,进行判断。
end_search=400;
% 得到长训练序列的时域信号
long_tr = sim_consts.legacylongtraning;
long_tr_symbols = tx_freqd_to_timed(long_tr,1,sim_consts.nonHTNumSubc);
ltrs = long_tr_symbols;
long_trs=[ltrs(end/2+1:end);ltrs(1:end/2)];
long_trs_pwr=sum(long_trs.*conj(long_trs));
Nrx=size(rx_signal,2);
Ns=size(rx_signal,1);
L=64;
for i=1:Nrx
for j=1:Ns-L*2
rx_cross_corr(j,i) = abs(sum(rx_signal(j:j+L-1,i).*conj(long_trs)));
rx_self_corr(j,i) = sum(rx_signal(j:j+L-1,i).*conj(rx_signal(j:j+L-1,i))).^0.5;
rx_cross_ratio(j,i)=rx_cross_corr(j,i)./rx_self_corr(j,i);
if rx_cross_ratio(j,i)>0.4
thres_idx(i)=j;
break
end
end
End