OFDM学习、编程实现
先来看一下OFDM的原理图:
上图的过程可以用IFFT实现,IFFT充当的是一个实现子载波正交的作用,具体可以推导其DFT公式。
Matlab中有一个实现5G OFDM的函数,可以帮助我们理解OFDM的原理。
官方的使用方法有以下三种:
[waveform,info] = nrOFDMModulate(carrier,grid)
[waveform,info] = nrOFDMModulate(grid,scs,initialNSlot)
[waveform,info] = nrOFDMModulate(___,Name,Value)
- [waveform,info] = nrOFDMModulate(carrier,grid)
我们先看第一种方式,他有两个参数,carrier(载波)和grid(网格),Matlab中对这种用法的描述如下:
[waveform,info] = nrOFDMModulate(carrier,grid) generates waveform, a time-domain waveform, by performing orthogonal frequency-division multiplexing (OFDM) modulation of carrier resource array grid for carrier configuration parameters carrier. The function also returns info, a structure containing OFDM information.
翻译过来就是说,这个函数用来产生一个ofdm调制的时域信号,输入的参数有载波资源网格和载波配置参数,这个函数同时也能返回一个包含有ofdm信息的结构体。
相信很多人看完后和我还是一样很懵,但是,我们可以知道两个重要信息:1.资源网格;2.载波。这两个是很重要的参数,花开两朵,各表一枝。我们逐个击破。Matlab中给出了一个例子,我把它拿来看看,跑一跑,加深以下理解。
咱们逐行运行一下它的程序:
carrier = nrCarrierConfig('SubcarrierSpacing',30,'NSizeGrid',24);%设置载波配置参数,指定载波资源阵列中30 kHz的子载波间隔和24个资源块(RB)。
一个RB包含了12个子载波。运行完之后在matlab中生成了一个结构体:
可以看到,每个Slot有14个符号,每个子帧有两个Slot,每帧有10个子帧。
再往下运行:
srs = nrSRSConfig('SRSPeriod',[2 0]);%设置时隙的周期为2,偏移量为0
同样,它返回的结构体如下:
参数很多,难以理解。
info = nrOFDMInfo(carrier); %从载波参数中获取ofdm信息
得到的结构体信息如下:
通过创建和连接单个时隙资源阵列来生成帧资源阵列。
往下运行:
grid = [];
for nslot = 0:(info.SlotsPerFrame - 1)%通过创建和连接单个时隙资源阵列来生成帧资源阵列。carrier.NSlot = nslot;slotGrid = nrResourceGrid(carrier);ind = nrSRSIndices(carrier,srs);sym = nrSRS(carrier,srs);slotGrid(ind) = sym;grid = [grid slotGrid];
end
我对这行代码的理解是创建一个个时隙的网格,然后将它们连在一起,就是一帧的网格,可以看到nslot是20,就是10个subFrame,刚刚好就是1帧。
这次生成了一个288X280的复数矩阵:grid。
上面说到,资源网格,是一个很重要的参数,现在终于看到它了。它是一个280列的矩阵,280,联想一下,20个时隙Slot就是20X14个符号,因此,280的含义是一帧的符号数,288又是什么意思呢?前面说到,有24个资源块(RB),一个RB包含了12个子载波。那么就是24X12=288个资源网格。我渐渐理解了这个矩阵的含有,它的横轴就是时间(符号),纵轴就是频率(资源网格说白了就是子载波的频率排成一列,每一个子载波带宽就是一个网格)。
最后一行代码:
[waveform,info] = nrOFDMModulate(carrier,grid);%执行ofdm调制
最终调制后的生成的waveform信号是一个复数序列,很多都是0。
完整的代码如下:matlab至少是2020b才能运行。
clc;clear all;close all;
carrier = nrCarrierConfig('SubcarrierSpacing',30,'NSizeGrid',24);
srs = nrSRSConfig('SRSPeriod',[2 0]);
info = nrOFDMInfo(carrier);
grid = [];
for nslot = 0:(info.SlotsPerFrame - 1)carrier.NSlot = nslot;%时隙的编号:0~13slotGrid = nrResourceGrid(carrier);%一个资源网格,空网格ind = nrSRSIndices(carrier,srs);%SRS子载波所在位置sym = nrSRS(carrier,srs);%SRS频域序列,即ZC序列slotGrid(ind) = sym;%grid = [grid slotGrid];
end
[waveform,info] = nrOFDMModulate(carrier,grid);
保存下来生成的复数序列:waveform,它是一个153600的列向量。前面看到,采样率是15360000Hz,因此153600个点的时常就是(153600/15360000)=10ms。10ms就是一个帧的时长。
在matlab中画出来它的波形:
waveform的实部图
waveform的实部图局部放大:
再放大:
看一下它的频域图:
局部放大:
得到上述信号后,它还仅仅是基带信号,做链路仿真,不会做上下行变频的。
链路仿真主要目的是仿真上下行链路级的性能,不会考虑RF的性能。
上下行变频造成的影响,可以用matlab做,但射频方面的仿真,做了用处不是特别大。
做上变频可以参考我另一篇博客5G中的上变频
这里进行上变频的程序为
data = waveform;%波形幅值
t = (0:1:153600-1)*(0.01/153600);%采样时间
fc = 2500000000;%2.5GHz载频
I = real(data);%取I路
Q = imag(data);%取Q路
I_carrier = cos(2*pi*fc*t);%对I路进行调制
Q_carrier = sin(2*pi*fc*t);%对Q路进行调制
I_carrier = I_carrier';%I路调制
Q_carrier = Q_carrier';%Q路调制
st = I.*I_carrier - Q.*Q_carrier;%相加,st即为调制后的信号
plot(t, st);
title('modulated signal')
看一下结果:
先是原图:
放大一个SRS:
再放大:
看一下这个IQ调制后的频谱图:
放大:
上面过程完整的程序如下:
%% 参考网站 https://ww2.mathworks.cn/help/5g/ref/nrofdmmodulate.html
clc;clear all;close all;
carrier = nrCarrierConfig('SubcarrierSpacing',30,'NSizeGrid',24);%30KHz子载波间隔,24个资源快,也即是24*12=288个资源网格,256<288<512,因此进行512个点的fft,带宽即512*30K=15.36MHz,采样率即15.36M
srs = nrSRSConfig('SRSPeriod',[2 0]);%周期为2,偏移量为0(代表着它出现在SRS信号出现在每个时隙的最后一个符号上)
info = nrOFDMInfo(carrier);
grid = [];
for nslot = 0:(info.SlotsPerFrame - 1)carrier.NSlot = nslot;slotGrid = nrResourceGrid(carrier);%每个slot的网格ind = nrSRSIndices(carrier,srs);%索引,下表sym = nrSRS(carrier,srs);%SRS频域符号slotGrid(ind) = sym;%在网格中插入符号grid = [grid slotGrid];%在一个时隙中
end
[waveform,info] = nrOFDMModulate(carrier,grid);%进行OFDM调制%% 波形绘制
data = waveform;%波形幅值
t = (0:1:153600-1)*(0.01/153600);%采样时间
fc = 2500000000;%2.5GHz载频
I = real(data);%取I路
Q = imag(data);%取Q路
I_carrier = cos(2*pi*fc*t);%对I路进行调制
Q_carrier = sin(2*pi*fc*t);%对Q路进行调制
I_carrier = I_carrier';%I路调制
Q_carrier = Q_carrier';%Q路调制
st = I.*I_carrier - Q.*Q_carrier;%相加,st即为调制后的信号
plot(t, st);
title('modulated signal');
OFDM学习、编程实现相关推荐
- 为什么您不需要精通数学就可以学习编程
by Pau Pavón 通过保罗·帕文(PauPavón) 为什么您不需要精通数学就可以学习编程 (Why you don't need to excel at math to learn how ...
- 免费学习编程的10个好工具
互联网时代的快速发展,很多人都在学习编程技术,小编今天为大家推荐的就是学习编程技术会用到的一些编程工具,免费学习编程的10个好工具!希望能够帮助到正在学习的小伙伴们. 免费学习编程的10个好工具: 1 ...
- 学习编程能够从事哪些行业?
一直在谈如何学习编程,学习Java,C/C++.Python等一些前景良好的东西.可能有些人会问,那我们学编程能从事那些工作呢? 01互联网企业 最直接的工作就是到一个科技企业做程序员,人家码砖头,我 ...
- 如果学习编程可以重来
在过去的几个月里,我一直在学习用Objective-C编写iOS app,最后我开始理清思绪.这比我想象中要难很多,也花了太长时间. 我经常遇到困难.感到沮丧,修复bug比实际写代码要花太多时间.但是 ...
- 12 个最佳的免费学习编程的游戏网站【转】
转自:http://blog.csdn.net/jxgz_leo/article/details/52767185 本文导航 -CodinGame -Code Combat -Screeps -Che ...
- 我十年学习编程的历史
首先,我不是标题党.其次,我只想说说十年来我自己的关于编程的故事,做过的一些乱七八糟的程序.我的成长并不快,下面这些程序已经足够让我丢脸的了,喜欢发难的朋友,尽管嘲笑我吧(当然,如果你产生了共鸣,我们 ...
- 如果当初学习编程时能有人给我这些忠告该多好
Cecily Carver 是多伦多的一位程序媛,和 Jennie Faber 一起创办了一个游戏制作工作室.她喜欢歌剧.舞蹈和弹钢琴.Cecily 在这篇文章分享她在编程道路上的所感所想,给出很多 ...
- 学习编程可以参考哪些网站?
1.Free Online Course Materials https://ocw.mit.edu/index.htm 免费的麻省理工学院课程,有各种视频讲座.笔记和资源. 2.codecademy ...
- 7种从头开始免费学习编程的方法
我们曾在一篇文章中讨论过不会编程算不算是文盲的问题,虽然有人认为这样有点说过头,但同时也不可否认如今编程确实显得越来越重要.比如作为设计师,懂一些编程可能会帮你更好地理解自己工作内容:而如果你想从头开 ...
- 我对孩子学习编程的一点思考
暑假里,贝爸搞了一次Scratch少儿编程夏令营,完全免费的,但我是非常认真的,课程结束后我还给孩子们发了证书.这篇文章算是对这段时间的一个总结吧. 起先,贝爸原计划是这个假期里给贝贝讲讲什么是程序, ...
最新文章
- 【Timbre,Amplitude,Pitch】声音的基本属性
- asp服务器推送消息,asp.net实时向客户端推送消息(SignalRWeb)
- matlab中 bsxfun函数
- Selenium_用selenium webdriver实现selenium RC中的类似的方法
- Spring官方都说废掉GuavaCache用Caffeine,你还不换?
- Skywalking-09:OAL原理——如何通过动态生成的Class类保存数据
- java list详解_java集合List解析
- mysql 左表为null_sql left join count 左表为空表的时候出现空行
- VideoMatch: Matching based Video Object Segmentation
- springboot指定属性返回_Spring Boot 最最最常用的注解梳理
- solr配置oracle数据源,Solr索引Oracle数据库的基本配置
- 【最终幻想15 国王之剑】制作介绍2:最大限度满足角色,背景和道具的要求
- 网易16年春季实习生招聘的一道算法题
- 昨天申请了三丰云免费云服务器,体验不错
- tpc-e mysql_mysql评测工具TPC-C使用
- 18.导数的几何意义
- linux运行dock打包的镜像,Docke镜像和仓库基础命令
- nexus学习 五、搭建阿里云代理
- 使用top做sql分页
- 台式APE播放机 硬盘APE播放器 APE Player Ver0.1完成