MATLA 5G工具箱---无线通信入门之旅

基于MATLAB R2022b版软件学习!

官方提供正版的无线通信入门教程:无线通信入门之旅 (mathworks.com)

B站也有官方相应的通信视频:MATLAB中国的个人空间_哔哩哔哩_bilibili

 

仅仅加了白噪声(AWGN)

增加滤波

滤波器保证传输的信号在其频带范围内

发射和接收滤波器需要有相同的频率相应

 

这里选用升余弦滤波器,消除符号间干扰(ISI)

波峰对应相邻其他波形的零点,ISI

黄色是无噪声的信号(发射滤波器输出),蓝色的为含噪声的信号(加了白噪声AWGN)

对于每个滤波器,延迟是滤波器长度(以符号数表示)的一半。

但是,要比较位,您需要确定延迟的位数,而不是延迟的符号数。可以用符号数乘以 bitsPerSymbol(16-QAM为4) 将延迟从符号数转换为位数。

 

SNR虽然很低,但是有滤波器之后,误码率更低。

 

 

  

在脚本中定义了 mpChanOut 后,仿真的其余部分就会执行。

计算 BER 并将其显​​示在输出窗格中。正如预测的那样,多径导致链路几乎无法使用。必须对设计进行重大更改,才能重新操作。

为了更好地理解此问题,可以通过取消脚本末尾代码的注释来查看发射信号的频谱和信道输出。发射信号为黄色,而含噪多径信号为蓝色。

接收到的信号的频谱的通带中有一个“缺口”,这会使单载波波形发生显著扭曲。这种现象称为频率选择性多径,因为信道衰减或增益的水平取决于频率。

LTE、WiFi 和 5G 等现代系统采用了一种技术来应对多径现象。它被称为正交频分复用 (OFDM),我们将在接下来的练习中应用这种技术。

 

 

总和

可通过IFFT有效x实现

发射机IFFT    接收机FFT

ifft 函数计算信号的离散傅里叶逆变换。

sigOut = ifft(sig)


输出信号与输入信号大小相同。

请注意,仿真中的位数发生了变化 – 它现在是 2 的幂,这意味着 QAM 信号的长度也是 2 的幂。对于特定长度的信号,包括长度为 2 的幂的信号,ifft 和 fft 函数明显更快。

 

在脚本中创建变量 ofdmModOut 后,它将通过噪声信道发送。

接下来,在接收机中,您需要通过执行 FFT 来“撤消”IFFT。

fft 函数通过快速傅里叶变换算法计算离散傅里叶变换。

sigOut = fft(sig)

由于 OFDM 解调器输出是 16-QAM 信号,让我们看看它的散点图。

scatterplot()

信号是通过噪声信道发送的,因此您应该会在星座图中看到一些噪声。脚本还会计算 BER,您可以在第 11 行更改 SNR 值以查看链路的性能。

该链路的性能与没有 OFDM 的噪声 16-QAM 链路差不多 – 如果将 SNR 增加到大约 20,则不会出现误码。

但是链路在遇到多径信道时的性能如何还是未知的。您将在下一次练习中了解这一点。

OFDM Modulation with IFFT

Instructions are in the task pane to the left. Complete and submit each task one at a time.
This code sets up a 16-QAM link with OFDM modulation.
numBits = 32768; % power of 2, to optimize performance of fft/ifft
modOrder = 16; % for 16-QAM

 
srcBits = randi([0,1],numBits,1);
qamModOut = qammod(srcBits,modOrder,"InputType","bit","UnitAveragePower",true);
ofdmModOut = ifft(qamModOut);

Task

Channel: multipath channel and/or AWGN
hasMultipath = true;
hasAWGN = true;
SNR = 28;
chanOut = channel(ofdmModOut,hasMultipath,hasAWGN,SNR);
 
 
Demodulate the received signal and calculate the BER.
ofdmDemodOut = fft(chanOut);
scatterplot(ofdmDemodOut)
title("OFDM Demodulator Output")
qamDemodOut = qamdemod(ofdmDemodOut,modOrder,"OutputType","bit","UnitAveragePower",true);
numBitErrors = nnz(srcBits~=qamDemodOut)
BER = numBitErrors/numBits
 
