OFDM程序流程说明-完美
- 格式:doc
- 大小:47.00 KB
- 文档页数:2
OFDM 技术原理及关键技术介绍一、原理介绍1、OFDM 的基本原理介绍在数字通信系统中,我们通常采用的通信系统是单载波传输系统模型,如图1所示。
tjw 0t jw 0图1. 单载波传输示意图图中g(t)是匹配滤波器(对于给定的码元波形,使得输出信噪比最大的线性滤波器),这种系统在传输速率不是很高的情况下,因时延产生的码间干扰不是特别严重,可以通过均衡技术消除这种干扰。
所谓码间干扰(intersymbol interference ,ISI )就是当一个码元的时延信号产生的拖尾延伸到相邻码元时间中去的时候,会影响信号的正确接收,造成系统误码性能的降低,这类干扰就是码间干扰。
而当数据传输速率较高的时候,若想要消除ISI ,对均衡的要求更高,需要引入更复杂的均衡算法。
随着OFDM 技术的兴起与发展,考虑到可以使用OFDM 技术来进行高速数据传输,它可以很好地对抗信道的频率选择性衰落,减少甚至消除码间干扰的影响。
OFDM 的全称是正交频分复用,是一项多载波传输技术,可以被看作是调制技术,也可以当作是一种复用技术。
其基本原理是把传输的数据流串并变换后分解为若干个并行的子数据流(也可以看作将一个信道划分为若干个并行的相互正交的子信道),这样每个子数据流的速率比串行过来的数据流低得多(速率变为多少取决于变换为多少路并行数据流),这样的话每个子信道上的码元周期变长,每个子信道上便是平坦衰落,然后用每个子信道上的低速率数据去调制相应的子载波,从而构成多个低速率码元合成的数据发送的传输系统,其基本原理图如图2。
图2. OFDM 系统调制解调原理框图在单载波系统中,一次衰落或者干扰就可以导致整个链路性能恶化甚至失效,但是在多载波系统中,某一时刻只会有少部分子信道受到衰落的影响,而不会使整个通信链路性能失效。
在衰落信道中,根据多径信号最大时延m T 和码元时间s T 的关系,可以把性能降级分为两种类型:频率选择性衰落和平坦衰落。
1.OFDM调制/解调1.1. 概述1.1.1.OFDM调制基本原理如图OFDM调制的过程就是将待发送的多个数据分别与多路子载波相乘合成基带复信号s(t)的过程,而OFDM解调的过程就是由复信号s(t)求解傅立叶系数的过程。
复信号s(t)是时域信号,而傅立叶系数就是频域的数据。
需要明确的是:对于OFDM调制来讲,输入的数据是频域数据,而输出是S(t)就是时域数据;对于OFDM解调来讲,输入的s(t)是时域信号,而输出的数据就是频域数据。
当使用IDFT/DFT实现OFDM调制/解调的时候,IDFT的输入是频域数据,输出是时域数据;DFT的输入是时域数据,输出是频域数据。
基于快速离散傅里叶变换的产生和接收OFDM信号原理:在发射端,输入速率为Rb 的二进制数据序列先进行串并变换,将串行数据转化成N个并行的数据并分配给N个不同的子信道,此时子信道信号传输速率为Rb/N。
N路数据经过编码映射成N个复数子符号Xk。
(一个复数子符号对应速率为Rb的一路数据)随后编码映射输出信号被送入一个进行快速傅里叶逆变换IFFT的模块,此模块将频域内N个复数子符号Xk变换成时域中2N个实数样值Xk。
(两个实数样值对应1个复数子符号,即对应速率为Rb的一路数据)由此原始数据就被OFDM按照频域数据进行处理。
计算出的IFFT变换之样值,被一个循环前缀加到样值前,形成一个循环扩展的OFDM信息码字。
此码字在此通过并串变换,然后按照串行方式通过D/A和低通滤波器输出基带信号,最后经过上变频输出OFDM信号。
1.1.2.OFDM的优缺点1.1.2.1. OFDM优点1.1.2.1.1.频谱效率高由于FFT处理使各个子载波可以部分重叠,因为理论上可以接近乃奎斯特极限。
以OFDM为基础的多址技术OFDMA(正交频分多址)可以实现小区内各用户之间的正交性,从而避免用户间干扰。
这使OFDM系统可以实现很高的小区容量。
1.1.2.1.2.带宽扩展性强由于OFDM系统的信号带宽取决于使用的子载波数量,因此OFDM系统具有很好的带宽扩展性。
OFDM程序% OFDM_basic.m%MIMO-OFDM Wireless Communications with MATLAB㈢Yong Soo Cho, Jaekwon Kim, Won Young Yang and Chung G. Kang%2010 John Wiley & Sons (Asia) Pte Ltdclear allclcNgType=1; % NgType=1/2 for cyclic prefix/zero paddingif NgType==1, nt='CP'; elseif NgType==2, nt='ZP'; endCh=0; % Ch=0/1 for AWGN/multipath channelif Ch==0, chType='AWGN'; Target_neb=100; else chType='CH'; Target_neb=500; endfigure(Ch+1), clfPowerdB=[0 -8 -17 -21 -25]; % Channel tap power profile 'dB'Delay=[0 3 5 6 8]; % Channel delay 'sample'Power=10.^(PowerdB/10); % Channel tap power profile 'linear scale'Ntap=length(PowerdB); % Chanel tap numberLch=Delay(end)+1; %Channel lengthNbps=4; M=2^Nbps; % Modulation order=2/4/6 for QPSK/16QAM/64QAMNfft=64; % FFT sizeNg=16; %Nfft/4; % Ng=0: Guard interval lengthNg=Nfft/4;Nsym=Nfft+Ng; % Symbol durationNvc=Nfft/4; % Nvc=0: no virtual carrierNused=Nfft-Nvc;EbN0=0:5:30; % EbN0N_iter=1e3; % Number of iterations for each EbN0Nframe=3; % Number of symbols per framesigPow=0; % Signal power initializationfile_name=['OFDM_BER_' chType '_' nt '_' 'GL' num2str(Ng) '.dat'];fid=fopen(file_name, 'w+');norms=[1 sqrt(2) 0 sqrt(10) 0 sqrt(42)]; % BPSK 4-QAM 16-QAMi=0;while(i<=length(EbN0))%for i=0:length(EbN0)% randn('state',0); rand('state',0); Ber2=ber(); % BER initializationNeb=0; Ntb=0; % Initialize the number of error/total bitsfor m=1:N_iter% Tx______________________________________________________________% X= randint(1,Nused*Nframe,M); % bit: integer vectorX= randi(1,Nused*Nframe,M); % bit: integer vectorXmod= qammod(X,M,0,'gray')/norms(Nbps);if NgType~=2, x_GI=zeros(1,Nframe*Nsym);elseif NgType==2, x_GI= zeros(1,Nframe*Nsym+Ng);% Extend an OFDM symbol by Ng zerosendkk1=[1:Nused/2]; kk2=[Nused/2+1:Nused]; kk3=1:Nfft; kk4=1:Nsym;for k=1:Nframeif Nvc~=0, X_shift= [0 Xmod(kk2) zeros(1,Nvc-1) Xmod(kk1)];else X_shift= [Xmod(kk2) Xmod(kk1)];endx= ifft(X_shift);x_GI(kk4)= guard_interval(Ng,Nfft,NgType,x);kk1=kk1+Nused; kk2= kk2+Nused; kk3=kk3+Nfft; kk4=kk4+Nsym;endif Ch==0, y= x_GI; % No channelelse % Multipath fading channel%channel=(randn(1,Ntap)+j*randn(1,Ntap)).*sqrt(Power/2);channel=(randn(1,Ntap)+li*randn(1,Ntap)).*sqrt(Power/2);h=zeros(1,Lch); h(Delay+1)=channel; % cir: channel impulse responsey = conv(x_GI,h); %卷积和多项式乘法endif i==0 % Only to measure the signal power for adding AWGN noisey1=y(1:Nframe*Nsym); sigPow = sigPow + y1*y1';continue;end% Add AWGN noise________________________________________________snr = EbN0(i)+10*log10(Nbps*(Nused/Nfft)); % SNR vs. Eb/N0noise_mag = sqrt((10.^(-snr/10))*sigPow/2);%y_GI = y + noise_mag*(randn(size(y))+j*randn(size(y)));y_GI = y + noise_mag*(randn(size(y))+1i*randn(size(y)));% Rx_____________________________________________________________kk1=(NgType==2)*Ng+1:Nsym; kk2=1:Nfft;kk3=1:Nused; kk4=Nused/2+Nvc+1:Nfft; kk5=(Nvc~=0)+[1:Nused/2];if Ch==1H= fft([h zeros(1,Nfft-Lch)]); % Channel frequency responseH_shift(kk3)= [H(kk4) H(kk5)];endfor k=1:NframeY(kk2)= fft(remove_GI(Ng,Nsym,NgType,y_GI(kk1)));Y_shift=[Y(kk4) Y(kk5)];if Ch==0, Xmod_r(kk3) = Y_shift;else Xmod_r(kk3)= Y_shift./H_shift; % Equalizer - channel compensation endkk1=kk1+Nsym; kk2=kk2+Nfft; kk3=kk3+Nused; kk4=kk4+Nfft; kk5=kk5+Nfft; endX_r=qamdemod(Xmod_r*norms(Nbps),M,0,'gray');size(Neb);size(de2bi(X_r,Nbps));Neb=Neb+sum(sum(de2bi(X_r,Nbps))); %~=de2bi(X,Nbps))); %Matrix dimensions must agree.Ntb=Ntb+Nused*Nframe*Nbps; %[Ber,Neb,Ntb]=ber(bit_Rx,bit,Nbps);if Neb>Target_neb, break; endendif i==0sigPow= sigPow/Nsym/Nframe/N_iter;fprintf('Signal power= %11.3e\n', sigPow);fprintf(fid,'%%Signal power= %11.3e\n%%EbN0[dB] BER\n', sigPow);elseBer = Neb/Ntb;%EbN0显示部分% [EbN0(i),Neb,Ntb,Ber]%fprintf('EbN0=%3d[dB], BER= %4d / %8d =%11.3e \n', EbN0(i), Neb,Ntb,Ber)fprintf('EbN0=%3d[dB], %4d %8d %11.3e \n', EbN0(i), Neb,Ntb,Ber)fprintf(fid, '%d\t%11.3e\n', EbN0(i), Ber);if Ber<1e-6, break; endendi=i+1;endif (fid~=0), fclose(fid); enddisp('Simulation is finished');plot_ber(file_name,Nbps);function plot_ber(file_name,Nbps)%MIMO-OFDM Wireless Communications with MATLAB㈢Yong Soo Cho, Jaekwon Kim, Won Young Yang and Chung G. Kang%2010 John Wiley & Sons (Asia) Pte LtdEbN0dB=[0:1:30]; M=2^Nbps;ber_AWGN = ber_QAM(EbN0dB,M,'AWGN');ber_Rayleigh = ber_QAM(EbN0dB,M,'Rayleigh');semilogy(EbN0dB,ber_AWGN,'r:'), hold on, semilogy(EbN0dB,ber_Rayleigh,'r-')a= load(file_name); semilogy(a(:,1),a(:,2),'b--s'); grid onlegend('AWGN analytic','Rayleigh fading analytic', 'Simulation');xlabel('EbN0[dB]'), ylabel('BER'); axis([a(1,1) a(end,1) 1e-5 1])function y=Q(x)% co-error function: 1/sqrt(2*pi) * int_x^inf exp(-t^2/2) dt.y=erfc(x/sqrt(2))/2;function y=remove_GI(Ng,Lsym,NgType,ofdmSym)%MIMO-OFDM Wireless Communications with MATLAB㈢Yong Soo Cho, Jaekwon Kim, Won Young Yang and Chung G. Kang%2010 John Wiley & Sons (Asia) Pte Ltdif Ng~=0if NgType==1 % cyclic prefixy=ofdmSym(Ng+1:Lsym);elseif NgType==2 % cyclic suffixy=ofdmSym(1:Lsym-Ng)+[ofdmSym(Lsym-Ng+1:Lsym) zeros(1,Lsym-2*Ng)];endelsey=ofdmSym;endfunction ber=ber_QAM(EbN0dB,M,AWGN_or_Rayleigh)% Find ananlytical BER of Mary QAM in AWGN or Rayleigh channel% EbN0dB=EbN0dB: Energy per bit-to-noise power[dB] for AWGN channel% =rdB: Average SNR(2*sigma Eb/N0)[dB] for Rayleigh channel% M = Modulation order (Constellation size)%MIMO-OFDM Wireless Communications with MATLAB㈢Yong Soo Cho, Jaekwon Kim, Won Young Yang and Chung G. Kang%2010 John Wiley & Sons (Asia) Pte LtdN= length(EbN0dB); sqM= sqrt(M);a= 2*(1-power(sqM,-1))/log2(sqM); b= 6*log2(sqM)/(M-1);if nargin<3, AWGN_or_Rayleigh='AWGN'; endif lower(AWGN_or_Rayleigh(1))=='a', ber = a*Q(sqrt(b*10.^(EbN0dB/10)));else rn= b*10.^(EbN0dB/10)/2; ber = 0.5*a*(1-sqrt(rn./(rn+1)));Endfunction y = guard_interval(Ng,Nfft,NgType,ofdmSym)%MIMO-OFDM Wireless Communications with MATLAB㈢Yong Soo Cho, Jaekwon Kim, Won Young Yang and Chung G. Kang%2010 John Wiley & Sons (Asia) Pte Ltdif NgType==1y=[ofdmSym(Nfft-Ng+1:Nfft) ofdmSym(1:Nfft)];elseif NgType==2y=[zeros(1,Ng) ofdmSym(1:Nfft)];end。
OFDM通信系统的实现OFDM(Orthogonal Frequency Division Multiplexing)是一种多载波调制技术,广泛应用于现代通信系统中,包括无线通信、数字电视和数字音频等领域。
1.基带信号处理:OFDM系统使用多个互相正交的子载波来传输数据,因此需要对待传输的数据进行分组和频率域调制。
首先,将待传输的数据分为若干个块,每个块的长度为子载波的数量。
然后,对每个块进行快速傅里叶变换(FFT),将时域信号转换为频域信号。
最后,将频域信号映射到对应的子载波上,形成OFDM符号。
2.调制与解调:OFDM系统常用的调制方式包括相位移键控(PSK)、正交振幅调制(QAM)和幅度相位键控(APSK)等。
调制时,将数据经过映射表对应的调制符号,然后分配到各个子载波上。
解调时,将接收到的信号进行串并转换,然后进行FFT变换,得到频域信号。
根据调制方式对频域信号进行解调,恢复原始数据。
3.前导导频和信道估计:OFDM系统中常使用前导序列和导频子载波来实现同步和估计信道。
前导序列是一段具有特定结构的已知数据,用于接收端进行同步。
导频子载波是知道频域信号,用于信道估计和均衡。
在发送端,将前导序列和导频子载波插入到OFDM符号中一起传输。
接收端根据接收到的数据,通过解调和FFT变换得到频域信号,从中提取出前导序列和导频子载波,并根据它们进行同步和信道估计。
4.多路径衰落信道的处理:OFDM系统在传输过程中会受到多径衰落效应的影响。
为了克服这一问题,通常采用等化技术。
接收端通过利用已知的导频子载波,估计信道的频率响应,然后对接收到的信号进行频域均衡来抵消信道的影响。
常用的均衡算法包括线性均衡、最小均方误差(MMSE)均衡和零引导均衡(ZFE)等。
5. 信号检测与解码:接收端通过解调和FFT变换得到频域信号,在进行均衡后,将频域信号映射回原始数据。
然后,将解调后的数据进行解码,恢复原始信息。
解码通常采用纠错编码技术,如卷积码、LDPC码或Turbo码等。
OFDM简单实现%a_run_design.m文件setup %系统设置OFDM %OFDM调制方式Analysis %OFDM的收发数据及误码1setup %初始化部分% setupdisp(' '), disp('------------------------------------------------------------')disp('Simulation Setup')% OFDM Setup -----------------------------------------------------------fft_size = 128 % should be a power of 2 for fast computation% more points = more time domain samples (smoother & more cycles) num_carriers = 32 % should be <= fft_size/4% number of carriers used for each data chunk% new var - denotes even spacing or variations of carriers among fft pointsinput_type = 2;% 1 = test inputtest_input_type = 1;% 1 = bit specified (binary)binary_data = [0 1 0 1 0 1 0 1];% 2 = random data stream (samples in the range of 0-255)num_symbols = 9;% 3 = sinusoidalfrequency = 2;num_samples = 50;% 2 = external file 'mywav.wav'; % Name of input filefile_input_type = 3;% 1 = binary (not implemented)% 2 = text % Demo file: 'text.txt'% 3 = sound % Demo files: 'mywav.wav'% 4 = image (not implemented)% Channel Simulation Parameters --------------------------------------------channel_on = 1; % 1=on, 0=offclip_level = 1.0; % 0.0 - 1.0 (0-100%)% Max magnitude of the signal is 'clip_level' times the full magnitude of the signal noise_level = 0.0; % 0.0 - 1.0 (0-100%)% Magnitude of noise is 'noise_level' times the magnitude of the signal% Multipath Channel Simulation% Good defaults when fft_size = 128 and num_carriers = 32:% d1=6; a1=0.30; d2=10; a2=0.25d1 = 6; % delay in unitsa1 = 0.30; % attenuation factor - multipath signal is x% of size or original signald2 = 10; % delay for second multipath signala2 = 0.25; % attenuation factor for second multipath signal% ****************** TEST INPUT SETUP - DO NOT MODIFY ************************** if input_type == 1if test_input_type == 1%specify BINARY input bit-by-bitdata_in = binary_data;endif test_input_type == 2%random input defined by parametersnum_levels = 255; %number of possible levels of a symbol%must be integer between 1-255data_samples = round(rand(1,num_symbols)*(num_levels-1));data_in = zeros(1,8*length(data_samples));for i = 1:length(data_samples)data_in(1 + (i-1)*8:(i-1)*8 + 8) = eight2bin(data_samples(i));endendif test_input_type == 3%data stream represents sine wave samplest = linspace(0,1,num_symbols); %evenly space number of samples%take 8-bit samples of sine wavedata_samples = round(127.5*sin(frequency*2*pi*t) +127.5);data_in = zeros(1,8*length(data_samples));for i = 1:length(data_samples)data_in(1 + (i-1)*8:(i-1)*8 + 8) = eight2bin(data_samples(i));endendendalready_made_noise = 0; % initialization (don't change)3 % Run OFDM simulationtic % Start stopwatch to calculate how long QFDMsimulation takesdisp(' '),disp('------------------------------------------------------------')disp('OFDM Simulation')txchrx% Stop stopwatch to calculate how long QFDM simulation takesOFDM_simulation_time = toc;if OFDM_simulation_time > 60disp(strcat('Time for OFDM simulation=', num2str(OFDM_simulation_time/60), ' minutes.'));elsedisp(strcat('Time for OFDM simulation=', num2str(OFDM_simulation_time), ' seconds.'));end3.1发送% txdisp('Transmitting')read %read original datadata_in_pol = bin2pol(data_in); % Converts binary data to polar datatx_chunk %convert polar data into chunks.% perform ifft to create time domain waveform representing datatd_sets = zeros(num_chunks,fft_size);for i = 1:num_chunkstd_sets(i,1:fft_size) = real(ifft(spaced_chunks(i,1:fft_size)));endtx_dechunk % Construct signal to transmit by placing time domain sets in series3.1.1 % tx_chunk %双极性数组转化成OFDM字符串,串并子程序data_length = length(data_in_pol) %number of symbols in original inputnum_chunks = ceil(data_length/(2*num_carriers)) %2 data on each carrier (real and imaginary)r = rem(data_length,2*num_carriers)if r ~= 0for i = 1:num_carriers*2-rdata_in_pol(data_length+i) = 0; %pad input with zeros to complete last data set end %speed improve possibleend% break data into chunkschunks = zeros(num_chunks,num_carriers); % for speedfor i = 1:num_chunks% *********************chunk donefor k = 1:num_carrierschunks(i,k) = data_in_pol(2*num_carriers*(i-1)+k) + data_in_pol(2*num_carriers*(i-1)+k+num_carriers)*j;endendchunks% Padding chunks with zeros so num_carriers and fft_size are compatible% Once compatible, further spacing is simplifiednum_desired_carriers = num_carriers;num_zeros = 0;thinking = 1;while thinking == 1 % Continue if num_carriers and fft_size are not compatible if rem(fft_size/2,num_desired_carriers) == 0thinking = 0;elsenum_desired_carriers = num_desired_carriers + 1;num_zeros = num_zeros + 1;endendpadded_chunks = zeros(num_chunks,num_carriers + num_zeros); % for speedpadded_chunks(1:num_chunks,num_zeros + 1:num_carriers + num_zeros) = chunks;%compute zeros_betweenzeros_between = ((fft_size/2) - (num_carriers + num_zeros))/(num_carriers + num_zeros);spaced_chunks = zeros(num_chunks,fft_size); % for speed - extra room for folding later %add zeros_betweeni = 1;for k = zeros_between +1:zeros_between +1:fft_size/2spaced_chunks(1:num_chunks,k) = padded_chunks(1:num_chunks,i);i = i+1;end% folding data to produce an odd function for ifft inputfor i = 1:num_chunks% Note: index = 1 is actually DC freq for ifft -> it does not get copied over y-axis spaced_chunks(i,fft_size:-1:fft_size/2+2) = conj(spaced_chunks(i,2:fft_size/2));end3.1.2 tx_dechunk并串子程序% tx_dechunk% Construct signal to transmit by placing time domain sets in seriesxmit = zeros(1,num_chunks*fft_size);for i = 1:num_chunksfor k = 1:fft_sizexmit(k + (i-1)*fft_size) = td_sets(i,k);endend3.2 %ch.m% chrecv = xmit; % channel is applied to recv, don't modify transmitted dataif channel_on == 1disp('Simulating Channel')norm_factor = max(abs(recv)); % Normalize all data before applyingrecv = (1/norm_factor) * recv; % channel for a fair comparisonch_clipping %clipp datach_multipath %ch_noise %recv = norm_factor * recv; % Restore data magnitude for proper decoding end3.2.1 %ch_clipping.m% ch_clippingfor i = 1:length(recv)if recv(i) > clip_levelrecv(i) = clip_level;endif recv(i) < -clip_levelrecv(i) = -clip_level;endend3.2.2 % ch_multipath % 产生多经的方法copy1=zeros(size(recv));for i=1+d1:length(recv)copy1(i)=a1*recv(i-d1);endcopy2=zeros(size(recv));for i=1+d2:length(recv)copy2(i)=a2*recv(i-d2);endrecv=recv+copy1+copy2;3.2.3、%ch_noise %施加信道噪声% ch_noise (operate on recv)% random noise defined by noise_level amplitudeif already_made_noise == 0 % only generate once and use for OFDM noise = (rand(1,length(recv))-0.5)*2*noise_level;already_made_noise = 1;endrecv = recv + noise;3.3 %rx.m %接收程序% rxdisp('Receiving')rx_chunk% perform fft to recover original data from time domain setsrecv_spaced_chunks = zeros(num_chunks,fft_size);for i = 1:num_chunksrecv_spaced_chunks(i,1:fft_size) = fft(recv_td_sets(i,1:fft_size));% Note: 'round()' gets rid of small numerical error in Matlab but a threshold will be needed for a practical system% Got rid of 'round()' to do decoding more intelligentlyendrx_dechunkoutput = pol2bin(output); % Converts polar to binarywrite3.3.1 %rx_chunk.m% rx_chunk% break received signal into parellel sets for demodulationrecv_td_sets = zeros(num_chunks,fft_size);for i = 1:num_chunksfor k = 1:fft_sizerecv_td_sets(i,k) = recv(k + (i-1)*fft_size);endend3.3.2 % rx_dechunk %并串转换% rx_dechunk% take out zeros_between from recv_spaced_chunks --> recv_padded_chunksrecv_padded_chunks = zeros(num_chunks, num_carriers+num_zeros);i = 1;for k = zeros_between +1:zeros_between +1:fft_size/2recv_padded_chunks(1:num_chunks,i) = recv_spaced_chunks(1:num_chunks,k);i = i+1;end% take out num_zeros from padded chunks --> recv_chunksrecv_chunks = zeros(num_chunks, num_carriers);recv_chunks = recv_padded_chunks(1:num_chunks, num_zeros+1:num_carriers+num_zeros);% Recover bit stream by placing reconstructed frequency domain data in seriesrecv_dechunked = zeros(1, num_chunks*num_carriers);for i = 1:num_chunksfor k = 1:num_carriersrecv_dechunked(k + (i-1)*num_carriers*2) = real(recv_chunks(i,k));recv_dechunked(k + (i-1)*num_carriers*2 + num_carriers) = imag(recv_chunks(i,k));endend% take out trailing zeros from output --> outputoutput_analog = recv_dechunked(1:data_length);output = sign(output_analog);3.3.3 %write %save received data% write% ******************TEST OUTPUT*********************************if input_type == 1if test_input_type == 1%already binary - do nothingendif (test_input_type == 2) | (test_input_type == 3)%random input OR sine wave samplesoutput_samples = zeros(1,floor(length(output)/8)); %extra zeros are not original datafor i = 1:length(output_samples)output_samples(i) = bin2eight(output(1 + (i-1)*8:(i-1)*8 + 8));endendend% ******************FILE OUTPUT*********************************if input_type == 2if file_input_type == 1%binary file output - not implementedendif file_input_type == 2%text file outputoutput_samples = zeros(1,floor(length(output)/8)); %extra zeros are not original datafor i = 1:length(output_samples)output_samples(i) = bin2eight(output(1 + (i-1)*8:(i-1)*8 + 8));endfile = fopen('OFDM_text_out.txt','wt+');fwrite(file,output_samples,'char');fclose(file);endif file_input_type == 3output_samples_big = zeros(1,floor(length(output)/8)); %extra zeros are not original data for i = 1:length(output_samples_big)output_samples_big(i) = bin2eight(output(1 + (i-1)*8:(i-1)*8 + 8));end%convert dynamic range from 0:255 to -1:1output_samples = (output_samples_big-127)/128;%sound file outputwavwrite(output_samples, 11025, 8, 'OFDM_out.wav')endif file_input_type == 4%image file output - not implementedendend4、%Analysis.m% Analysisdisp(' '), disp('------------------------------------------------------------') disp('Preparing Analysis')figure(2), clfif (input_type == 1) & (test_input_type == 1)subplot(221), stem(data_in), title('OFDM 二进制输入数据');subplot(223), stem(output), title('OFDM 二进制恢复数据') elsesubplot(221), plot(data_samples), title('OFDM 输入信号');subplot(223), plot(output_samples), title('OFDM 恢复信号'); endsubplot(222), plot(xmit), title('OFDM发射');subplot(224), plot(recv), title('OFDM接收');dig_x_axis = (1:length(xmit))/length(xmit);figure(3), clfif channel_on ==1num = [1, zeros(1, d1-1), a1, zeros(1, d2-d1-1), a2];den = [1];[H, W] = freqz(num, den, 512);mag = 20*log10(abs(H));phase = angle(H) * 180/pi;subplot(313)freq_data = abs(fft(recv));L = length(freq_data)/2;plot(dig_x_axis(1:L), freq_data(1:L))xlabel('OFDM接收端FFT')axis_temp = axis;subplot(311),freq_data = abs(fft(xmit));plot(dig_x_axis(1:L), freq_data(1:L)), axis(axis_temp)title('OFDM发射端FFT')subplot(312)plot(W/(2*pi),mag),ylabel('信道幅度响应')elsesubplot(212)freq_data = abs(fft(recv));L = length(freq_data)/2;plot(dig_x_axis(1:L), freq_data(1:L))xlabel('OFDM接收端FFT')axis_temp = axis;subplot(211),freq_data = abs(fft(xmit));plot(dig_x_axis(1:L), freq_data(1:L)), axis(axis_temp)title('OFDM发射端FFT')end% if file_input_type == 4% figure(5)% subplot(211)% image(data_in);% colormap(map);% subplot(212)% image(output);% colormap(map);% endfigure(4), clfif channel_on == 1subplot(211), plot(W/(2*pi),mag),title('信幅度响应')xlabel('数字频率'),ylabel('幅度dB')subplot(212), plot(W/(2*pi),phase),title('信道相位响应')xlabel('数字频率'),ylabel('相位度数')elsetitle('Channel is turned off - No frequency response to plot') end% Compare output to input and count errorsbinary_err_bits_OFDM = 0;for i = 1:length(data_in)err = abs(data_in(i)-output(i));if err > 0binary_err_bits_OFDM = binary_err_bits_OFDM +1;endendBER_OFDM = 100 * binary_err_bits_OFDM/data_length;disp(strcat('OFDM: BER=', num2str(BER_OFDM,3), ' %'))disp(strcat(' Number of error bits=', num2str(binary_err_bits_OFDM)))。
python实现的ofdm通信算法的代码全文共四篇示例,供读者参考第一篇示例:OFDM(Orthogonal Frequency Division Multiplexing)是一种广泛应用于无线通信系统中的多载波调制技术。
它将数据流分成多个子载波进行传输,每个子载波频谱互相正交,能够提高信号传输效率和抵抗多径干扰。
在本文中,我们将介绍如何用Python实现一个简单的OFDM通信算法。
我们需要定义一些基本的参数,如子载波数量、信号采样率、符号周期等。
在一个OFDM系统中,通常会使用IFFT(Inverse Fast Fourier Transform)和FFT(Fast Fourier Transform)来进行频域和时域的转换。
我们可以通过以下代码来生成这些参数:```pythonimport numpy as np# 参数定义n_carriers = 64 # 子载波数量fft_size = 64 # FFT 大小symbol_period = 64 # 符号周期sampling_rate = 1e6 # 采样率# 生成载波频率fs = sampling_ratedelta_f = fs / fft_sizecarrier_freq = np.arange(-fs/2, fs/2, delta_f)```然后我们可以定义一个函数来生成一个随机的OFDM信号。
在这个函数中,我们可以利用NumPy库中的FFT和IFFT函数来进行频域和时域的转换。
下面是一个简单的示例代码:```pythondef generate_ofdm_signal(n_carriers, fft_size):# 生成随机数据data = np.random.randint(0, 2, n_carriers * fft_size)# 进行IFFT,得到时域信号ofdm_signal = np.fft.ifft(data)return ofdm_signal```我们可以利用以上定义的函数来模拟OFDM信号的发送和接收过程。
程序流程说明
1、基本流程描述
接收端采用的算法和程序流程与发送端发送的OFDM符号的帧结构有关系。
具体的帧结构,以及定时估计,频偏估计,剩余误差跟踪的算法可参考算法说明文档。
这里对程序的流程进行说明。
首先根据短训练字的特性进行相关运算,进行信号到达检测,当检测到相关值大于门限一定次数后,认为有信号到达。
然后根据长训练字的特性,进行相关运算,进行OFDM符号FFT窗口起始位置的估计。
估计出FFT窗口的位置后,先在时域进行小频偏的估计,将两个长训练字进行小频偏补偿后,进行FFT运算,根据FFT运算的结果进行整数倍频偏的估计。
这些参数估计完成后,就可以进行数据解调了。
先对数据部分进行完整的频偏补偿,然后根据估计的FFT窗口位置进行FFT运算得到频域的数据,进行解调。
然后在对应于导频的子载波位置上提取出导频信息,根据导频信息估计出剩余定时误差以及剩余的信道响应误差,将误差量送入环路进行跟踪。
当收到所有数据后,重新回到信号到达检测状态,进行下一次信号到达的检测和信号接收。
2、流程图
程序流程图如下:
Welcome To Download !!!
欢迎您的下载,资料仅供参考!。
OFDM系统设计与仿真共3篇OFDM系统设计与仿真1OFDM系统设计与仿真OFDM技术是一种多载波信号传输技术,将整个信道分割成数个互不干扰的子载波,每个子载波都可以进行调制传输数据,使得OFDM技术具有抗多径和高速传输的优点,因此在现代通信系统中得到广泛应用。
本文将介绍OFDM系统的设计和仿真过程。
一、OFDM系统的设计OFDM系统的设计首先需要确定系统的参数,包括子载波数量、调制方式、误码率等。
具体的设计流程如下:1. 确定子载波数量OFDM系统中子载波数量的选择与系统的带宽有关系,可以通过下式计算出子载波数量:N = B/Δf其中,N是子载波数量,B是系统的带宽,Δf是子载波的带宽。
2. 确定调制方式OFDM系统的调制方式有许多种,如BPSK、QPSK、16QAM、64QAM等。
不同的调制方式可以达到不同的传输速率和误码率,通常选用16QAM和64QAM,可以提高系统的信噪比和传输速率。
3. 确定误码率OFDM系统在传输数据时会受到各种干扰和噪声的影响,因此需要确定合适的误码率。
在一般情况下,当误码率为10^-5时,OFDM系统的性能最优。
二、OFDM系统的仿真OFDM系统的仿真可以通过软件或硬件实现。
其中,软件仿真可以通过Matlab软件实现,硬件实现需要使用FPGA等电路设计工具。
1. Matlab仿真Matlab软件提供了许多工具箱,可以方便地进行OFDM系统的仿真。
例如,可以使用Communications Toolbox进行信道估计、信号变换和误码率分析等,可以使用Simulink进行系统建模和仿真。
下面以Simulink仿真为例,介绍OFDM系统的仿真过程。
首先,将OFDM调制器、仿真信道和OFDM解调器添加到Simulink模型中。
然后,对OFDM信号进行比特随机分配、IFFT和加前缀(保障多径传播),并对信道进行加性白噪声、多径衰减和时间延迟的模拟,最后进行OFDM解调和误码率计算。
ofdm_mod.mfunction [qam_out] = Qam4_mod(qam_in)%% 4QAM 调制函数%% 输入:矩阵,列数必须是4的倍数,01序列%% 输出:矩阵,4qam调制后的矩阵global QamTableglobal bitPerSymbol;QamTable = [ -1-i, 1-i, -1+i, 1+i ];[ m, n ] = size(qam_in);qam_out = zeros(m,n/bitPerSymbol);for k = 1:mQamTmp = reshape(qam_in(k,:),bitPerSymbol,n/bitPerSymbol)';QamTmpTmp = bi2de( QamTmp, 'left-msb');qam_out(k, :) = QamTable( QamTmpTmp+1 );endofdm_demod.mfunction [qam_out] = Qam4_demod(qam_in)%% 4QAM 解调函数%% 输入:矩阵,列数必须是的的倍数%% 输出:矩阵,解调后的01序列矩阵%% 之前必须调用过global QamTable;global bitPerSymbol ;[m,n] = size(qam_in);qam_out = zeros(m,n*bitPerSymbol);% 判决for k = 1:mdelt = abs(reshape(qam_in(k,:), n, 1)*ones(1,4) - ones(n,1)*QamTable); %求最近的点[tmp, index] = min(delt,[],2); %得到索引值qam_outTmp = de2bi(index-1,bitPerSymbol,'left-msb');qam_out(k,:) = reshape(qam_outTmp',1,bitPerSymbol*n);endofdm_mod_neq.mfunction [s_out] = ofdm_mod_neq( s_in )%% ofdm 调制,无均衡%% 输入:二进制序列%% 输出:ofdm调制后符号%global CP_len;global nSubCglobal ifft_len;global symbolPerCarrier;global bitPerSymbol;global CP_len;global carriers;len = length(s_in);SQam = reshape(s_in, nSubC,len/nSubC); %串并转换PQam = Qam4_mod(SQam);carriers = (1: nSubC) + (floor( ifft_len/4) - floor(nSubC/2));conj_carriers = ifft_len - carriers + 2;P_IFFT = zeros(ifft_len, symbolPerCarrier ); % 一个符号块,含4列训练序列,1列0 P_IFFT(carriers,:) = PQam;P_IFFT(conj_carriers,:)=conj(PQam); % 构造共轭矩阵PCh = real(ifft( P_IFFT ));PCh2 = cat(1, PCh((ifft_len-CP_len+1):ifft_len,:), PCh); % 添加CPs_out = reshape(PCh2, 1, (ifft_len+CP_len)*(symbolPerCarrier)); %并串转换ofdm_mod_eq.mfunction [s_out] = ofdm_mod_eq( s_in )%% ofdm 调制,带均衡%% 输入:二进制序列%% 输出:ofdm调制后符号%global CP_len;global nSubCglobal ifft_len;global symbolPerCarrier;global bitPerSymbol;global trainingSymbols;global trainingSymbols_len;global CP_len;global carriers;len = length(s_in);SQam = reshape(s_in, nSubC,len/nSubC); %串并转换PQam = Qam4_mod(SQam);tmpTable = [-1,1,i,-i];trainingSymbols_len = 10;trainingSymbols = (tmpTable(floor( 4*rand(trainingSymbols_len,nSubC))+1 ))'; PQam = cat(2,zeros(nSubC,1),PQam);PQam = cat(2,trainingSymbols,PQam);carriers = (1: nSubC) + (floor( ifft_len/4) - floor(nSubC/2));conj_carriers = ifft_len - carriers + 2;P_IFFT = zeros(ifft_len,1 + symbolPerCarrier + trainingSymbols_len);P_IFFT(carriers,:) = PQam;P_IFFT(conj_carriers,:)=conj(PQam) ;PCh = (ifft( P_IFFT ,ifft_len,1));PCh2 = cat(1, PCh((ifft_len-CP_len+1):ifft_len,:), PCh); % 添加CPs_out = reshape(PCh2, 1, (ifft_len+CP_len)*(symbolPerCarrier +trainingSymbols_len + 1)); %并串转换channel.mfunction [s_out] = channel(s_in, SNR)%% 信道函数% 模拟多径信道global fade;Len = length(s_in);f_len = length(fade);sch = s_in;for m = 1:f_lensch(1+m:Len) = sch(1+m:Len) + fade(m)*(s_in(1:Len-m));end% 高斯信道Tx_signal_power = var(sch); % 方差linear_SNR = 10^( SNR /10) ;noise_sigma = Tx_signal_power / linear_SNR;noise_scale_factor = sqrt(noise_sigma) ;noise = randn(1, length(sch) )*noise_scale_factor; %模拟信道噪声,为随机数,即高斯白噪s_out = sch + noise;ofdm_demod_neq.mfunction [s_out] = ofdm_demod_neq(s_in)%% ofdm 解调%% 输入为二进制序列global ifft_len;global CP_len;global bitPerSymbol;global symbolPerCarrier;global carriers;global s_len;P_S = reshape(s_in, ifft_len+CP_len, symbolPerCarrier); % 接收,进行串并转换PDeCP = P_S(1+CP_len:ifft_len+CP_len,:); %去CPP_FFT = fft(PDeCP);P_FFT2 = P_FFT(carriers,:);SQam = Qam4_demod(P_FFT2);s_out = reshape(SQam,1,s_len); % 并串转换ofdm_demod_eq.mfunction [s_out] = ofdm_demod_eq(s_in)%% ofdm 解调%% 输入为二进制序列global trainingSymbols;global trainingSymbols_len;global ifft_len;global CP_len;global bitPerSymbol;global symbolPerCarrier;global carriers;global s_len% 接收,进行串并转换P_S = reshape(s_in, ifft_len+CP_len, symbolPerCarrier + trainingSymbols_len + 1); PDeCP = P_S(1+CP_len:ifft_len+CP_len,:); %去C PP_FFT = fft(PDeCP,ifft_len,1);P_FFT2 = P_FFT(carriers,:);RxTrainSymbols = P_FFT2(:, (1: trainingSymbols_len));%RxTrainSymbols =P_FFT2(:, (1: trainingSymbols_len,size(P_FFT2,2)-trainingSymbols_len+1:size(P_FFT2,2)); %信道均衡H = RxTrainSymbols./ trainingSymbols;H_2 = H.^2;H_2 = sum(H_2,2);H_C2 = sum(H,2);H_C2 = conj(H_C2);H = H_C2./H_2 ; % 1/H = conj(H)/H^2P_FFT3 = H*ones(1,size(P_FFT2,2)).*P_FFT2 ;P_FFT4 = P_FFT2(:,(trainingSymbols_len+2:size(P_FFT3,2)));SQam = Qam4_demod(P_FFT4);s_out = reshape(SQam,1,s_len); % 并串转换test1.m%% 本测试为不同信道环境下系统误码率曲线%%close all;clear all; clc; tic ; %计时开始global CP_len;global nSubC;global ifft_len;global bitPerSymbol;global symbolPerCarrier;global s_len;global fade; %信道衰弱%% 测试参数%SNR = 40; % dBCP_len = 0;nSubC = 48;ifft_len = 256;bitPerSymbol = 2;symbolPerCarrier = 50;% 开始测试s_len = nSubC*bitPerSymbol* symbolPerCarrier;SNR = 0:2:20;ber1 = zeros(1,length(SNR));ber2 = zeros(1,length(SNR));ber3 = zeros(1,length(SNR)); for kk = 1:length(SNR)max = floor((2^kk)/10)+10;fprintf('仿真信噪比:%d\n', SNR(kk));fprintf('仿真点数: %d\n', max*bitPerSymbol*symbolPerCarrier*nSubC);fade = [0]; % 信道参数,下标为延时点数,值为衰减系数ber = 0;for m = 1:max% 生成用于测试的随机比特s_in = floor( rand(1, s_len )*2 );sch = ofdm_mod_eq(s_in);sch = channel(sch,SNR(kk));s_out = ofdm_demod_eq(sch);%计算误比特率err_count = sum(abs(s_in-s_out));ber = ber + err_count/s_len;endber1(kk) = ber/max;fade = [0, 0, 0, 0, 0.4]; % 信道参数ber = 0;for m = 1:maxs_in = floor( rand(1, s_len )*2 );sch = ofdm_mod_eq(s_in);sch = channel(sch,SNR(kk));s_out = ofdm_demod_eq(sch);%计算误比特率err_count = sum(abs(s_in-s_out));ber = ber + err_count/s_len;endber2(kk) = ber/max ;fade = [0, 0, 0, 0, 0.4, 0.3]; % 信道参数,下标为延时点数,值为衰减系数ber = 0;for m = 1:max% 生成用于测试的随机比特s_in = floor( rand(1, s_len )*2 );sch = ofdm_mod_eq(s_in);sch = channel(sch,SNR(kk));s_out = ofdm_demod_eq(sch);%计算误比特率err_count = sum(abs(s_in-s_out));ber = ber + err_count/s_len;endber3(kk) = ber/max ;endfigure(2);semilogy(SNR,ber1,'o-');hold on;semilogy(SNR,ber2,'r*-');hold on;semilogy(SNR,ber3,'gv-');xlabel('SNR in dB');ylabel('Bit Error Rate');legend('AWGN','AWGN + 2 path','AWGN + 3 path');grid;toctest2.m%% 多径信道下,有无添加CP的系统误码率曲线close all;clear all; clc; tic ; %计时开始global CP_len;global nSubC;global ifft_len;global bitPerSymbol;global symbolPerCarrier;global s_len;global fade; %信道衰弱%% 测试参数CP_len = 0;nSubC = 48;ifft_len = 256;bitPerSymbol = 2;symbolPerCarrier = 50; fade = [0, 0, 0, 0.4, 0.3]; % 信道参数% 开始测试s_len = nSubC*bitPerSymbol* symbolPerCarrier;SNR = 0:2:30;ber1 = zeros(1,length(SNR));ber2 = zeros(1,length(SNR));for kk = 1:length(SNR)max = floor((2^(kk))/50)+10;fprintf('仿真信噪比:%d\n', SNR(kk));fprintf('仿真点数: %d\n', max*nSubC*bitPerSymbol*symbolPerCarrier);CP_len = 0;ber = 0;for m = 1:max% 生成用于测试的随机比特s_in = floor( rand(1, s_len )*2 );sch = ofdm_mod_neq(s_in);sch = channel(sch,SNR(kk));s_out = ofdm_demod_neq(sch);%计算误比特率err_count = sum(abs(s_in-s_out));ber = ber + err_count/s_len ;endber1(kk) = ber/max;fprintf('cp=0 :%f\n',ber1(kk));CP_len = 16;ber = 0;for m = 1:max% 生成用于测试的随机比特s_in = floor( rand(1, s_len )*2 );sch = ofdm_mod_neq(s_in);sch = channel(sch,SNR(kk));s_out = ofdm_demod_neq(sch);%计算误比特率err_count = sum(abs(s_in-s_out));ber = ber + err_count/s_len;endber2(kk) = ber/max ;fprintf('cp=16 :%f\n\n',ber2(kk));endfigure(2);semilogy(SNR,ber1,'o-');hold on;semilogy(SNR,ber2,'r*-');xlabel('SNR in dB');ylabel('Bit Error Rate');legend('no CP','CP');grid;toctest3.m%% 本测试为有无使用均衡情况下的系统误码率曲线%%close all;clear all; clc; tic ; %计时开始global CP_len;global nSubC;global ifft_len;global bitPerSymbol;global symbolPerCarrier;global s_len;global fade; %信道衰弱%% 测试参数%SNR = 40; % dBCP_len = 16;nSubC = 48;ifft_len = 256;bitPerSymbol = 2;symbolPerCarrier = 50; fade = [0, 0, 0, 0.4, 0.3]; % 信道参数,下标为延时点数,值为衰减系数% 开始测试s_len = nSubC*bitPerSymbol*symbolPerCarrier;SNR = 0:2:20;ber1 = zeros(1,length(SNR));ber2 = zeros(1,length(SNR));for kk = 1:length(SNR)max = floor((2^kk)/10)+10;fprintf('仿真信噪比:%d\n', SNR(kk));fprintf('仿真点数: %d\n', max*bitPerSymbol*symbolPerCarrier*nSubC);CP_len = 16 ;ber = 0;for m = 1:max% 生成用于测试的随机比特s_in = floor( rand(1, s_len )*2 );sch = ofdm_mod_neq(s_in);sch = channel(sch,SNR(kk));s_out = ofdm_demod_neq(sch);%计算误比特率err_count = sum(abs(s_in-s_out));ber = ber + err_count/s_len;endber1(kk) = ber/max;fprintf('无均衡 BER = %f\n',ber1(kk)); CP_len = 16;ber = 0;for m = 1:max% 生成用于测试的随机比特s_in = floor( rand(1, s_len )*2 );sch = ofdm_mod_eq(s_in);sch = channel(sch,SNR(kk));s_out = ofdm_demod_eq(sch);%计算误比特率err_count = sum(abs(s_in-s_out));ber = ber + err_count/s_len;endber2(kk) = ber/max ;fprintf('均衡和CP BER = %f\n\n',ber2(kk));endfigure(2);semilogy(SNR,ber1,'o-');hold on;semilogy(SNR,ber2,'r*-');xlabel('SNR in dB');ylabel('Bit Error Rate'); legend('without equilizer','with equlizer');grid;toc。
程序流程说明
1、基本流程描述
接收端采用的算法和程序流程与发送端发送的OFDM符号的帧结构有关系。
具体的帧结构,以及定时估计,频偏估计,剩余误差跟踪的算法可参考算法说明文档。
这里对程序的流程进行说明。
首先根据短训练字的特性进行相关运算,进行信号到达检测,当检测到相关值大于门限一定次数后,认为有信号到达。
然后根据长训练字的特性,进行相关运算,进行OFDM符号FFT窗口起始位置的估计。
估计出FFT窗口的位置后,先在时域进行小频偏的估计,将两个长训练字进行小频偏补偿后,进行FFT运算,根据FFT运算的结果进行整数倍频偏的估计。
这些参数估计完成后,就可以进行数据解调了。
先对数据部分进行完整的频偏补偿,然后根据估计的FFT窗口位置进行FFT运算得到频域的数据,进行解调。
然后在对应于导频的子载波位置上提取出导频信息,根据导频信息估计出剩余定时误差以及剩余的信道响应误差,将误差量送入环路进行跟踪。
当收到所有数据后,重新回到信号到达检测状态,进行下一次信号到达的检测和信号接收。
2、流程图
程序流程图如下:。