目录

  • 一、OFDM经典框架图
  • 二、基础理论
    • (一)导频(Pilot)
    • (二)保护间隔(Guard)
    • (三)帧、符号、子载波、导频、保护间隔的关系
  • 三、代码流程图
  • 四、代码
  • 五、代码和原图下载

一、OFDM经典框架图

二、基础理论

(一)导频(Pilot)

  • 本质:导频不携带信息,导频是双方已知的数据,因为所有子载波会产生一定的相位偏移,在信号中插入导频是提供相位参考,来做接收信号时候的信道估计。

  • 原理:将训练信号(导频)插入帧中,以便接收器可以根据导频和数据类似地失真的假设来估计信道响应。 设计了一种适当的导频模式来满足这种假设。 OFDM系统中的典型导频模式为:块,梳状和分散式。如下图所示。

(二)保护间隔(Guard)

  • 也叫保护频带

  • 作用:多径信道会对OFDM符号造成ISI影响,破坏了子载波间的正交性。故需要采取一些方法来消除多径信道带来的符号间干扰(ISI)影响,即插入保护间隔。

  • 方法:

  1. 补零(zp),即在保护间隔中填充0
  2. 另一种是插入循环前缀(cp)或循环后缀(cs)实现OFDM的循环扩展(为了某种连续性),cp是将OFDM后部的采样复制到前面,长度为Tcp,故每个符号的长度为Tsym=Tsub+Tcp,Tsub为数据部分子载波数。Tcp大于或等于多径时延,符号间的ISI影响将被限制在保护间隔中,因此不会影响下一个OFDM的FFT变换。

(三)帧、符号、子载波、导频、保护间隔的关系

  • 该图中是一帧数据,64× 8 的矩阵,64行表示64个子载波,8列表示8个OFDM符号。这个图对应以下代码的各个参数设置。结合该该图和代码理解,几者的关系。

OFDM的一帧数据矩阵图

三、代码流程图

代码流程图

四、代码