Local Function: Apply channel to transmitter output.
function chanOut = channel(sig,hasMP,hasAWGN,SNR)
% Apply multipath channel if selected
if hasMP
mpChan = [0.8; zeros(7,1); -0.5; zeros(7,1); 0.34];
mpChanOut = filter(mpChan,1,sig);
else
mpChanOut = sig;
end
% Apply AWGN if selected
if hasAWGN
chanOut = awgn(mpChanOut,SNR,"measured");
else
chanOut = mpChanOut;
end
end

 

通过接收机中的复数增益来补偿信道的信号损失和相位变化

 

多径的信道会对着信号的带宽而变化

进而导致选择性衰落,不同频率衰落程度不同

接收机需要通过均衡器来消除通道产生的所有波峰和波谷

OFDM将高速率的信号转换为低速率的并行信号

 

每个低速率信号的带宽都很窄,所以频谱相对平坦

可以将复数增益应用于每个单独的子载波,从而消除波峰和波谷

可以先进行信道估计

但该均衡方程仅在信道对信号执行循环卷积时才成立

实际情况中,信道执行线性卷积(由于仅仅只是一个滤波器)

如果信号是周期性的,那么线性卷积和周期卷积就是相同的

所以需将信号变成周期性的,即增加循环前缀,并且循环前缀需要与信道冲激响应一样长

 

 

 

 

在接收机中去掉循环前缀(除去多径干扰)

 

 

还添加保护频带

 

 

在设计实际 OFDM 系统时,子载波数(FFT 大小)是一个重要的设计参数。

该仿真是围绕子载波数设计的 – 创建单个 OFDM 符号,其中每个子载波加载有一个 16-QAM 符号。要生成的源位数是通过将子载波数乘以每个 16-QAM 符号的位数来计算的。

设置源位数后,脚本创建源位序列并使用 16-QAM 对其进行调制。

下一步是对包括循环前缀的信号执行 OFDM 调制。

ofdmmod 和 ofdmdemod 函数将为您管理循环前缀。您所要做的就是指定循环前缀的长度。

循环前缀必须至少与信道的冲激响应一样长。但它也不宜过长,因为其中包含的是将要丢弃的重复数据。在本例中,多径信道冲激响应长度为 17,因此我们要使用比 17 稍大一点的循环前缀长度。

使用 ofdmmod 函数执行 OFDM 调制,指定子载波数和循环前缀长度。

sigOut = ofdmmod(sig,nCarr,cpLen)

接下来,OFDM 调制信号将通过信道发送到接收机。

在接收机中,使用 ofdmdemod 函数执行 OFDM 解调,同样指定子载波数和循环前缀长度。

sigOut = ofdmdemod(sig,nCarr,cpLen)

均衡发生在频域中,因此您需要使用 fft 函数变换信道冲激响应。通过传递 FFT 大小作为第二个输入来设置 FFT 大小。

fft(mpChan,numCarr)



fft 函数的输出以零频率分量开始,但 ofdmdemod 函数指定的是频率范围中间的零频率分量。使用 fftshift 移动信道的频谱,使零频率分量位于中心。

fftshift(fft(mpChan,numCarr))

现在您已做好均衡信号的准备。为此,将其逐元素除以信道频率响应。

使用 ./ 运算符将两个向量逐元素相除。

x ./ y

 

均衡信号的散点图更接近于所需的星座图,并且已消除了多径信道的大部分效应。

此脚本会解调 16-QAM 信号并计算误码率。频域均衡器极大地提高了链路的性能,甚至在存在多径信道的情况下也是如此。要仅查看均衡器对多径信道的效用,请尝试在第 5 行将 SNR 增加到 100。

在本例中,每个子载波都是数据子载波,但实际情况并非总是如此。有些子载波会被指定用于数据以外的其他用途。在下一次练习中,您就会使用这样一种子载波 – 空子载波。

