%% OFDM 64QAM调制解调系统(含EVM计算)
clear; clc; close all;
% 参数设置
N = 64; % 子载波数量
cp_len = 16; % 循环前缀长度
num_symbols = 100; % OFDM符号数量
snr_dB = 30; % 信噪比(dB)
% 生成随机二进制数据 (64QAM每符号6比特)
total_bits = num_symbols * N * 6;
data_bits = randi([0 1], total_bits, 1);
% 64QAM调制
M = 64; % 调制阶数
tx_symbols = qammod(data_bits, M, 'InputType', 'bit', 'UnitAveragePower', true);
% OFDM调制
tx_ofdm_symbols = zeros(N + cp_len, num_symbols);
for k = 1:num_symbols
% 提取当前OFDM符号的数据
start_idx = (k-1)*N + 1;
end_idx = k*N;
symbols = tx_symbols(start_idx:end_idx);
% IFFT变换
ifft_out = ifft(symbols, N);
% 添加循环前缀
tx_ofdm_symbols(:, k) = [ifft_out(end-cp_len+1:end); ifft_out];
end
% 序列化为时域信号
tx_signal = tx_ofdm_symbols(:);
% 通过AWGN信道
rx_signal = awgn(tx_signal, snr_dB, 'measured');
% 重塑接收信号为矩阵形式
rx_matrix = reshape(rx_signal, N + cp_len, num_symbols);
% OFDM解调
rx_symbols = zeros(N, num_symbols);
for k = 1:num_symbols
% 提取当前OFDM符号
symbol = rx_matrix(:, k);
% 移除循环前缀
symbol_no_cp = symbol(cp_len+1:end);
% FFT变换
fft_out = fft(symbol_no_cp, N);
rx_symbols(:, k) = fft_out;
end
% 重塑为向量
rx_symbols = rx_symbols(:);
% 64QAM解调
rx_bits = qamdemod(rx_symbols, M, 'OutputType', 'bit', 'UnitAveragePower', true);
% 误码率计算
ber = sum(data_bits ~= rx_bits) / total_bits;
disp(['误码率(BER): ', num2str(ber)]);
%% EVM计算(新增功能)
% 1. 计算误差向量
e_vector = rx_symbols - tx_symbols;
% 2. 计算误差向量幅度
evm_per_symbol = abs(e_vector);
% 3. 计算RMS EVM
evm_rms = sqrt(mean(abs(e_vector).^2)) / sqrt(mean(abs(tx_symbols).^2));
evm_rms_percent = evm_rms * 100;
% 4. 计算峰值EVM
evm_peak = max(evm_per_symbol) / sqrt(mean(abs(tx_symbols).^2));
evm_peak_percent = evm_peak * 100;
% 显示结果
disp(['RMS EVM: ', num2str(evm_rms_percent), '%']);
disp(['Peak EVM: ', num2str(evm_peak_percent), '%']);
%% 增强型星座图可视化(含EVM指示)
figure;
% 发送星座图
subplot(1,2,1);
plot(real(tx_symbols), imag(tx_symbols), '.', 'MarkerSize', 8);
title('发送端64QAM星座图');
xlabel('同相分量'); ylabel('正交分量');
grid on; axis([-1.5 1.5 -1.5 1.5]);
axis square;
% 接收星座图(含EVM指示)
subplot(1,2,2);
hold on;
% 绘制接收符号
plot(real(rx_symbols), imag(rx_symbols), '.', 'MarkerSize', 8);
% 绘制误差向量(随机选择100个点显示)
sample_idx = randperm(length(rx_symbols), min(100, length(rx_symbols)));
for i = sample_idx
plot([real(tx_symbols(i)), real(rx_symbols(i))], ...
[imag(tx_symbols(i)), imag(rx_symbols(i))], 'r-', 'LineWidth', 0.5);
end
title({'接收端64QAM星座图', ...
['SNR = ', num2str(snr_dB), 'dB, RMS EVM = ', num2str(evm_rms_percent, '%.2f'), '%']});
xlabel('同相分量'); ylabel('正交分量');
grid on; axis([-1.5 1.5 -1.5 1.5]);
axis square;
hold off;
% 最大化窗口(如果环境支持)
try
set(gcf, 'WindowState', 'maximized');
catch
% 如果最大化不可用,则使用默认大小
end
%% 附加分析:EVM随SNR变化曲线(可选)
% 定义SNR范围
snr_range = 0:5:30;
evm_results = zeros(size(snr_range));
% 计算不同SNR下的EVM
for i = 1:length(snr_range)
% 通过AWGN信道
rx_signal_temp = awgn(tx_signal, snr_range(i), 'measured');
% 重塑接收信号
rx_matrix_temp = reshape(rx_signal_temp, N + cp_len, num_symbols);
% OFDM解调
rx_symbols_temp = zeros(N, num_symbols);
for k = 1:num_symbols
symbol = rx_matrix_temp(:, k);
symbol_no_cp = symbol(cp_len+1:end);
fft_out = fft(symbol_no_cp, N);
rx_symbols_temp(:, k) = fft_out;
end
rx_symbols_temp = rx_symbols_temp(:);
% 计算EVM
e_vector_temp = rx_symbols_temp - tx_symbols;
evm_rms_temp = sqrt(mean(abs(e_vector_temp).^2)) / sqrt(mean(abs(tx_symbols).^2));
evm_results(i) = evm_rms_temp * 100;
end
% 绘制EVM-SNR曲线
figure;
semilogy(snr_range, evm_results, 'o-', 'LineWidth', 2);
xlabel('SNR (dB)');
ylabel('RMS EVM (%)');
title('64QAM调制EVM随SNR变化');
grid on;
legend('64QAM', 'Location', 'best');
% 添加理论参考线
hold on;
theoretical_evm = 100 * sqrt(10.^(-snr_range/10));
semilogy(snr_range, theoretical_evm, 'r--', 'LineWidth', 1.5);
legend('仿真结果', '理论值', 'Location', 'best');
针对该代码请为接收信号制作一个BUSSGANG盲均衡函数,以提升其EVM指标