MATLAB ofdmmod 函数使用说明

最近在看ofdm相关的东西,发现matlab本身也有自带的调制函数,乍一看没搞懂是怎么个用法,写这个笔记的过程中把这个函数大概搞清楚了,也顺便复习一下ofdm的调制过程。


matlab的帮助文档中描述此函数有四种语法,分别是:

1.Y=ofdmmod(X,nfft,cplen);

2.Y=ofdmmod(X,nfft,cplen,nullidx);

3.Y=ofdmmod(X,nfft,cplen,nullidx,pilotidx,pilots);

4.Y=ofdmmod(X,nfft,cplen,___,OversamplingFactor=Value;


语法1:Y=ofdmmod(X,nfft,cplen)

对于语法1,X代表子载波上携带的数据,ofdmmod采用快速傅里叶变换的方式实现正交频分复用,nfft代表快速傅里叶变换长度,cplen即cyclic prefix length 循环前缀长度。

此代码为文档中对语法1的示例,描述的是,双天线发射,16QAM调制,128子载波,循环前缀长度16,每帧传输5个ofdm符号(我不知道此处的RE为何意,故理解为帧)的情况。

M = 16;      % Modulation order for 16QAM
nfft  = 128; % Number of data carriers
cplen = 16;  % Cyclic prefix length
nSym  = 5;   % Number of symbols per RE
nt    = 2;   % Number of transmit antennas
dataIn = randi([0 M-1],nfft,nSym,nt);
qamSig = qammod(dataIn,M,'UnitAveragePower',true);
y1 = ofdmmod(qamSig,nfft,cplen);

y1输出的是一个720×2的复数数组,(128+16 )×5=720,没有问题。

调出其中一组数据的第一个符号来看一下循环前缀的效果:

plot(abs(y1(1:128+16,1)));
xlim([1,144]);

 可以看到,1:16的符号其实就是129:144的符号。


语法2:Y=ofdmmod(X,nfft,cplen,nullidx);

比语法1多了一个参数nullindx,文档的描述是:

Y = ofdmmod(X,nfft,cplen,nullidx) inserts null subcarriers into the frequency domain input data signal prior to performing OFDM modulation. The null subcarriers are inserted at index locations from 1 to nfft, as specified by nullidx. For this syntax, the number of rows in the input X must be nfftlength(nullidx). Use null carriers to account for guard bands and DC subcarriers.

 在进行OFDM调制之前在频域输入信号中插入空子载波,插入的位置可以是索引1到nfft(这里直译过来就是这样,其实我不太懂啥意思,看下面)。此时,输入的X行数长度必须为nfft-length(nullidx)。这些空载波是用来放置保护频带或是直流载波的。

给的代码是这样的:

M = 16;     % Modulation order for 16QAM
nfft  = 64; % FFT length
cplen = 16; % Cyclic prefix length
nSym  = 10; % Number of symbols per RE

nullIdx  = [1:6 33 64-4:64]';
numDataCarrs = nfft-length(nullIdx);
inSym = randi([0 M-1],numDataCarrs,nSym);

qamSig = qammod(inSym,M,'UnitAveragePower',true);
outSig = ofdmmod(qamSig,nfft,cplen,nullIdx);

16QAM调制,fft长度64,循环前缀16,每帧10个ofdm符号。

值得注意的是,根据代码中对子载波数据numDataCarrs的描述,此时nfft应该不是子载波个数,而是进行ifft的长度了,进行了ifft处理的数据除了16QAM符号应该还包含其他东西,也就保护间隔或直流载波。nullidx是为保护间隔和直流载波占了位置,在这里还没有加入数据。

因此这句语法对应的处理效果可以画图表示成这样:

 


语法3:Y=ofdmmod(X,nfft,cplen,nullidx,pilotidx,pilots);

又多了两个参数,pilotidx和pilots,很好理解,就是导频的位置和导频信号本身。

Y = ofdmmod(X,nfft,cplen,nullidx,pilotidx,pilots) inserts null and pilot subcarriers into the frequency domain input data symbols prior to performing OFDM modulation. The null subcarriers are inserted at the index locations specified by nullidx. The pilot subcarriers, pilots, are inserted at the index locations specified by pilotidx. For this syntax, the number of rows in the input X must be nfftlength(nullidx)length(pilotidx). The function assumes pilot subcarrier locations are the same across each OFDM symbol and transmit antenna.

和上面那个差不多,在频域插入了空载波和导频载波。前面提到空载波是为保护间隔和直流载波预留的,所以在这里,pilotidx和nullidx是两组数组,并不是包含关系。也就是除了前面的空载波外,又插入了一组空载波,但是新插入的空载波是用来放置导频信号的。相应的,QAM信号的长度又得削减一点,也就对应了导频的加入对信号造成了额外开销。最后一句话说,这个函数他就只能设置一种导频放置位置,如果像第一个例子中那种有俩天线发射,对不起,你们导频的位置一样。

同样地,看一下例子:

M = 16;     % Modulation order
nfft = 64;  % FFT length
cplen = 16; % Cyclic prefix length
nSym  = 10; % Number of symbols per RE

nullIdx  = [1:6 33 64-4:64]';
pilotIdx = [12 26 40 54]';

numDataCarrs = nfft-length(nullIdx)-length(pilotIdx);
dataSym = randi([0 M-1],numDataCarrs,nSym);
qamSig = qammod(dataSym,M,UnitAveragePower=true);
pilots = repmat(pskmod((0:3).',4),1,nSym);

y2 = ofdmmod(qamSig,nfft,cplen,nullIdx,pilotIdx,pilots);

在pilotidx处又加了导频之后be like:

但是这个图只是一个ofdm信号,要知道一帧里面是传输了10个ofdm信号的,并且通常是构建一个10列(nSym)的二维数组来表示一帧的,所以实际上应该是这样的一个图:

这也说明了为啥上面的pilot要进行repmat操作了。


语法4: Y=ofdmmod(X,nfft,cplen,___,OversamplingFactor=Value;

在前面这些语法的基础上,又给出了上采样因子这个参数,该值必须为正标量,也可以是分数。默认情况下上采样因子值为1。但是要注意不要四舍五入,例如对FFT长度为12的信号进行4/3上采样,结果本来应该是获得16个信号。如果这里输入写的不是4/3而是1.333,那么会报错,因为这么算的话应该输出15.9960个信号,这是不可能的。

给的示例代码是这个:

M = 64;      % Modulation order
osf = 3;     % Oversampling factor
nfft = 256;  % FFT length
cplen = 16;  % Cyclic prefix length

nullidx  = [1:6 nfft/2+1 nfft-5:nfft]';
numDataCarrs = nfft-length(nullidx);

x = randi([0 M-1],numDataCarrs,1);
qamSig = qammod(x,M,UnitAveragePower=true);
y = ofdmmod(qamSig,nfft,cplen,nullidx,OversamplingFactor=osf); 

运行了一下,竟然报错了:

数据长度、空载波长度和导频长度加起来不等于FFT长度;但是代码内是用fft长度减去空载波长度来定义数据长度的,不应该报这个错。我觉得和上采样因子的引入有关,于是把这一项去掉之后运行了一下代码,是没有问题的。

语法4中和报错中都提到了导频,但在此例子中我们并没有设置导频。

但是我加入导频之后仍然报错,显示输入参数过多。

这个问题目前还没有解决,欢迎大家探讨。

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值