在 MATLAB 中,您可以通过子载波的索引来识别子载波。子载波从左到右编号,从 1 开始,以 numCarr 结束。ofdmmod 和 ofdmdemod 函数按从最负频率到最正频率的顺序排列子载波,零频率分量位于中间。

要指定保护带索引,首先要设置每个保护带中的子载波数。然后,您可以使用冒号运算符定义保护带索引。左侧保护带的索引由以下公式给出:

1:numGBCarr



。类似地,您可以定义右侧保护带的索引。

(numCarr-numGBCarr+1):numCarr
numGBCarr = numCarr/16
gbLeft = (1:numGBCarr)
gbRight = ((numCarr-numGBCarr+1):numCarr)

ofdmmod 函数指定的是频率范围中间的零频率分量。这意味着 DC 空子载波是中心索引。当子载波个数为偶数时,DC 空索引设置为

numCarr/2 + 1



要创建空子载波索引的列向量,请将左侧保护带、DC 和右侧保护带索引串联,然后转置。

[left dc right]'
dcIdx = numCarr/2 + 1
nullIdx = [gbLeft dcIdx gbRight]'
 
 
子载波的总数是 numCarr。但是,该仿真会通过每个数据子载波发送一个 16-QAM 符号。这意味着该仿真的源位序列是基于数据子载波数创建的。

要确定数据子载波数,请从子载波总数中减去空子载波数。

然后,要生成的源位数是数据子载波数乘以每个 16-QAM 符号的位数。
numDataCarr = numCarr-length(nullIdx)
numBits = numDataCarr*bitsPerSymbol
 
设置源位数后,脚本创建源位序列并使用 16-QAM 对其进行调制。

现在您可以使用 ofdmmod 函数执行 OFDM 调制。要指定空子载波,请将空索引向量作为第四个输入传递。

sigOut = ofdmmod(sig,nCarr,cpLen,nullIdx)
 
ofdmModOut = ofdmmod(qamModOut,numCarr,cycPrefLen,nullIdx)
 
接下来,OFDM 调制信号通过信道发送到接收机。

使用 ofdmdemod 函数对接收到的信号执行 OFDM 解调。由于使用了空子载波,所以该函数需要两个额外的输入:符号采样偏移量和空索引向量。

sigOut = ofdmdemod(sig,nCarr,...
      cpLen,symOffset,nullIdx)


符号采样偏移量是在执行 FFT 之前要丢弃的信号采样数。它可以是 0 到循环前缀的长度之间的任何值。要删除被多径信道损坏的信息,它应该大于多径信道冲激响应的长度
ofdmDemodOut = ofdmdemod(chanOut,numCarr,cycPrefLen,cycPrefLen,nullIdx)
 
下一步是均衡信号。

与之前一样,使用 fft 和 fftshift 函数变换和移动信道冲激响应。

fftshift(fft(mpChan,numCarr))


信道频率响应具有 numCarr 频率分量。但是,OFDM 解调器输出仅包含数据子载波。要执行逐元素除法,您需要从信道频率响应中删除空子载波频率分量。

您可以使用索引删除向量的特定元素。

x(idx) = []
 
mpChanFreq = fftshift(fft(mpChan,numCarr))
mpChanFreq(nullIdx) = []
 
 
任务
通过除以 mpChanFreq 来均衡信号 ofdmDemodOut。将均衡信号命名为 eqOut

创建均衡信号的散点图。
eqOut = ofdmDemodOut./mpChanFreq
scatterplot(eqOut)
title("Frequency Domain Equalizer Output")

恭喜您!您已经仿真了一个包含保护带、空 DC 和频域均衡器的实际 OFDM 系统。

通过对脚本末尾的代码取消注释,您可以可视化发射信号和含噪多径信号的频谱。OFDM 发射信号为黄色,含噪多径信号为蓝色。您可以从多径信道中看到保护带和频率选择性衰落。

 

posted @ 2023-03-30 20:26  小明同学的铺铺  阅读(830)  评论(0编辑  收藏  举报