logo资料库

OFDM的完整源程序.doc

第1页 / 共26页
第2页 / 共26页
第3页 / 共26页
第4页 / 共26页
第5页 / 共26页
第6页 / 共26页
第7页 / 共26页
第8页 / 共26页
资料共26页,剩余部分请下载后查看
%main_OFDM.m %一个相对完整的 OFDM 通信系统的仿真设计,包括编码,调制,IFFT, %上下变频,高斯信道建模,FFT,PAPR 抑制,各种同步,解调和解码等模 %块,并统括系统性能的仿真验证了系统设计的可靠性。 clear all close all clc 表示当前帧是第几帧 定时同步的定位 %++++++++++++++++++++++++++全局变量++++++++++++++++++++++++++++++ % seq_num % count_dds_up 上变频处的控制字的累加 % count_dds_down 下变频处的控制字的累加(整整) % count_dds_down_tmp 下变频处的控制字的累加(小数) % dingshi % m_syn global seq_num global count_dds_up global count_dds_down global count_dds_down_tmp global dingshi global m_syn %+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 记录定时同步中的自相关平台 % SNR_Pre % interval_SNR % frame_num % err_int_final % fwc_down % fre_offset % k0 % G SNR_Pre=-5; interval_SNR=1; 设定用于仿真的信噪比的初值 设定用于仿真的信噪比间隔 每一个信噪比下仿真的数据帧数 用于计算每帧出现的误比特数 设定的接收机初始载波频率控制字 设定接收机初始载波频率偏移调整量(单位为 Hz) 每次进入卷积编码器的信息比特数 卷积编码的生成矩阵 for SNR_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=[1 0 1 1 0 1 1;1 1 1 1 0 0 1 ];
disp('--------------start-------------------'); for seq_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); %+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ %+++++++++++++++++++++++++++生成训练序列+++++++++++++++++++++++++ if seq_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),PILO T,m_QPSKdata(25:32),PILOT,m_QPSKdata(33:40),PILOT,m_QPSKdata(41:48),m_QPSKdata(4 9:56),PILOT,m_QPSKdata(57:64),PILOT,m_QPSKdata(65:72),PILOT,m_QPSKdata(73:80),PIL OT,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 运算+++++++++++++++++++++++++++ if seq_num==1 ifftin=trainsp; elseif seq_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.0017216 0.010162 0.025512 0.028801 -0.0059219 0.091431 0.29636 0.3956 0.028801 0.025512 0.010162 0.0017216 ]; 0.29636 0.091431 -0.0496 -0.060115 -0.060115 -0.0496 -0.0059219 %抽样截止频率为 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.03934 0.049055 -0.018102 0.049055 -0.03934 0.019527]; -0.1003 0.5944 -0.018102 0.5944 -0.1003 %抽样截止频率为 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); %+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ %++++++++++++++++++++++++++++定时同步检测++++++++++++++++++++++++ if seq_num<3 time_syn(q_rxFIRdatai,q_rxFIRdataq); end %+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ %+++++++++++++++++++++++++++++频率同步+++++++++++++++++++++++++++ fre_offset=fre_syn(rxFIRdatai,rxFIRdataq); %+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ %+++++++++++++++++++++++++++++fft 运算+++++++++++++++++++++++++++ if seq_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); for m=1:192 if datatemp4(m)==-1 datatemp4(m)=1; elseif datatemp4(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]) grid on %+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ %************************beginning of file***************************** %cnv_encd.m %卷积码编码程序 function output=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 % input % output %++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 决定输入序列的生成矩阵 每一时钟周期输入编码器的 bit 数 输入数据 输入数据 if rem(length(input),k0)>0 input=[input,zeros(size(1:k0-rem(length(input),k0)))]; end n=length(input)/k0; % 检查生成矩阵 G 的维数是否和 k0 一致
if rem(size(G,2),k0)>0 error('Error,G is not of the right size.') 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 为第二组,。。。。, %并将分组按倒序排列。 for i=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)); % ************************end of file*********************************** %************************beginning of file***************************** %interlacecode.m function dout=interlacecode(din,m,n) %实现信道的交织编码 %din 为输入交织编码器的数据,m,n 分别为交织器的行列值 输入数据 %+++++++++++++++++++++++variables++++++++++++++++++++++++++++ % din % m % n % dout %++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 交织器的行值 交织器的列值 输出数据 for j=1:m temp(j,:)=din(j*n-(n-1):j*n); end dout_temp=reshape(temp,1,length(din)); dout=dout_temp(1:end); %************************end of file**********************************
%************************beginning of file***************************** %qpsk.m %QPSK 调制映射 function dout=qpsk(din) %+++++++++++++++++++++++variables++++++++++++++++++++++++++++ % din % dout %++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 输入数据 输出数据 din2=1-2*din; din_temp=reshape(din2,2,length(din)/2); for i=1:length(din)/2, dout(i)=din_temp(1,i)+j*din_temp(2,i); end % ************************end of file*********************************** %************************beginning of file***************************** %seq_train.m %生成用于同步的训练符号 function dout=seq_train() %第一帧产生短训练序列,第二帧产生长训练序列 %每个短训练符号由 16 个子载波组成,短训练序列 %是由伪随机序列经过数字调制后插 0 后,再经过 %IFFT 之后得到的。具体过程如下:首先采用抽头 %系数为[1 0 0 1 ]的 4 级移位寄存器产生长度为 %15 的伪随机序列之后末尾补 0,经过 QPSK 调制之 %后的伪随机序列只在 16 的整数倍位置上出现,其 %余的位置补 0,产生长度为 128 的序列,此序列再 %补 128 个 0 经过数据搬移后做 256 点的 IFFT 变换就 %得到 16 个以 16 为循环的训练序列,经过加循环前 %后缀就会产生 20 个相同的短训练序列。长训练序 %列的产生同短训练序列。 global seq_num if seq_num==1 fbconnection=[1 0 0 1]; QPSKdata_pn=[m_sequence(fbconnection),0]; QPSKdata_pn=qpsk(QPSKdata_pn); elseif seq_num==2 fbconnection=[1 0 0 0 0 0 1];
分享到:
收藏