Matlab中IFFT/FFT注意事项及在OFDM仿真中的应用问题

1.Matlab里的IFFT/FFT函数系数的问题

  • Matlab里的ifft函数会在做完正常的变换后除以ifft变换的点数,而fft函数中没有系数。

  • Matlab里的IFFT变换及FFT变换:

  • 因此在Matlab上,利用fft函数做频谱分析,应注意以下几点:

  • (1)应对FFT的结果除以FFT点数,才能得到各频点的真实幅值。

  • (2)FFT的频率分辨力等于采样频率除以FFT点数,即:

  • (3)对实序列进行FFT,结果的前半部分,对应正频率,后半部分对应负频率,这样比较符合习惯。即前N/2个点对应频率,或者表示为。后N/2个点对应频率,或者表示为

  • (4)在Matlab中可以直接利用fftshift函数对fft的结果进行变换。另外,如果只画出半谱图,则需对除直流分量(fft的第一个结果)以外的其他分量幅值乘上2。

  • clc
    clear all
    close all
    fs= 200;%采样频率
    N = 256;%采样点数
    t = (0:N-1)/fs;%各采样点
    a = cos(2*pi*50*t)+cos(2*pi*75*t);
    b = fft(a);
    f = 0:fs/N:(N-1)/N*fs;
    figure
    subplot(211)
    plot(f,abs(b));title('直接FFT结果')
    subplot(212)
    plot(f,abs(b)/N);title('除以FFT点数得到的真实值')
    figure
    subplot(211)
    plot((0:fs/N:fs/2),abs(b(1:N/2+1))/N*2);title('半谱图')
    c = fftshift(b);%使用fftshift函数得到全谱图
    f1= -fs/2:fs/N:fs/2-fs/N;
    subplot(212)
    plot(f1,abs(c/N));title('正负频率半轴表示的全谱图')

    运行结果如下所示:

  • Matlab中IFFT/FFT注意事项及在OFDM仿真中的应用问题_第1张图片Matlab中IFFT/FFT注意事项及在OFDM仿真中的应用问题_第2张图片


  • 更多关于这个问题,以下这篇文章讲的很详细:https://blog.csdn.net/qq_39297053/article/details/113916666

  • 2.用IFFT/FFT实现OFDM系统中的调制解调应注意的问题

  • OFDM利用IFFT/FFT调制解调的公式如下所示,其中为准备调制的符号,为接收到采样序列:
  • OFDM对PSK或QAM符号调制过程:
  • OFDM对接收采样信号解调过程:

对照以上公式和公式(1.1-1.2),可以看出,两者只是系数1/N存在的位置不同。在简单的OFDM仿真中直接使用ifft函数调制及fft函数解调,对仿真结果是没有影响的。但是仔细考虑会发现,对PSK或QAM符号进行ifft调制得到的序列的能量会变小,再进行fft解调能量会变大。因此,在进一步的仿真中,为了使得频域和时域上能量的一致,一般需在IFFT后乘上,解调处理的时候先对接收序列除以再进行FFT变换。因此式(2.1-2.2)变为如下形式,其中也被称为功率归一化因子:

对功率归一化的理解:

调制之前各个符号能量为|x[k]|,符号的总能量为E(x[k]),在经过式(1.1)所示的N点的IFFT变换调制到各个子载波上后,各个子载波上的能量为\frac{|x[k]|}{N},总的子载波上的能量为\frac{E(x[k])}{N}。由此,对IFFT结果乘上后,各个子载波上的能量为|x[k]|,总的子载波上的能量为E(x[k])。这样就实现了频域上和时域上能量的一致,使得在仿真中更加方便地进行各种计算。另外需要注意的是功率归一化因子中的N应该是IFFT/FFT的点数,而不是有效子载波数(网上浏览时看到有些人弄混淆了)。

3.在IFFT之前对序列进行共轭对称处理的作用

对要调制的序列进行共轭对称处理,再分别调制到相应载波上是为了得到实的OFDM信号。在1中说过,FFT的前半结果表示正频率部分,后半结果表示负频率部分,这在IFFT过程中也是类似的。在进行N点的IFFT时,序列的第一个数定义直流成分,第\frac{N}{2}+1个数定义最高频率成分,再后面的即为负频率部分。

例如,若对采样频率为1kHz,长度为17的某个序列(序列长度要小于128/2)进行128点的IFFT变换,这个序列在做IFFT前存放在128个数中33-49的位置上,即。取该序列共轭存在第97-81的位置,这样正负频率对应共轭,ifft后就能得到一个实序列。而其他位置的值置零,即为空载波。(注:以上参数设置是为了解释方便。)

clc
close all
clear all
%% 参数设置
fs=1000;%采样频率
carrier_count=17;%调制符号数或有效子载波数
ifft_length=128;%FFT长度
M=4;%调制阶数
%% 产生随机序列
bit_per_symbol=log2(M); %每个子载波调制的比特数
bit_length=carrier_count*bit_per_symbol;%所有比特数
bit_sequence=randi([0 1],bit_length,1);%产生随机比特序列(列向量)
%% QAM调制
bit_moded=qammod(bit_sequence,M,'InputType','bit','UnitAveragePower',true);%QPSK调制并归一化
%% IFFT
carrier_position=33:49;%对应频段250Hz-375kHz
conj_position=97:-1:81;
ifft_position=zeros(ifft_length,1);
ifft_position(carrier_position)=bit_moded;%将调制符号存入33-49行
ifft_position(conj_position)=conj(bit_moded);%将调制符号取共轭存入97-81行
signal_time=ifft(ifft_position,ifft_length);
signal_time=signal_time*sqrt(ifft_length);%对经过IFFT的信号功率归一化
%% FFT
Rx_signal=signal_time/sqrt(ifft_length);
fft_sig=fft(Rx_signal,ifft_length);%FFT
Rx_bit_moded=fft_sig(carrier_position);%提取载波调制符号33-49
%% 能量计算
E_bit_moded=2*sum(sum(abs(bit_moded).^2))
E_ifft=sum(abs(signal_time).^2)
E_fft=sum(abs(fft_sig).^2)

运行结果可以看到IFFT后的结果signal_time为实序列,且能量在频域和时域上相等,证明了2中的结论。需要注意的是,在进行共轭对称处理后,序列能量翻倍了。

你可能感兴趣的:(MATLAB,matlab,数字通信,信号处理)