OFDM
正交频分复用(Orthogonal Frequency Division Multiplexing, OFDM)是一种多载波调制技术,用于高效地传输数据,特别是在无线通信和宽带网络中。OFDM通过将数据分割成多个并行的低俗数据流,并分别调制到多个正交子载波上,从而提高了频谱效率和抗干扰能力。
OFDM的基本原理
1.多载波调制
- OFDM将宽带信号分割成许多窄带子信号(子载波),每个子载波都携带一部分数据。
- 这些子载波彼此正交,因此可以在频谱上紧密地排列而不会相互干扰
2.正交性
- 子载波的正交性保证了在频域中,每个子载波在其他子载波中心频率处对其贡献为零,意味着子载波间不会相互干扰
如图所示,每个子载波的中心频率处,其他子载波的幅度为零。
这验证了子载波的正交性,即在子载波的中心频率处没有相互干扰。
这样,图示有效地说明了OFDM子载波之间的正交性如何确保子载波间不会相互干扰(ICI)
3.快速傅里叶变换
- OFDM使用FFT和逆FFT(IFFT)来实现子载波调制和解调。IFFT用于将调制后的频域信号转换回时域信号,FFT用于将接收到的时域信号转换回频域信号进行解调。
- OFDM系统中的每个子载波都在频域上调制了数据,通过IFFT,这些频域的子载波信号被转换为一个单一的时域信号。这是因为物理信道传输的是时域信号,而不是频域信号。
OFDM调制过程
1.数据分割
- 输入的数据流被分割成多个子数据流,每个子数据流的速率较低。
2.调制
- 每个子数据流在子载波上进行调制,常用的调制方式有QPSK、QAM等
3.串并转换
- 调制后的子数据流通过串并转换器转换为并行信号。
4.逆快速傅里叶变换(IFFT)
- 并行信号经过IFFT转换到时域,生成OFDM符号。
5.加入循环前缀(cp)
- 为了对抗多径干扰,通常在每个OFDM符号前添加循环前缀。循环前缀是从OFDM符号尾部复制的一部分,添加到符号的开头。
6.并串转换
- 将并行信号转换回串行信号,生成时域的OFDM信号。
7.射频传输
- 将时域信号转换为模拟信号,通过射频(RF)链路进行传输
OFDM解调过程
1.射频接收
- 接收端接收到射频信号并将其转换为基带信号。
2.去除循环前缀
- 去掉循环前缀以恢复原始OFDM符号。
3.快速傅里叶变换(FFT)
- 通过FFT将时域信号转换回频域,得到各个子载波上的数据.
4.子载波解调
- 对每个子载波进行解调,恢复子数据流。
5.并串转换
- 将并行信号转换为串行信号,恢复原始的数据流。
OFDM的优点
1.高频谱效率
子载波的正交性允许子载波紧密排列,提高了频谱利用率。
2.抗多径干扰能力强
循环前缀和子载波调制使得OFDM在多径环境下表现优异,减少了符号间干扰(ISI, Inter-Symbol Interference)。
3.简化信道均衡
在频域中进行信道均衡比在时域中简单许多,因为每个子载波可以独立地进行均衡。
4.适应性强
可以根据信道条件动态调整子载波的调制方式和功率分配,提高传输效率和可靠性。
OFDM调制的matlab代码
% 参数设置
N = 64; % 子载波数量
CP_len = 16; % 循环前缀长度
num_symbols = 10; % OFDM符号数量
mod_order = 16; % 16-QAM调制阶数
SNR_dB = 20; % 信噪比(dB)
% 生成随机数据
data_bits = randi([0 mod_order-1], N * num_symbols, 1);
% 调制映射(16-QAM)
qam_modulated_data = qammod(data_bits, mod_order, 'UnitAveragePower', true, 'InputType', 'integer');
% 串并转换
data_blocks = reshape(qam_modulated_data, N, num_symbols).';
% IFFT转换
ifft_data = ifft(data_blocks, N, 2);
% 添加循环前缀
cyclic_prefix = ifft_data(:, end-CP_len+1:end);
ofdm_symbols = [cyclic_prefix, ifft_data];
% 并串转换
tx_signal = reshape(ofdm_symbols.', [], 1);
% 多径信道模型
h = [0.9 0.5 0.2]; % 简单的多径信道脉冲响应
rx_signal = conv(tx_signal, h, 'same');
% 添加噪声
rx_signal = awgn(rx_signal, SNR_dB, 'measured');
% 接收端处理
% 重新转换为并行数据块
rx_ofdm_symbols = reshape(rx_signal, N + CP_len, num_symbols).';
% 去除循环前缀
rx_ofdm_symbols = rx_ofdm_symbols(:, CP_len+1:end);
% FFT转换
rx_data_blocks = fft(rx_ofdm_symbols, N, 2);
% QAM解调
rx_data_bits = qamdemod(rx_data_blocks.', mod_order, 'UnitAveragePower', true, 'OutputType', 'integer');
% 重新串行化数据
rx_data_bits = rx_data_bits(:);
% 计算误码率
[~, BER] = biterr(data_bits, rx_data_bits);