• 基于OFDM的通信系统模拟实现



    前言

    本文讲解了基于 OFDM 的通信系统模拟实现。


    一、OFDM 基本知识

    1、OFDM 理论知识及仿真

    有关 OFDM 相关理论知识及仿真参考我之前写过的博客:OFDM原理及MATLAB仿真

    2、OFDM 调制

    IDFT、IFFT

    3、OFDM 解调

    DFT、FFT

    二、2ASK(二进制振幅键控)

    因后面 OFDM 载波调制时每个子载波使用 2ASK 调制,因此这里对 2ASK 进行一个理论的讲解

    1、2ASK 基本原理

    振幅键控是利用载波的幅度变化来传递数字信息,而其频率和初始相位保持不变。在 2ASK 中,载波的幅只有两种变化状态,分别对应二进制信息 “0” 或 “1”。

    ①、OOK

    一种常用的、也是最简单的二进制振幅键控方式称为通一断键控(OOK),其表达式为:
    e O O K ( t ) = { A c o s ω c t 以概率 P 发送 “1” 时 0 以概率 1-P 发送 “0” 时 e_{OOK}(t)= {Acosωct以概率 P 发送 “1” 时0以概率 1-P 发送 “0” 时 eOOK(t)={Acosωct0以概率 P 发送 “1” 以概率 1-P 发送 “0” 

    典型波形如下图所示:
    在这里插入图片描述

    2ASK/OOK信号时间波形

    可见,载波在二进制基带信号 s ( t ) s(t) s(t) 控制下通一断变化,所以这种键控又称为通一断键控。在 OOK 中,某一种符号(“0” 或 “1”)用有没有电压来表示

    ②、2ASK

    2ASK 信号的一般表达式为:
    e 2 A S K ( t ) = s ( t ) c o s ω c t e_{2ASK}(t)=s(t)cos\omega_ct e2ASK(t)=s(t)cosωct
    其中
    s ( t ) = ∑ n a n g ( t − n T B ) s(t)=\sum_na_ng(t-nT_B) s(t)=nang(tnTB)
    式中: T B T_B TB 为码元持续时间; g ( t ) g(t) g(t) 为持续时间为 T B T_B TB 的基带脉冲波形。为简便起见,通常假设 g ( t ) g(t) g(t) 是高度为 1、宽度等于 T B T_B TB 的矩形脉冲; a n a_n an 是第 n n n 个符号的电平取值。若取
    a n = { 1 概率为 P 0 概率为 1-P a_n= {1概率为 P0概率为 1-P an={10概率为 P概率为 1-P
    则相应的 2ASK 信号就是 OOK 信号

    2、2ASK/OOK 信号产生方法

    2ASK/OOK 信号的产生方法通常有两种:模拟调制法(相乘器法)和键控法,相应的调制器如下图所示。图(a)就是一般的模拟幅度调制的方法,用乘法器(multiplier)实现;图(b)是一种数字键控法,其中的开关电路 s ( t ) s(t) s(t)控制
    在这里插入图片描述

    2ASK/OOK信号调制器原理框图

    3、2ASK/OOK 信号解调方法

    与 AM 信号的解调方法翌阳。2ASK/OOK 信号也有两种基本的解调方法:非相干解调(包络检波法)相干解调(同步检测法),相应的接收系统组成方框图如下图所示:
    在这里插入图片描述

    2ASK/OOK信号的接收系统组成方框图

    与模拟信号的接收系统相比,这里增加了一个“抽样判决器”方框,这对于提高数字信号的接收性能是必要的。

    下图给出了 2ASK/OOK 信号非相干解调过程的时间波形
    在这里插入图片描述

    2ASK/OOK信号非相干解调过程的时间波形

    2ASK 是 20 世纪初最早运用于无线电报中的数字调制方式之一。但是,ASK 传输技术受噪声影响很大。噪声电压和信号一起改变了振幅。在这种情况下,“0” 可能变为 “1”,“1” 可能变为“0”。可以想象,对于主要依赖振幅来识别比特的 ASK 调制方法,噪声是一个很大的问题。由于 ASK 是受噪声影响最大的调制技术,现已较少应用,不过,2ASK 常常作为研究其他数字调制的基础,还是有必要了解它。

    三、基于 OFDM 的通信系统模拟实现

    1、整体流程

    基于 OFDM 的通信系统模拟实现的整体流程图大致如下图所示:
    在这里插入图片描述

    2、MATLAB 源码

    % 这段代码是一个基于正交频分复用(Orthogonal Frequency Division Multiplexing,OFDM)
    % 的通信系统的模拟实现。下面是对代码进行详细分析的解释:
    
    % 这些命令用于清除命令窗口、清除工作区变量和关闭所有打开的图形窗口
    clc;            % 清除命令窗口
    clear;          % 清除工作区变量
    close all;      % 关闭所有打开的图形窗口
    
    % ===============================变量参数定义=============================================
    
    % 接下来的几行代码定义了一些变量和参数
    M  = 8;			% 子载波数,指定了OFDM系统中的子载波数量
    fc   = 1e6;		% 主载波频率/Hz,表示OFDM系统中的主载波频率
    fsub = 1e3;		% 子载波频率间隔,表示相邻子载波之间的频率间隔
    fsig = fc:fsub:fc+(M-1)*fsub; % 频率序列,计算出每个子载波的频率
    
    % 下面的几行代码定义了一些与时间和采样相关的参数
    T  = 0.001;		% 子载波持续时间,表示每个子载波的时间长度
    fs = 10e6;		% 采样频率/Hz,表示对信号进行采样的频率
    ts = 1/fs;		% 采样时间间隔,表示相邻采样点之间的时间间隔
    t  = 0:ts:T-ts;	% 一个符号周期的时间矢量,生成了一个从0到T的时间向量,用于表示一个符号周期内的时间
    
    % =============================== OFDM 频谱分析=============================================
    
    % 接下来的代码段生成了子载波信号,并进行了频谱分析
    c  = zeros(M,length(t));% c 是一个大小为 M×length(t)(目前这里是8*10000) 的矩阵,用于存储 M 个子载波的信号
    NN = length(t)*16;      % 计算了扩展后的采样点数,乘以 16 是为了提高频谱计算的分辨率,NN=10000*16
    XN = zeros(M,NN);       % XN 是一个大小为 M×NN (目前这里是8*160000)的矩阵,用于存储每个子载波信号的频域表示
    f0 = fs/NN;             % 采样间隔 = 采样率 / 采样点数
    f  = (0:NN-1)*f0;       % 采样间隔序列,计算出每个采样间隔的开始频率
    for k = 1:M
    	c(k,:)  = exp(1j*2*pi*fsig(k)*t);   % 生成一个复指数形式的子载波信号,通过循环遍历每个复指数形式的子载波,将复指数形式的子载波信号存储在矩阵 c 中
    	XN(k,:) = fft(c(k,:),NN);           % 并对每个子载波的信号进行快速傅里叶变换(FFT)得到其频域表示,并将结果存储在矩阵 XN 中
    end
    
    % 最后,使用 plot 函数将每个子载波的频谱绘制在一张图上,并设置图像的标题、坐标轴标签和图例。
    figure;
    plot(f,abs(XN(1,:)), f,abs(XN(2,:)), f,abs(XN(3,:)), f,abs(XN(4,:)), f,abs(XN(5,:)), f,abs(XN(6,:)), f,abs(XN(7,:)), f,abs(XN(8,:)));
    legend('1000kHz子载波', '1001kHz子载波', '1002kHz子载波', '1003kHz子载波', '1004kHz子载波', '1005kHz子载波', '1006kHz子载波', '1007kHz子载波');
    axis([995e3 1012e3 -inf inf]);  % x 轴范围设置成[995000,1012000],y 轴范围最小值和最大值都为无穷
    title('频域中 子载波分布图');
    ylabel('幅度');
    xlabel('频率/Hz');
    
    % =============================== OFDM 载波调制=============================================
    
    % OFDM载波调制(这里每个子载波使用 2-ASK 调制,实际上每个子载波使用PSK、QAM调制也可以)
    symbol = M;                         % 定义了发送的符号数,这里与子载波数相等
    msg  = randi([0 1],1,symbol);       % 并行发送 8bit 数据
    % msg  = [1 1 0 1 1 1 0 1];         % 并行发送 8bit 数据
    tx = zeros(1,length(t));            % tx 的大小是 1*10000,用来存储发射信号
    for k = 1:length(msg)               % 通过循环遍历每个子载波,将每个子载波信号乘以对应的数据位(0或1),并将它们叠加得到最终的发送信号
    	tx = tx + msg(k)*c(k,:);        % 子载波叠加
    end
    XN_tx = fft(tx,NN);                 % 使用FFT对发送信号 tx 进行频谱分析,并将结果存储在 XN_tx 中
    disp(['发送数据: ' num2str(msg)]);  % 显示发送的数据 msg
    
    % =============================== OFDM 空中信道传输=============================================
    
    % 空中信道传输
    sigma = sum(abs(tx))/length(tx) * 0.9;  % sigma 是根据发送信号 tx 的幅度计算得到的噪声标准差
    rx    = tx + sigma*rand(1,length(tx));  % rx 是将发送信号 tx 加上高斯白噪声(AWGN)后得到的接收信号,加入AWGN(实际上只影响直流分量)
    XN_rx = fft(rx,NN);                     % 使用FFT对接收信号 rx 进行频谱分析,并将结果存储在 XN_rx 中
    
    % =============================== OFDM 解调=============================================
    
    % OFDM解调
    msg_demodulation = zeros(1,symbol);         % msg_demodulation 是一个大小为 1×symbol 的向量,用于存储解调后的数据
    for k = 1:symbol                            % 通过循环遍历每个符号,利用FFT结果进行解调。如果接收到的信号在对应子载波的频谱中的幅度大于阈值(5e3),则将解调后的数据位设置为1,否则为0。
    	if(abs(XN_rx(16001 + 16*(k-1))) > 5e3)  % 使用FFT结果来解调
    		msg_demodulation(1,k) = 1;
    	end
    end
    disp(['收到数据: ' num2str(msg_demodulation)]);
    
    bit_error_cnt = 0;                              % bit_error_cnt 用于存储比特错误的数量,初始值为0。
    for k = 1:symbol
    	if(msg_demodulation(k) ~= msg(k))           % 如果解调后的数据位与发送的数据位不一致
    		% 当判定的接收比特与发送比特不一致时,认为判定错误
    		bit_error_cnt = bit_error_cnt + 1;
    	end
    end
    bit_error_percent = bit_error_cnt/symbol;       % 计算误码率 bit_error_percent,即比特错误的数量除以总的符号数。
    disp(['误码率: ' num2str(bit_error_percent)]);
    
    
    figure;
    subplot(2,1,1);plot(t,real(tx));axis([-inf inf -inf inf]);title('OFDM发送信号 时域图');
    ylabel('幅度');
    xlabel('时间/s');
    subplot(2,1,2);plot(t,real(rx));axis([-inf inf -inf inf]);title('OFDM接收信号 时域图');
    ylabel('幅度');
    xlabel('时间/s');
    
    figure;
    subplot(2,1,1);plot(f,abs(XN_tx));axis([995e3 1012e3 -inf inf]);title('OFDM发送信号 频谱');
    ylabel('幅度');
    xlabel('频率/Hz');
    subplot(2,1,2);plot(f,abs(XN_rx));axis([995e3 1012e3 -inf inf]);title('OFDM接收信号 频谱');
    ylabel('幅度');
    xlabel('频率/Hz');
    
    • 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

    3、仿真结果

    ①、OFDM 频谱分析

    请添加图片描述

    OFDM 频谱分析

    ②、OFDM 发送及接收信号时域图

    请添加图片描述
    请添加图片描述

    ③、OFDM 发送及接收信号频谱图

    请添加图片描述
    请添加图片描述

    ④、OFDM 误码率

    在这里插入图片描述

    四、资源自取

    基于OFDM的通信系统模拟实现


    我的qq:2442391036,欢迎交流!


  • 相关阅读:
    路由器二次开发一步一步把工业路由器变成一个高端的可指定出网、节点和链路的路由器,包含详细过程及快捷脚本(四)
    备战 2023 春招,P7大咖位手打 26 大后端面试专题神技,1500+题解析助力offer
    音视频进阶:浅谈Android 开发音视频入门之路
    ES写入数据报错:retrying failed action with response code: 429
    【Spring boot 集成 Junit 单元测试】
    自学Vue开发Dapp去中心化钱包(一)
    【MySQL数据库】最全安装过程及配置详解
    【MySQL命令】
    【python函数】torch.nn.Embedding函数用法图解
    150. 逆波兰表达式求值
  • 原文地址:https://blog.csdn.net/qq_41839588/article/details/133997625