一、本文意义
基于matlab程序,实现OFDM发射机(802.11a)中训练符号(短训练序列、长训练序列)的时域样值正确计算。
二、问题描述
IEEE 802.11a标准所规定的物理层协议数据单元(Physical Protocol Data Unit,PPDU)帧结构,也就是基带发射处理器索要生成的数据结构。接收机的定时同步、载波频偏估计以及信道估计等都是由前置的两个训练符号完成的。训练符号包括10个周期重复的短训练符号(Short Training Symbol,STS)t1-t10(每个符号的间隔为正常OFDM符号间隔的1/4)和2个周期重复的长训练序列(Long Training Symbol,LTS)T1-T2(符号间隔与正常OFDM符号相同)两个部分。总的训练序列时间长度为16us。关于训练序列的作用此处不再赘述,想搞清楚的筒子们,可以去读《基于xilinx fpga 的ofdm的通信系统基带设计》这本教材。
教材“第四章、OFDM发射机设计及实现”中“4.1 训练序列的生成”主要讲长短序列的生成。开始对STS和LSTS时域样值(如下面表所示)懵懂,准备飘过。到后面接收机同步的符号同步部分,需要用到STS的时域值,必须要搞定了。把书翻回去看,大概意思懂了,还是不知道怎么计算出来的。
不懂问搜狗,找到CSDN的一篇参考文章(见本文最后的链接)——主要将长短序列的生成仿真实现,很有价值的参考(楼主:xl@666)。把作者的代码拷贝运行(原代码有误,需要再零频点补零),哇呼,怎么就算不出来书上的结果,总是差个正负号,要么实部要么虚部,总是不对。(这篇文章后面的评论,也有同样的疑问,估计楼主太忙没给解决)
三、问题分析
本着“有困难要解决,没有困难创造困难也要解决”的科研精神,经过认真分析,回忆学过的知识,终于找到问题所在——IFFT函数的频点序号。MATLAB中的FFT函数和IFFT计算出来的都是按照正频率(0~fs/2)、负频率(-fs/2~0)的顺序排列的,而参考文章仿真程序用的书上频点顺序:按照负频率(-fs/2~0)、正频率(0~fs/2)顺序排列的(下面贴出来的)。
四、问题解决
分析出问题根源,于是在参考文章原代码的基础上修改,在进行ifft计算前,首先通过fftshift函数调整频点顺序(当然,也可以自行修改程序中STS、LST的定义)。修改后正确的短、长训练序列的生成代码如下:
% STS频域表示,频点为-32~31,此处将52个频点外的零补全。
S=[0,0,0,0,0,0,0,0,1+i,0,0,0,-1-i,0,0,0,1+i,0,0,0,-1-i,0,0,0,-1-i,0,0,0,1+i,0,0,0,0,0,0,0,-1-i,0,0,0,-1-i,0,0,0,1+i,0,0,0,1+i,0,0,0,1+i,0,0,0,1+i,0,0,0,0,0,0,0];
% LTS频域表示,频点为-32~31,此处将52个频点外的零补全。
L=[0,0,0,0,0,0,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,0,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,0,0,0,0,0];
% 保证OFDM符号的功率值稳定
S=(13/6)^(1/2)*S;
% 64点的傅里叶逆变换,变成时域
% !!!通过IFFT函数将STS频域的频点顺序调整为正频率(0~31)、负频率(-32~-1)
short=ifft(fftshift(S));
% 取前1~16个点,可以验证,后面17~32、33~48、49~64的数值都是1~16的复制
short_cp=short((1:16));
short=short_cp;
% 产生160个数据
for f=1:9
short=[short,short_cp];
end
short_str = short;
% 长训练序列产生
% !!!通过IFFT函数将LTS频域的频点顺序调整为正频率(0~31)、负频率(-32~-1)
long_cp = ifft(fftshift(L));
% 后32个数据
long1 = long_cp(33:64);
long2 = long_cp(1:64);
long_str = [long1,long2,long2];
preamble = [short_str,long_str];
% 对第一个和最后一个加窗处理,硬件上表现右移一位
% 第161个数据加窗处理
preamble(:,161) = preamble(:,161)*0.5 + preamble(:,1)*0.5;
% 第一个数据加窗处理
preamble(:,1) = preamble(:,1)*0.5;
% 短+长
LeaderSequence = preamble;
五、结果验证
运行程序,即可生成训练符号。
5.1 短训练序列结果
短训练序列数值为:
>> short_cp.'
ans =
0.0460 + 0.0460i
-0.1324 + 0.0023i
-0.0135 - 0.0785i
0.1428 - 0.0127i
0.0920 + 0.0000i
0.1428 - 0.0127i
-0.0135 - 0.0785i
-0.1324 + 0.0023i
0.0460 + 0.0460i
0.0023 - 0.1324i
-0.0785 - 0.0135i
-0.0127 + 0.1428i
0.0000 + 0.0920i
-0.0127 + 0.1428i
-0.0785 - 0.0135i
0.0023 - 0.1324i
将短训练序列变换为8位的二进制数:
>> struct.mode = 'fixed'; struct.roundmode = 'ceil'; struct.overflowmode = 'saturate'; struct.format = [8 8]; q = quantizer(struct); num2bin(q,short_cp)
ans =
00001100 + 00001100i
11011111 + 00000001i
11111101 + 11101100i
00100101 + 11111101i
00011000 + 00000000i
00100101 + 11111101i
11111101 + 11101100i
11011111 + 00000001i
00001100 + 00001100i
00000001 + 11011111i
11101100 + 11111101i
11111101 + 00100101i
00000000 + 00011000i
11111101 + 00100101i
11101100 + 11111101i
00000001 + 11011111i
5.2 长训练序列结果
长训练序列数值为:
>> long_cp.'
ans =
0.1563 + 0.0000i
-0.0051 - 0.1203i
0.0397 - 0.1112i
0.0968 + 0.0828i
0.0211 + 0.0279i
0.0598 - 0.0877i
-0.1151 - 0.0552i
-0.0383 - 0.1062i
0.0975 - 0.0259i
0.0533 + 0.0041i
0.0010 - 0.1150i
-0.1368 - 0.0474i
0.0245 - 0.0585i
0.0587 - 0.0149i
-0.0225 + 0.1607i
0.1192 - 0.0041i
0.0625 - 0.0625i
0.0369 + 0.0983i
-0.0572 + 0.0393i
-0.1313 + 0.0652i
0.0822 + 0.0924i
0.0696 + 0.0141i
-0.0603 + 0.0813i
-0.0565 - 0.0218i
-0.0350 - 0.1509i
-0.1219 - 0.0166i
-0.1273 - 0.0205i
0.0751 - 0.0740i
-0.0028 + 0.0538i
-0.0919 + 0.1151i
0.0917 + 0.1059i
0.0123 + 0.0976i
-0.1563 + 0.0000i
0.0123 - 0.0976i
0.0917 - 0.1059i
-0.0919 - 0.1151i
-0.0028 - 0.0538i
0.0751 + 0.0740i
-0.1273 + 0.0205i
-0.1219 + 0.0166i
-0.0350 + 0.1509i
-0.0565 + 0.0218i
-0.0603 - 0.0813i
0.0696 - 0.0141i
0.0822 - 0.0924i
-0.1313 - 0.0652i
-0.0572 - 0.0393i
0.0369 - 0.0983i
0.0625 + 0.0625i
0.1192 + 0.0041i
-0.0225 - 0.1607i
0.0587 + 0.0149i
0.0245 + 0.0585i
-0.1368 + 0.0474i
0.0010 + 0.1150i
0.0533 - 0.0041i
0.0975 + 0.0259i
-0.0383 + 0.1062i
-0.1151 + 0.0552i
0.0598 + 0.0877i
0.0211 - 0.0279i
0.0968 - 0.0828i
0.0397 + 0.1112i
-0.0051 + 0.1203i
将长训练序列变换为8位的二进制数:
>> struct.mode = 'fixed'; struct.roundmode = 'ceil'; struct.overflowmode = 'saturate'; struct.format = [8 8]; q = quantizer(struct); num2bin(q,long_cp)
ans =
00101000 + 00000000i
11111111 + 11100010i
00001011 + 11100100i
00011001 + 00010110i
00000110 + 00001000i
00010000 + 11101010i
11100011 + 11110010i
11110111 + 11100101i
00011001 + 11111010i
00001110 + 00000010i
00000001 + 11100011i
11011101 + 11110100i
00000111 + 11110010i
00010000 + 11111101i
11111011 + 00101010i
00011111 + 11111111i
00010000 + 11110000i
00001010 + 00011010i
11110010 + 00001011i
11011111 + 00010001i
00010110 + 00011000i
00010010 + 00000100i
11110001 + 00010101i
11110010 + 11111011i
11111000 + 11011010i
11100001 + 11111100i
11100000 + 11111011i
00010100 + 11101110i
00000000 + 00001110i
11101001 + 00011110i
00011000 + 00011100i
00000100 + 00011001i
11011000 + 00000000i
00000100 + 11101000i
00011000 + 11100101i
11101001 + 11100011i
00000000 + 11110011i
00010100 + 00010011i
11100000 + 00000110i
11100001 + 00000101i
11111000 + 00100111i
11110010 + 00000110i
11110001 + 11101100i
00010010 + 11111101i
00010110 + 11101001i
11011111 + 11110000i
11110010 + 11110110i
00001010 + 11100111i
00010000 + 00010000i
00011111 + 00000010i
11111011 + 11010111i
00010000 + 00000100i
00000111 + 00001111i
11011101 + 00001101i
00000001 + 00011110i
00001110 + 11111111i
00011001 + 00000111i
11110111 + 00011100i
11100011 + 00001111i
00010000 + 00010111i
00000110 + 11111001i
00011001 + 11101011i
00001011 + 00011101i
11111111 + 00011111i
六、总结
基于matlab程序,解决了OFMD发射机中,解决了训练序列生成计算问题。
参考文献:
1、《基于xilinx fpga 的ofdm的通信系统基带设计》
2、https://blog.csdn.net/weixin_40640020/article/details/83344801