% Benchmark code for OFDM communication system in AWGN channel
% AWGN信道下OFDM通信系统的基准码%% Step 1: Configurations
clc;
%clear all;
close all;
save_tx_data = 1;
if save_tx_datamkdir('mat');
end
% 1.1 OFDM parameters
N = 64;                                                 % FFT size, Number of total subcarriers FFT大小,子载波总数
Ncp = 16;                                             % Length of Cyclic prefix 循环前缀的长度
Ts = 1e-7;                                             % Sampling period of channel 信道采样周期
Fd = 0;                                                  % Max Doppler frequency shift 最大多普勒频移
Np = 8;                                                 % No of pilot symbols 导频的数量
Ng = 4;                                                 % No of side guard subcarriers 保护频带数
Ndc = 2;                                               % No of DC guard subcarriers 直流保护频带数
Ndata = N - Np - 2.*Ng - Ndc;          % No of Data subcarriers per symbol 每个符号的数据子载波数46
Frame_size = 8;                                  % OFDM symbols per frame 每帧的OFDM符号数
Nframes = 1000;                                % Size of tested OFDM frames: set as 10^4 for smooth curve传送的数据帧数量
M_set = [2, 4, 8, 16];                          % Modulation orders 调制方式序列
SNRs = 0:1:8;                                      % Test SNR points 测试的信噪比取值区间
% 1.2 Vehicles for results              存结果berofdm_all = zeros(5,length(SNRs));
berofdm_all(1,:) = SNRs;
serofdm_all = zeros(5,length(SNRs));
serofdm_all(1,:) = SNRs;% 1.3 Calculate pilot locations           计算导频位置 ,以上图片中黄色圆圈的位置DC_sc = [N/2, N/2+1];                                                           % 32 33     第一个符号中直流保护频带的位置下标;以上图片中中间两行白色圆圈部分
Effec_sc = [Ng+1:N-Ng]; %5~60
Effec_sc = setdiff(Effec_sc, DC_sc);% 5:1:6                          % 第一个符号中数据+导频的位置下标pilot_loc = [1:ceil(length(Effec_sc)/Np):length(Effec_sc)];% 产生第一个符号中导频的位置下标
Pilot_sc = Effec_sc(pilot_loc);                                               % 存储第一个符号中导频的位置下标
% guard_sc = [1,2,3,4,61,62,63,64]
guard_sc = [1:Ng,N-Ng+1:N];                                              % 保护频带的位置下标,以上图片上四行和尾四行的白色圆圈部分Np = length(pilot_loc); % Recalculate Number of pilot  8
pilot_sc_frame = [];                                                                % 存储一帧8个符号所有的导频下标位置
guard_sc_frame = [];                                                             % 存储一帧8个符号所有的保护频带下标位置
DC_sc_frame = [];;                                                                 % 存储一帧8个符号所有的直流保护频带下标位
for i_sym = 0:Frame_size-1  %0~7                                      % 在一帧中8个符号一次计算导频+保护频带+直流保护频带位置pilot_sc_sym = Effec_sc(sort(mod((pilot_loc + i_sym*3)-1,length(Effec_sc))+1)); pilot_sc_frame = [pilot_sc_frame, pilot_sc_sym+i_sym*N];% 5:7:504 ;1* 64            % 采用Comb的导频方式 guard_sc_frame = [guard_sc_frame, guard_sc+i_sym*N];%1:1:502DC_sc_frame = [DC_sc_frame, DC_sc+i_sym*N];
end% C=setdiff(A,B)函数返回在向量A中却不在向量B中的元素,并且C中不包含重复元素,并且从小到大排序。
data_sc_frame = setdiff([1:Frame_size*N],guard_sc_frame);
data_sc_frame = setdiff(data_sc_frame, pilot_sc_frame);
data_sc_frame = setdiff(data_sc_frame, DC_sc_frame); %% 存储一帧8个符号所有的数据下标位置                                                                                                % 存储一帧8个符号所有的保护频带下标位%% Step 2: Test Loops
mod_names = {'BPSK','QPSK','8QAM','16QAM'};          % 该代码只是测试了BPSK的调制方式
channel = 'AWGN';
mat_name = sprintf('BER_OFDM_%s_Gray.mat',channel);
csv_name = sprintf('BER_OFDM_%s_Gray.csv',channel);
snr = SNRs;for m_ary = 1:1M = M_set(m_ary);     %BPSK调制方式                        % 选择BPSK的调制方式berofdm = zeros(1,length(snr));                                    % 为存储误码率做准备serofdm = zeros(1,length(snr));                                   % 为信号错误率做准备  for i = 1:length(snr) % 9                                                  % 在9个不同信噪比下做调制解调% Step 2.1 Transmitter% 2.1.1 Random bits generationD = round((M-1)*rand(Ndata*Frame_size,Nframes));  % 随机产生要传送的数据域D_test = reshape(D, Ndata, Frame_size*Nframes);      % 第一次矩阵变换 46× 8000(8× 1000)D_gray = D_test;                                                                   % gray2bin(D_test,'qam',M); 46* 16000的矩阵txbits = de2bi(D_gray(:));                                                    % de2bi 把十进制数转换成二进制向量,为计算误码率做准备% 2.1.2 Modulation Dmod = qammod(D,M,'gray');% 2.1.3 Framing 组装成帧,构造帧Data = zeros(N*Frame_size,Nframes);                           % 初始化一个存储所有帧的矩阵Data(data_sc_frame,:) = Dmod;                                        % 把数据域插入到矩阵中txamp = max(abs(Dmod(:)));pilot_signal = txamp.*sqrt(1/2).*(1+1i);                           % Norm pilot power to peak constellation power 初始化一个导频的数值Data(pilot_sc_frame,:)= pilot_signal;                                 % 把导频插入到矩阵中Data = reshape(Data, N, Frame_size*Nframes);           % 第二次矩阵变换  64× 8000% 2.1.4 To Time-domain OFDM symbolIFFT_Data = (N/sqrt(N-2*Np))*ifft(Data,N);                     % 频域转时域,及时傅里叶变换TxCy = [IFFT_Data((N-Ncp+1):N,:); IFFT_Data];                % Add Cyclic prefix添加16位的循环前缀[r, c] = size(TxCy);Tx_Data = TxCy;% 2.1.5 Clip PAPR to 8 (9dB)削减PAPR?????????%由于OFDM 符号是由多个独立经过调制的子载波信号叠加而成的,%当各个子载波相位相同或者相近时,叠加信号便会受到相同初始相位信号的调制,%从而产生较大的瞬时功率峰值,由此进一步带来较高的峰值平均功率比%Tx_Amp = abs(Tx_Data);                                                       %对复数取模Tx_Power = Tx_Amp.^2;Power_PAPR8 = 8.*mean(Tx_Power,1);Clip_loc = Tx_Power > Power_PAPR8;Clip_Data = Tx_Data./Tx_Amp;Clip_Data = sqrt(Power_PAPR8).*Clip_Data;Tx_Data(Clip_loc) = Clip_Data(Clip_loc);% Step 2.2 Wireless Channel                                                 % 模拟信道的串并转换Tx_Data = reshape(Tx_Data, r*Frame_size,[]);                  % 第三次矩阵变换640× 1000% 2.2.2 Add AWGN noisey1 = awgn(Tx_Data,snr(i),'measured');                                % 模拟信道,添加高斯白噪声                y = reshape(y1,r,[]);  %80* 8000                                           % 出信道,80× 8000第四次矩阵变换% Step 2.3: OFDM Receiver% 2.3.1 Remove cyclic prefix 去循环前缀Rx = y(Ncp+1:r,:);               % 2.3.2 Transform to Frequency-Domain    转换时域到频域Rx_Freq = (sqrt(N-2*Np)/N)*fft(Rx,N,1);% 2.3.3 Reshape to Frame size  FFT_Data = reshape(Rx_Freq,N*Frame_size,[]);                % 512× 1000 第五次矩阵变换,为提取每一帧的数据单元% 2.3.4 Extract Data Cells   提取数据单元格,从每一帧中提取数据FFT_Data = reshape(FFT_Data(data_sc_frame,:), [], Nframes*Frame_size);%46× 8000 第六次矩阵变换,为解调% 2.3.5 Demodulation  Rx_Data = qamdemod(FFT_Data,M,'gray');     Rx_gray = Rx_Datarxbits = de2bi(Rx_gray(:));                                                    %为了计算误码率而要转换成二进制的% Step 2.4 Collect BER and SER[bitErrors,ber] = biterr(txbits,rxbits);%[number,ratio] = symerr(x,y)%输出number是一个标量或向量,表示不同元素的数量。 输出ratio等于number除以较小输入中的元素总数。[symErrors,ser] = symerr(Rx_Data(:),D(:));                        %计算符号错误数和符号错误率serofdm(i) = ser;berofdm(i) = ber;Y(1,1,:,(i-1)*Nframes+1:i*Nframes) = D;                            %存储原始信号数据IX = real(y1);                                                                           %提取IQ信号的实部QX = imag(y1);                                                                        %提取IQ信号的虚部for j =1:size(IX,2)tempX(:,:,1,j) = [IX(:,j) QX(:,j)];endX(:,:,1,(i-1)*Nframes+1:i*Nframes) = tempX;                    %存IQ信号endberofdm_all(m_ary+1,:) = berofdm;                                         %存误码率serofdm_all(m_ary+1,:) = serofdm;                                           %存符号错误率
end%% Step 3: Result Presentation: Plot BER
save(mat_name, 'berofdm_all','serofdm_all');csvwrite(csv_name, berofdm_all);figure;
semilogy(SNRs,berofdm_all(2:5,:),'--x','LineWidth',2);
grid on;
title('OFDM BER vs SNR in AWGN channel');
xlabel('SNR (dB)');
ylabel('BER');
legend(mod_names);
save('Data_BPSK.mat','X','Y');

