openofdm的原作者从用usrp n210接在路由器上,生产了很多测试向量用于进行openofdm的仿真,我们当然可以用来进行仿真,并且肯定可以得到正确的结果。这里我在想的,将这些测试向量发射出去,之后用咱们fpga+ad9361平台接收回来,之后用openofdm在fpga里解析。
这个是个稍微复杂的实验,我这些文字主要是做一个将作者提供的测试向量转换成usrp可以识别的发射数据格式。
首先看看作者提供的bin_to_mem.y文件,这文件是将二进值的原始采样处理成verilog仿真软件的是readmemh函数所支持的文本文件。
#!/usr/bin/env python
"""
Convert a binary data file (generated by rx_samples_to_file) to a memroy text
file that can be read by Verilog's $readmemh.
"""
import argparse
import os
import time
import sys
CHUNK_SIZE = 2**20
def le_bin_str_to_signed_short(b):
v = ord(b[1])*(1<<8) + ord(b[0])
if v > (1<<15):
v = v - (1<<16)
return v
def signed_short_to_hex_str(n):
return format(n%(1<<16), '04x')
def main():
parser = argparse.ArgumentParser()
parser.add_argument('file', help="Binary file.")
parser.add_argument('--out', help="Output file.")
parser.add_argument('--scale', type=int, default=1)
args = parser.parse_args()
if args.out is None:
args.out = '%s.txt' % (os.path.splitext(args.file)[0])
begin = time.clock()
byte_count = 0
total_bytes = os.path.getsize(args.file)
with open(args.file, 'rb') as input:
with open(args.out, 'wb', buffering=2**26) as output:
while True:
bytes = input.read(CHUNK_SIZE)
if len(bytes) == 0:
break
for i in range(0, len(bytes), 4):
I = le_bin_str_to_signed_short(bytes[i:i+2])/args.scale
Q = le_bin_str_to_signed_short(bytes[i+2:i+4])/args.scale
output.write('%s%s\n' % (signed_short_to_hex_str(I),
signed_short_to_hex_str(Q)))
byte_count += len(bytes)
elapsed = time.clock() - begin
speed = byte_count / elapsed
eta = (total_bytes - byte_count)/speed
progress = '%d / %d B\tSpeed: %.1f B/s\t Elapsed: %d s\tETA: %d s' %\
(byte_count>>20, total_bytes, speed, int(elapsed), int(eta))
sys.stdout.write('\r%s' % (progress))
sys.stdout.flush()
sys.stdout.write('\n')
if __name__ == '__main__':
main()
从这些代码我们可以获得以下信息:
1,输入文件每四个字节为一个单位,前两个字节是I通道,后两个字节是Q通道。
2, I通道和Q通道数据,高字节表示高8位,低字节表示低八位。
3,I通道和Q通道是有符号的补码表示。
-==================以上是输入文件格式分析,接下来是实现分析==================-
输出文件我们根据usrp特性要做成float类型的。
每个单元占用八个字节前四个字节是i通道的float数据表示,后四个字节是q通道的float数据表示。
#include <stdio.h>
#include <string.h>
#define BUFF_SIZE 1024*1024*200
unsigned char buff[BUFF_SIZE] ;
int buff_size ;
float f_buff[BUFF_SIZE] ;
int file2buff (char * fn, unsigned char *buff ,int buff_len ){
int size ; FILE *fp;
fp = fopen( fn , "rb");
if (fp==NULL) { printf("can not read file \n");getchar();}
size = fread (buff,1, buff_len, fp);
fclose (fp);
buff_size =size ;
return size ;
}
int buff2file (char *fn ,unsigned char *buff,int size ){
FILE *fp ;
fp = fopen( fn , "wb");
if (fp==NULL) { printf("can not create file to write\n");getchar();}
size = fwrite (buff,1,size,fp);
return size ;
}
float fact = 2.0 * 4;
float u16_2_float ( short i ) {
float t;
t = i*1.0;
t = t/fact;
return t ;
}
int main (){
char fin[100] = "dot11a_6mbps_qos_data_e4_90_7e_15_2a_16_e8_de_27_90_6e_42.dat" ;
char fout[100] = "out.f" ;
int i,r,t;
short *p_i ;
short *p_q ;
float fi ,fq ;
printf("sizeof(short)=%d\n\r",sizeof(short)) ;
r = file2buff( fin ,buff,BUFF_SIZE ) ;
restart :
for (i=0;i< (r/4) ;i+=1) {
p_i = buff + 4*i ;
p_q = buff + 4*i + 2 ;
fi = u16_2_float(*p_i) ;
fq = u16_2_float(*p_q) ;
f_buff[i ] = fi ;
f_buff[i+1] = fq ;
if( (fi>1.0) || (fq>1.0 ) ) { fact *=2.0 ; printf("set fact as %f\n",fact ); goto restart ; }
if( (fi<-1.0) || (fq<-1.0 ) ) { fact *=2.0 ; printf("set fact as %f\n",fact ); goto restart ; }
}
buff2file(fout,f_buff,2*r);
printf("fact is %f\n",fact);
}
这个代码将short类型转换成了幅度数值在[-1,1]范围内的float类型。
我们用audacity查看生成的波形:
可以很明显看到有同步信息
放大再看:
具体使用的时候:
生成的文件在FILESINK里面指定
设置USRP 的输入类型选择complex_float32。
之后就可以将这些测试向量发送出去。