• OFDM系统各种QAM调制阶数在多径信道下的误码性能仿真(暂存版本)


    本文考虑OFDM系统在多径信道下的误码性能 

    代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    clc;close all;clear
     
    %% Seting parameters
    EbN0_list = 20:2:40;
    Q_order_list = 2:2:10;
    loopNumber = 10000;
    fprintf('Qm\t EbN0 \t \t EsN0 \t \t SNR_Cal \t \t ser \t\t ser_theory\t\t\t ber\t\t nloop \t\t \n');
    for iQorder = 1 : length(Q_order_list)
    for iEbN0 = 1 : length(EbN0_list)
     
    %% Frame structure
    N_Frame = 1;
    N_Symbol = 1;
    N_RB = 106;
    N_SC_perRB = 12;
    N_SC = N_RB * N_SC_perRB;
    N_Ant = 1;
    N_fft_order = floor(log2(N_RB * N_SC_perRB));
    N_fft = 2^(N_fft_order+1);
    N_cp = N_fft/8;
    EbN0 = EbN0_list(iEbN0);
     
    %% Modulation
    Q_order = Q_order_list(iQorder);
    Qm = 2^Q_order;
    N_bit = N_Frame * N_Symbol * N_RB * N_SC_perRB * Q_order;
     
    %% Noise Calculation
    SNR =  EbN0 + 10 * log10(Q_order);
     
    %% Loop
    for iloop = 1 :loopNumber
    data_bit_in = randi([0 1], 1, N_bit);
    dataSymbolsIn = bi2de(reshape(data_bit_in, Q_order, N_bit/Q_order).', 'left-msb');
    dataMod = qammod(dataSymbolsIn, Qm,'UnitAveragePower', true);
     
    %% Show Constellation
    %scatterplotme(dataMod)
     
    %% Resource Mapping
    RE_Grid = zeros(N_RB * N_SC_perRB,N_Symbol * N_Frame);
    dataMod_tmp = reshape(dataMod,N_RB * N_SC_perRB,[]); %only data
    Power_Scale = 1;
    RE_Grid_all = Power_Scale * dataMod_tmp;
     
    %% IFFT add CP
    frame_mod_shift = ifftshift(RE_Grid_all);
    ifft_data = ifft(frame_mod_shift,N_fft)*sqrt(N_fft);
    %ifft_data = ifft(frame_mod_shift)*sqrt(1272);
    Tx_cd = [ifft_data(N_fft-N_cp+1:end,:);ifft_data];
    time_signal = reshape(Tx_cd,[],1);
     
    %% Channel
    power_RE = sum(sum(abs(RE_Grid_all).^2)) / N_RB / N_SC_perRB / N_Symbol / N_Frame;
    power_tp = sum(sum(abs(ifft_data).^2)) / N_RB / N_SC_perRB / N_Symbol / N_Frame;  %IFFT zero padding averages the true RE Power
    N0 = power_RE .* 10.^(-SNR / 10);
    white_noise_starand = 1/sqrt(2)*(randn(size(time_signal)) + 1j * randn(size(time_signal)));
    nTap = 2;
    taps = RayleighChanTaps(nTap);
    % taps = [0.9,0.1];
    time_signal_path = Multipath_channel(time_signal,taps);
    TransmittedSignal = time_signal_path + sqrt(N0) * white_noise_starand;
     
    %% Receive and Sys
    ReceivedSignal = TransmittedSignal;
    hF = fftshift(fft(taps,N_fft));
     
    %% FFT and Frame  
    frame_recieved_parallel = reshape(ReceivedSignal, N_fft + N_cp, []);
    frame_Received = frame_recieved_parallel(N_cp + 1:end,:);   
    frame_Grid_fft = fft(frame_Received,N_fft) / sqrt(N_fft);
    RE_Grid_all_fftshift = fftshift(frame_Grid_fft);
    RE_Grid_all_fftshift_eq = fftshift(diag(1./hF)*RE_Grid_all_fftshift);
    RE_Grid_all_Received = fftshift(RE_Grid_all_fftshift_eq(1:N_SC,:));
    % figure(1)
    % plot(abs(RE_Grid_all_fftshift(:,1)))
    % figure(2)
    % plot(abs(RE_Grid_all_fftshift_eq(:,1)))
    % figure(3)
    % plot(abs(abs(hF)))
    % figure(4)
    % plot(abs(abs(1./hF)))
     
    %% Demodulation
    RE_PreDeMod = reshape(RE_Grid_all_Received,[],1);
    dataSymbolsOut = qamdemod(RE_PreDeMod, Qm,'UnitAveragePower', true);
    data_bit_out = reshape((de2bi(dataSymbolsOut, 'left-msb')).',1,[]);
    power_RE_receid = sum(sum(abs(RE_PreDeMod).^2)) / N_RB / N_SC_perRB / N_Symbol / N_Frame;
    snr_all(iQorder,iEbN0,iloop) = 10*log10(power_RE/(power_RE_receid - power_RE));
     
    %% Result: Ser and Ber
    %Ser
    sym_err = length(find(dataSymbolsOut - dataSymbolsIn));
    ser_all(iQorder,iEbN0,iloop) = sym_err / length(dataSymbolsOut);
    %Ber
    bit_error = sum(abs(data_bit_out - data_bit_in));
    ber_all(iQorder,iEbN0,iloop) = bit_error / length(data_bit_out);
    end
    sers = mean(ser_all,3);
    snrs = mean(snr_all,3);
    bers = mean(ber_all,3);
    sers_theory(iQorder,iEbN0) = QAM_SER_Theory(Qm,EbN0);
     
        fprintf('%dQAM\t%f\t %f\t %f\t %e\t\t%e\t\t%e\t\t%d\t\n', Qm, EbN0, SNR,snrs(iQorder,iEbN0),sers(iQorder,iEbN0),sers_theory(iQorder,iEbN0),bers(iQorder,iEbN0),loopNumber);
        end
    end
     
    figure(1)
    semilogy(EbN0_list, bers(1,:), 'k--+');
    hold on
    grid on
    semilogy(EbN0_list, bers(2,:), 'r--o');
    semilogy(EbN0_list, bers(3,:), 'b--x');
    semilogy(EbN0_list, bers(4,:), 'g--s');
    xlabel('Eb/N0,dB');
    ylabel('BER');
    title('BER VERS SNR');
    legend('QPSK','16QAM','256QAM','1024QAM');
     
     
    figure(2)
    semilogy(EbN0_list, sers(1,:), 'k--+');
    hold on
    grid on
    semilogy(EbN0_list, sers(2,:), 'r--o');
    semilogy(EbN0_list, sers(3,:), 'b--x');
    semilogy(EbN0_list, sers(4,:), 'g--s');
    xlabel('Eb/N0,dB');
    ylabel('SER');
    title('SER VERS SNR');
    %SML =  simulation, THR = theory
    legend('QPSK','16QAM','256QAML','1024QAM');

     用到的信道与过信道代码

    1
    2
    3
    4
    function taps = RayleighChanTaps(nTap)
      taps= 1/sqrt(2)*1/sqrt(nTap)*(randn(nTap,1) + 1j*randn(nTap,1));
       
    end

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    function taps = ExponentialChanTaps(SampRateMHz, delaySprdNsec)
    sampTimeNsec = 1000 / SampRateMHz;
     
    if delaySprdNsec == 0
        Kmax = 0;
        vark = 1;
    else
        Kmax = ceil(10 * delaySprdNsec/sampTimeNsec);
        var0 = 1 - exp(- sampTimeNsec /delaySprdNsec);
        k = (0:Kmax)';
        vark = var0 * exp( -k *sampTimeNsec/delaySprdNsec);
    end
        stdDevReOrIm = sqrt(vark/2);
        taps = stdDevReOrIm .*(randn(Kmax +1,1) + 1j*randn(Kmax+1,1));
    end

     

    1
    2
    3
    4
    5
    6
    function yt = Multipath_channel(xt,taps)
        ht = taps;
        xht = conv(ht,xt);
        %yt = xht(end - length(xt)+1:end);
        yt = xht(1:length(xt));
    end

     仿真结果

    瑞利信道下的仿真结果,设置抽头系数为2,仿真次数设置1000次曲线才会平滑。

    在瑞利信道和白噪声下的仿真结果对比

    一个感兴趣的点是固定信噪比时误码性能随多径的数量是如何变化的,先保证最大时延扩展没有超过CP的长度。该实验结果仅设置了100次,看起来曲线不是很光滑。在完美已知信道抽头系数的情况下,多径的数量不会影响解调性能。

     

    结论分析

    瑞利信道下的误码率曲线近似为直线,(很奇怪,难以理解)

    反思

     

  • 相关阅读:
    pytorch安装(windows)
    SIMULIA现实仿真解决方案 SIMULIA仿真模拟应用程序
    大模型lora微调-chatglm2
    Vue框架学习笔记——Vue框架的安装
    YOLOv8学习
    数据结构:二叉树的顺序结构--堆
    URI 和 URL 的区别
    Vue - 得到组件渲染的DOM
    如何在 Spring Boot 中使用 Quartz 调度作业
    程序设计中遇到的程序不通、逻辑不顺等问题
  • 原文地址:https://www.cnblogs.com/TensorLearning/p/18043051