五、代码和原图下载

OFDM存储IQ信号代码、OFDM的帧关系图、代码流程图下载

OFDM中的帧(frame)、符号(symbol)、子载波(subcarriers)、导频(Pilot)、保护间隔(guard)的关系图解以及代码详解--MATLAB相关推荐

  1. css中怎么消除a的下划线,如何使用css去掉a标签的下划线?(代码详解)

    写html超链接的时候,超链接总是自带下划线,如果不需要下划线,我们需要将其去掉,下面我们就来说一下怎么去掉下划线. 我们在使用超链接的时候,下划线总是伴随着出现,从视觉上来说有着下划线的a标签总是感 ...

  2. python使用视频_Python中操作各种多媒体,视频、音频到图片的代码详解

    我们经常会遇到一些对于多媒体文件修改的操作,像是对视频文件的操作:视频剪辑.字幕编辑.分离音频.视频音频混流等.又比如对音频文件的操作:音频剪辑,音频格式转换.再比如我们最常用的图片文件,格式转换.各 ...

  3. 利用unity和steamVR完成场景漫游(二) 关于steamVR插件中的代码详解

    1.SteamVR.cs 单例管理类,管理SteamVR程序的运行和终止. 2.SteamVR_Camera.cs 给场景添加一个最基本可运行的SteamVR组. 3.SteamVR_CameraFl ...

  4. python播放视频代码_Python中操作各种多媒体,视频、音频到图片的代码详解

    我们经常会遇到一些对于多媒体文件修改的操作,像是对视频文件的操作:视频剪辑.字幕编辑.分离音频.视频音频混流等.又比如对音频文件的操作:音频剪辑,音频格式转换.再比如我们最常用的图片文件,格式转换.各 ...

  5. js 浅拷贝直接赋值_JS中实现浅拷贝和深拷贝的代码详解

    (一)JS中基本类型和引用类型 JavaScript的变量中包含两种类型的值:基本类型值 和 引用类型值,在内存中的表现形式在于:前者是存储在栈中的一些简单的数据段,后者则是保存在堆内存中的一个对象. ...

  6. LoRa节点开发:5、代码详解LoRaWAN中的几种数据包(发送与接收数据)

    本文来源微信公众号[物联网思考] 本文主要结合LoRaNode SDK v4.4.2和LoRaWAN规范1.0.3来展开. 1.数据包类型 LoRaWAN规范中有不同的数据包,通过MType字段区分, ...

  7. Make your own Neural NetWork之代码详解中

    这篇博客接上一篇博客Make Your Own Neural Network之代码详解上.本文也是出自Make your own Neural NetWork这本书.上一篇博客讲了神经网络类的功能模块 ...

  8. matlab在数值计算中的应用,详解MATLAB在科学计算中的应用

    详解MATLAB在科学计算中的应用 编辑 锁定 讨论 上传视频 <详解MATLAB在科学计算中的应用>是2011年电子工业出版社出版的图书,作者是陈泽占海明. 书    名 详解MATLA ...

  9. C++中数组和指针的关系(区别)详解

    C++中数组和指针的关系(区别)详解 本文转自:http://c.biancheng.net/view/1472.html 博主在阅读后将文中几个知识点提出来放在前面: 没有方括号和下标的数组名称实际 ...

  10. 【genius_platform软件平台开发】第五十八讲:Linux系统之V4L2视频驱动-VIDIOC_REQBUFS向驱动申请帧缓冲代码详解

    VIDIOC_REQBUFS向驱动申请帧缓冲代码详解 1. 概述 2. 应用层 3. 内核驱动 3.1 vb2_ioctl_reqbufs函数 3.2 vb2_core_reqbufs函数 3.3 _ ...

