OFDM matlab源程序.docx
《OFDM matlab源程序.docx》由会员分享,可在线阅读,更多相关《OFDM matlab源程序.docx(41页珍藏版)》请在冰豆网上搜索。
OFDMmatlab源程序
%main_OFDM.m
%一个相对完整的OFDM通信系统的仿真设计,包括编码,调制,IFFT,
%上下变频,高斯信道建模,FFT,PAPR抑制,各种同步,解调和解码等模
%块,并统括系统性能的仿真验证了系统设计的可靠性。
clearall
closeall
clc
%++++++++++++++++++++++++++全局变量++++++++++++++++++++++++++++++
%seq_num表示当前帧是第几帧
%count_dds_up上变频处的控制字的累加
%count_dds_down下变频处的控制字的累加(整整)
%count_dds_down_tmp下变频处的控制字的累加(小数)
%dingshi定时同步的定位
%m_syn记录定时同步中的自相关平台
globalseq_num
globalcount_dds_up
globalcount_dds_down
globalcount_dds_down_tmp
globaldingshi
globalm_syn
%+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
%SNR_Pre设定用于仿真的信噪比的初值
%interval_SNR设定用于仿真的信噪比间隔
%frame_num每一个信噪比下仿真的数据帧数
%err_int_final用于计算每帧出现的误比特数
%fwc_down设定的接收机初始载波频率控制字
%fre_offset设定接收机初始载波频率偏移调整量(单位为Hz)
%k0每次进入卷积编码器的信息比特数
%G卷积编码的生成矩阵
SNR_Pre=-5;
interval_SNR=1;
forSNR_System=SNR_Pre:
interval_SNR:
5
frame_num=152;
dingshi=250;
err_int_final=0;
fwc_down=16.050;
fre_offset=0;
k0=1;
G=[1011011;1111001];
disp('--------------start-------------------');
forseq_num=1:
frame_num,%frame_num帧数
%+++++++++++++++++++++++以下为输入数据部分+++++++++++++++++++++++
datain=randint(1,90);
%+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
%++++++++++++++++++++++以下为信道卷积编码部分+++++++++++++++++++++
encodeDATA=cnv_encd(G,k0,datain);
%+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
%+++++++++++++++++++++++++++信道交织编码+++++++++++++++++++++++++
interlacedata=interlacecode(encodeDATA,8,24);
%+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
%+++++++++++++++++++++++++以下为QPSK调制部分+++++++++++++++++++++
QPSKdata=qpsk(interlacedata);
%+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
%+++++++++++++++++++++++++++生成训练序列+++++++++++++++++++++++++
ifseq_num<3
trainsp_temp=seq_train();
end
%+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
%++++++++++++++++++++++++++++插入导频++++++++++++++++++++++++++++
PILOT=(1+j);
m_QPSKdata=QPSKdata;
data2fft_temp=[m_QPSKdata(1:
8),PILOT,m_QPSKdata(9:
16),PILOT,m_QPSKdata(17:
24),PILOT,m_QPSKdata(25:
32),PILOT,m_QPSKdata(33:
40),PILOT,m_QPSKdata(41:
48),m_QPSKdata(49:
56),PILOT,m_QPSKdata(57:
64),PILOT,m_QPSKdata(65:
72),PILOT,m_QPSKdata(73:
80),PILOT,m_QPSKdata(81:
88),PILOT,m_QPSKdata(89:
end)];
%+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
trainsp_temp2=[trainsp_temp,zeros(1,128)];
trainsp=[trainsp_temp2(65:
256),trainsp_temp2(1:
64)];
%++++++++++++++++++++++++++降PAPR矩阵变换++++++++++++++++++++++++
matix_data=nyquistimp_PS();
matrix_mult=data2fft_temp*matix_data;
%+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
data2fft2=[matrix_mult(65:
128),zeros(1,128),matrix_mult(1:
64)];
%++++++++++++++++++++++++++++ifft运算+++++++++++++++++++++++++++
ifseq_num==1
ifftin=trainsp;
elseifseq_num==2
ifftin=trainsp;
else
ifftin=data2fft2;
end
IFFTdata=fft_my(conj(ifftin)/256);
IFFTdata=conj(IFFTdata);
%figure
%plot(real(IFFTdata))
%xlabel('realIFFTdata')
%figure
%plot(imag(IFFTdata))
%xlabel('imagIFFTdata')
%+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
%+++++++++++++++++++以下为插入循环前后缀,2倍升采样+++++++++++++++
data2fir=add_CYC_upsample(IFFTdata,2);
%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
%+++++++++++++++++++++++++fir低通滤波++++++++++++++++++++++++++
guiyi_a=[0.00172160.0101620.0255120.028801-0.0059219-0.060115-0.04960.0914310.296360.39560.296360.091431-0.0496-0.060115-0.00592190.0288010.0255120.0101620.0017216];
%抽样截止频率为128kHZ,通带截止频率为20kHZ,阻带截止频率为40kHZ,带内纹波动小于1dB,带外衰减100dB
txFIRdatai=filter(guiyi_a,1,real(data2fir));
txFIRdataq=filter(guiyi_a,1,imag(data2fir));
%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
%+++++++++++++++++++++++++发射机cic滤波++++++++++++++++++++++++++
CICidatai=cic_inter(txFIRdatai,20);
CICidataq=cic_inter(txFIRdataq,20);
%+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
%+++++++++++++++++++++++++++++上变频++++++++++++++++++++++++++++
fwc_up=16;%控制字可以选择
DUCdata=up_convert_ofdm(fwc_up,CICidatai,CICidataq);
%+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
%++++++++++++++++++++++++++高斯白噪声信道++++++++++++++++++++++++
[DUCdata,datamax]=guiyi_DUCdata(DUCdata);
awgn_data=awgn(DUCdata,SNR_System);
%+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
%*****************************接受机*****************************
%+++++++++++++++++++++++++++++下变频+++++++++++++++++++++++++++++
DUCdata_tmp=awgn_data;
fwc_down=fwc_down+(fre_offset*128/2560000);
r_fre_offset=2560000*((fwc_down-fwc_up)/128);
[DDCdatai,DDCdataq]=down_convert_ofdm(fwc_down,DUCdata_tmp);
%+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
%++++++++++++++++++++++++++接收机cic滤波+++++++++++++++++++++++++
CICddatai=cic_deci(DDCdatai,40,40);
CICddataq=cic_deci(DDCdataq,40,40);
%+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
%++++++++++++++++++++++++++++fir低通滤波++++++++++++++++++++++++
guiyi_b=[0.019527-0.039340.049055-0.018102-0.10030.59440.5944-0.1003-0.0181020.049055-0.039340.019527];
%抽样截止频率为64kHZ,通带截止频率为20kHZ,阻带截止频率为30kHZ,带内纹波动小于1dB,带外衰减60dB
rxFIRdatai=filter(guiyi_b,1,CICddatai);
rxFIRdataq=filter(guiyi_b,1,CICddataq);
%+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
%+++++++++++++++++++++++++++++++量化++++++++++++++++++++++++++++
q_rxFIRdatai=sign(rxFIRdatai);
q_rxFIRdataq=sign(rxFIRdataq);
%+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
%++++++++++++++++++++++++++++定时同步检测++++++++++++++++++++++++
ifseq_num<3
time_syn(q_rxFIRdatai,q_rxFIRdataq);
end
%+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
%+++++++++++++++++++++++++++++频率同步+++++++++++++++++++++++++++
fre_offset=fre_syn(rxFIRdatai,rxFIRdataq);
%+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
%+++++++++++++++++++++++++++++fft运算+++++++++++++++++++++++++++
ifseq_num>2
seq_num-2
fftw=32+dingshi;
rxFIRdata_syn=rxFIRdatai(fftw:
fftw+255)+j*rxFIRdataq(fftw:
fftw+255);
FFTdata=fft_my(rxFIRdata_syn);
%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
%++++++++++++++++++++++++++降PAPR逆矩阵变换++++++++++++++++++++++
fftdata_reg=[FFTdata(193:
256),FFTdata(1:
64)];
dematrix_data=fftdata_reg*pinv(matix_data);
%+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
%++++++++++++++++++++++++++++相位补偿+++++++++++++++++++++++++++
rx_qpsk_din_th=phase_comp(dematrix_data);
%+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
%+++++++++++++++++++++++++++QPSK解调部分++++++++++++++++++++++++
%figure
%plot(rx_qpsk_din_th,'.')
%xlabel('星座图')
datatemp4=deqpsk(rx_qpsk_din_th);
datatemp4=sign(datatemp4);
form=1:
192
ifdatatemp4(m)==-1
datatemp4(m)=1;
elseifdatatemp4(m)==1
datatemp4(m)=0;
end
end
%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
%+++++++++++++++++++++++++信道解交织++++++++++++++++++++++++++++
interdout=interlacedecode(datatemp4,8,24);
%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
%++++++++++++++++++++以下为viterbi译码部分++++++++++++++++++++++
decodeDATA=viterbi(G,k0,interdout);
%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
%+++++++++++++++++++++++++误比特统计++++++++++++++++++++++++++++
err_final=sum(abs(decodeDATA-datain))
err_int_final=err_int_final+err_final
end
end
disp('------------------------------------------------------');
SNR_System
err_rate_final((SNR_System-SNR_Pre)./interval_SNR+1)=err_int_final/(90*(frame_num-2))
disp('------------------------------------------------------');
end
disp('--------------end-------------------');
SNR_System=SNR_Pre:
interval_SNR:
5;
figure
semilogy(SNR_System,err_rate_final,'b-*');
xlabel('信噪比/dB')
ylabel('误码率')
axis([-5,5,0,1])
gridon
%+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
%************************beginningoffile*****************************
%cnv_encd.m
%卷积码编码程序
functionoutput=cnv_encd(G,k0,input)
%cnv_encd(G,k0,input),k0是每一时钟周期输入编码器的bit数,
%G是决定输入序列的生成矩阵,它有n0行L*k0列n0是输出bit数,
%参数n0和L由生成矩阵G导出,L是约束长度。
L之所以叫约束长度
%是因为编码器在每一时刻里输出序列不但与当前输入序列有关,
%而且还与编码器的状态有关,这个状态是由编码器的前(L-1)k0。
%个输入决定的,通常卷积码表示为(n0,k0,m),m=(L-1)*k0是编码
%器中的编码存贮个数,也就是分为L-1段,每段k0个
%有些人将m=L*k0定义为约束长度,有的人定义为m=(L-1)*k0
%查看是否需要补0,输入input必须是k0的整数部
%+++++++++++++++++++++++variables++++++++++++++++++++++++++++
%G决定输入序列的生成矩阵
%k0每一时钟周期输入编码器的bit数
%input输入数据
%output输入数据
%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ifrem(length(input),k0)>0
input=[input,zeros(size(1:
k0-rem(length(input),k0)))];
end
n=length(input)/k0;
%检查生成矩阵G的维数是否和k0一致
ifrem(size(G,2),k0)>0
error('Error,Gisnotoftherightsize.')
end
%得到约束长度L和输出比特数n0
L=size(G,2)/k0;
n0=size(G,1);
%在信息前后加0,使存贮器归0,加0个数为(L-1)*k0个
u=[zeros(size(1:
(L-1)*k0)),input,zeros(size(1:
(L-1)*k0))];
%得到uu矩阵,它的各列是编码器各个存贮器在各时钟周期的内容
u1=u(L*k0:
-1:
1);
%将加0后的输入序列按每组L*k0个分组,分组是按k0比特增加
%从1到L*k0比特为第一组,从1+k0到L*k0+k0为第二组,。
。
。
。
,
%并将分组按倒序排列。
fori=1:
n+L-2
u1=[u1,u((i+L)*k0:
-1:
i*k0+1)];
end
uu=reshape(u1,L*k0,n+L-1);
%得到输出,输出由生成矩阵G*uu得到
output=reshape(rem(G*uu,2),1,n0*(L+n-1));
%************************endoffile***********************************
%************************beginningoffile*****************************
%interlacecode.m
functiondout=interlacecode(din,m,n)
%实现信道的交织编码
%din为输入交织编码器的数据,m,n分别为交织器的行列值
%+++++++++++++++++++++++variables++++++++++++++++++++++++++++
%din输入数据
%m交织器的行值
%n交织器的列值
%dout输出数据
%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
forj=1:
m
temp(j,:
)=din(j*n-(n-1):
j*n);
end
dout_temp=reshape(temp,1,length(din));
dout=dout_temp(1:
end);
%************************endoffile**********************************
%************************beginningoffile*****************************
%qpsk.m
%QPSK调制映射
functiondout=qpsk(din)
%+++++++++++++++++++++++variables++++++++++++++++++++++++++++