最新文章

  1. xamarin使用mysql_[开源] .NetCore .NetFramework Xamarin 使用 ORM FreeSql 访问 MySql
  2. ScheduledThreadPoolExecutor定时任务线程池执行原理分析
  3. 【学习笔记】Miller-Rabin(米勒-拉宾)素性测试,附常用表
  4. Icon+启动图尺寸
  5. 45万例患者基因检测显示:NGS很难检测出七分之一的致病变异
  6. 使用JS提交form表单和w3c标准
  7. STC12C5A60S2片内存储器介绍
  8. Windows下编译FFmpeg-2.6.1详解
  9. 直接通过服务器文件相对路径实现文件下载
  10. sandisk主控量产工具_[转载]群联PS3109主控固态硬盘修复教程_固态修复案例方法...
  11. linux磁盘写保护怎么修改_在Linux下创建写保护的文件的教程
  12. 【图神经网络】异构时间图卷积网络HTGCN——用于社区检测
  13. Appium相对坐标定位元素
  14. 解决一个远程主机强迫关闭连接的bug
  15. 将ubuntu光盘作为安装源_从光盘安装ubuntu
  16. 数据分析出的 2000年以来高分华语电影前50名
  17. LWIP源码分析——ip4.c
  18. php json输出对象的属性值,JavaScript_jquery动态遍历Json对象的属性和值的方法,1、遍历 json 对象的属性/ - phpStudy...
  19. trans系列平移距离模型
  20. GE董事长兼首席执行官杰夫.伊梅尔特上任第一年致诸位股东、客户与员工(中英文)

热门文章

  1. 小米3 android4.4,小米3移动版原厂刷机包4.4.4rom线刷包Root权限驱动
  2. CSDN早报-2019-04-29
  3. 哈哈哈,我终于注册了CSDN的账号
  4. vue-cli开发Vue项目时定义环境变量需加VUE_APP前缀
  5. Java SSM 项目实战 day02 功能介绍,SSM整合,数据库和IDEA的maven工程搭建,产品信息查询和添加
  6. rk3288 android7.1.2 4g模块调试(四)
  7. 宏观经济指标分析与数据可视化——PMI
  8. 如何在html页面跳转的时候携带数据(页面跳转时参数传递问题)?
  9. 关键路径例题图表_计算题专题:关键路径法(CPM)
  10. matlab线性规划求解函数:linprog