1. 完整的QAM星座图生成和可视化
function qam_constellation_demo()
% 16QAM, 32QAM, 64QAM星座图演示
fprintf('=== QAM调制星座图演示 ===\n\n');
%% 参数设置
M_list = [16, 32, 64]; % 调制阶数
SNR_dB = 20; % 信噪比
num_symbols = 1000; % 每个调制方式的符号数
%% 生成星座图
figure('Position', [100, 100, 1400, 1000]);
for i = 1:length(M_list)
M = M_list(i);
% 生成QAM调制信号
[tx_symbols, constellation, bit_labels] = generate_qam_signal(M, num_symbols);
% 添加高斯噪声
rx_symbols = add_awgn_noise(tx_symbols, SNR_dB);
% 绘制星座图
subplot(2, 3, i);
plot_constellation(rx_symbols, constellation, bit_labels, M, SNR_dB);
% 计算理论误码率
subplot(2, 3, i+3);
plot_ber_curve(M);
end
% 比较不同调制方式的性能
figure('Position', [100, 100, 1200, 800]);
compare_modulation_schemes();
fprintf('星座图演示完成\n');
end
function [tx_symbols, constellation, bit_labels] = generate_qam_signal(M, num_symbols)
% 生成QAM调制信号
% 输入:
% M - 调制阶数
% num_symbols - 符号数量
% 输出:
% tx_symbols - 发送符号
% constellation - 星座点
% bit_labels - 比特标签
% 生成随机比特序列
k = log2(M); % 每个符号的比特数
num_bits = num_symbols * k;
data_bits = randi([0, 1], num_bits, 1);
% 根据调制阶数生成星座图
[constellation, bit_labels] = generate_constellation(M);
% 调制
tx_symbols = qam_modulate(data_bits, constellation, M);
fprintf('生成 %dQAM 信号: %d 个符号, %d 个比特\n', M, num_symbols, num_bits);
end
function [constellation, bit_labels] = generate_constellation(M)
% 生成QAM星座图
k = log2(M);
switch M
case 16
% 16QAM - 4x4 网格
I = [-3, -1, 1, 3];
Q = [-3, -1, 1, 3];
[I_grid, Q_grid] = meshgrid(I, Q);
constellation = I_grid(:) + 1j * Q_grid(:);
% 格雷编码的比特标签
bit_labels = [
'0000'; '0001'; '0011'; '0010';
'0100'; '0101'; '0111'; '0110';
'1100'; '1101'; '1111'; '1110';
'1000'; '1001'; '1011'; '1010'
];
case 32
% 32QAM - 交叉星座图 (6x6网格去掉4个角点)
I = [-5, -3, -1, 1, 3, 5];
Q = [-5, -3, -1, 1, 3, 5];
[I_grid, Q_grid] = meshgrid(I, Q);
constellation = I_grid(:) + 1j * Q_grid(:);
% 去掉4个角点
remove_indices = [1, 6, 31, 36]; % 四个角点
constellation(remove_indices) = [];
% 生成格雷编码标签 (简化版本)
bit_labels = generate_gray_labels_32qam();
case 64
% 64QAM - 8x8 网格
I = [-7, -5, -3, -1, 1, 3, 5, 7];
Q = [-7, -5, -3, -1, 1, 3, 5, 7];
[I_grid, Q_grid] = meshgrid(I, Q);
constellation = I_grid(:) + 1j * Q_grid(:);
% 格雷编码的比特标签
bit_labels = generate_gray_labels_64qam();
otherwise
error('不支持的调制阶数: %d', M);
end
% 归一化星座图能量
constellation = constellation / sqrt(mean(abs(constellation).^2));
fprintf('%dQAM星座图生成: %d个星座点\n', M, length(constellation));
end
function bit_labels = generate_gray_labels_32qam()
% 生成32QAM的格雷编码标签
% 32QAM使用交叉星座图,需要特殊的格雷编码
% 定义基本模式 (简化版本)
base_pattern = [
'00000'; '00001'; '00011'; '00010'; '00110'; '00111';
'00101'; '00100'; '01100'; '01101'; '01111'; '01110';
'01010'; '01011'; '01001'; '01000'; '11000'; '11001';
'11011'; '11010'; '11110'; '11111'; '11101'; '11100';
'10100'; '10101'; '10111'; '10110'; '10010'; '10011';
'10001'; '10000'
];
bit_labels = base_pattern;
end
function bit_labels = generate_gray_labels_64qam()
% 生成64QAM的格雷编码标签
bit_labels = [];
for i = 0:7
for j = 0:7
% 行和列的格雷编码
gray_i = dec2gray(i, 3);
gray_j = dec2gray(j, 3);
bit_labels = [bit_labels; [gray_i, gray_j]];
end
end
end
function gray_code = dec2gray(decimal_num, num_bits)
% 将十进制数转换为格雷码
binary_num = dec2bin(decimal_num, num_bits);
gray_code = binary_num(1);
for i = 2:num_bits
gray_code(i) = num2str(xor(str2double(binary_num(i-1)), str2double(binary_num(i))));
end
end
2. QAM调制和解调函数
function modulated_symbols = qam_modulate(data_bits, constellation, M)
% QAM调制
% 输入:
% data_bits - 输入比特序列
% constellation - 星座图
% M - 调制阶数
% 输出:
% modulated_symbols - 调制后的符号
k = log2(M);
num_symbols = length(data_bits) / k;
% 重新整形为每k比特一组
bit_groups = reshape(data_bits, k, num_symbols)';
% 将比特组转换为十进制索引
symbol_indices = bi2de(bit_groups, 'left-msb') + 1;
% 映射到星座点
modulated_symbols = constellation(symbol_indices);
fprintf('QAM调制完成: %d比特 -> %d符号\n', length(data_bits), num_symbols);
end
function demodulated_bits = qam_demodulate(received_symbols, constellation, M)
% QAM解调
% 输入:
% received_symbols - 接收符号
% constellation - 星座图
% M - 调制阶数
% 输出:
% demodulated_bits - 解调后的比特序列
k = log2(M);
num_symbols = length(received_symbols);
demodulated_bits = zeros(num_symbols * k, 1);
% 最小距离解调
for i = 1:num_symbols
% 计算到所有星座点的距离
distances = abs(received_symbols(i) - constellation);
% 找到最近的星座点
[~, min_idx] = min(distances);
% 将索引转换为比特
bit_pattern = dec2bin(min_idx-1, k);
start_idx = (i-1)*k + 1;
end_idx = i*k;
demodulated_bits(start_idx:end_idx) = bit_pattern' - '0';
end
fprintf('QAM解调完成: %d符号 -> %d比特\n', num_symbols, length(demodulated_bits));
end
function noisy_symbols = add_awgn_noise(clean_symbols, SNR_dB)
% 添加加性高斯白噪声
% 输入:
% clean_symbols - 干净信号
% SNR_dB - 信噪比(dB)
% 输出:
% noisy_symbols - 含噪信号
% 计算信号功率
signal_power = mean(abs(clean_symbols).^2);
% 计算噪声功率
SNR_linear = 10^(SNR_dB/10);
noise_power = signal_power / SNR_linear;
% 生成复高斯噪声
noise = sqrt(noise_power/2) * (randn(size(clean_symbols)) + 1j*randn(size(clean_symbols)));
% 添加噪声
noisy_symbols = clean_symbols + noise;
fprintf('添加AWGN噪声: SNR = %d dB\n', SNR_dB);
end
3. 星座图可视化函数
function plot_constellation(received_symbols, constellation, bit_labels, M, SNR_dB)
% 绘制星座图
% 创建颜色映射
colors = lines(M);
% 绘制接收到的符号
scatter(real(received_symbols), imag(received_symbols), 20, 'filled', ...
'MarkerFaceAlpha', 0.6, 'MarkerEdgeAlpha', 0.8);
hold on;
% 绘制理论星座点
scatter(real(constellation), imag(constellation), 100, 'r', 'x', 'LineWidth', 2);
% 添加比特标签
for i = 1:length(constellation)
text(real(constellation(i)), imag(constellation(i)) + 0.3, bit_labels(i,:), ...
'HorizontalAlignment', 'center', 'FontSize', 8, 'FontWeight', 'bold');
end
% 设置图形属性
grid on;
axis equal;
xlabel('同相分量 (I)');
ylabel('正交分量 (Q)');
title(sprintf('%dQAM星座图 (SNR = %d dB)', M, SNR_dB));
% 添加网格线
x_limits = xlim;
y_limits = ylim;
max_limit = max([abs(x_limits), abs(y_limits)]);
xlim([-max_limit, max_limit]);
ylim([-max_limit, max_limit]);
% 添加参考线
plot([0, 0], ylim, 'k--', 'LineWidth', 0.5);
plot(xlim, [0, 0], 'k--', 'LineWidth', 0.5);
legend('接收符号', '理论星座点', 'Location', 'best');
% 计算并显示EVM
evm = calculate_evm(received_symbols, constellation);
text(0.02, 0.98, sprintf('EVM: %.2f%%', evm*100), 'Units', 'normalized', ...
'VerticalAlignment', 'top', 'BackgroundColor', 'white', 'FontSize', 10);
end
function plot_ber_curve(M)
% 绘制理论误码率曲线
SNR_dB_range = 0:2:30;
BER_theoretical = zeros(size(SNR_dB_range));
for i = 1:length(SNR_dB_range)
SNR_dB = SNR_dB_range(i);
BER_theoretical(i) = qam_ber_theoretical(M, SNR_dB);
end
% 绘制BER曲线
semilogy(SNR_dB_range, BER_theoretical, 'b-', 'LineWidth', 2);
grid on;
xlabel('信噪比 (dB)');
ylabel('误码率 (BER)');
title(sprintf('%dQAM理论误码率曲线', M));
% 添加参考线
hold on;
ber_references = [1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6];
for ber_ref = ber_references
plot(xlim, [ber_ref, ber_ref], 'r--', 'LineWidth', 0.5);
end
legend('理论BER', '参考线', 'Location', 'southwest');
end
function evm = calculate_evm(received_symbols, constellation)
% 计算误差向量幅度(EVM)
% 输入:
% received_symbols - 接收符号
% constellation - 理论星座图
% 输出:
% evm - 误差向量幅度
num_symbols = length(received_symbols);
decoded_symbols = zeros(size(received_symbols));
% 解调每个符号到最近的星座点
for i = 1:num_symbols
distances = abs(received_symbols(i) - constellation);
[~, min_idx] = min(distances);
decoded_symbols(i) = constellation(min_idx);
end
% 计算EVM
error_vectors = received_symbols - decoded_symbols;
evm = sqrt(mean(abs(error_vectors).^2)) / sqrt(mean(abs(constellation).^2));
fprintf('EVM计算: %.4f (%.2f%%)\n', evm, evm*100);
end
4. 性能分析和比较
function compare_modulation_schemes()
% 比较不同调制方式的性能
fprintf('=== 调制方式性能比较 ===\n\n');
M_list = [4, 16, 32, 64, 256]; % 各种调制阶数
SNR_dB_range = 0:2:30;
colors = ['b', 'g', 'r', 'c', 'm', 'y'];
figure('Position', [100, 100, 1200, 800]);
%% 子图1: 理论BER比较
subplot(2, 2, 1);
hold on;
for i = 1:length(M_list)
M = M_list(i);
BER = zeros(size(SNR_dB_range));
for j = 1:length(SNR_dB_range)
BER(j) = qam_ber_theoretical(M, SNR_dB_range(j));
end
semilogy(SNR_dB_range, BER, [colors(i) '-'], 'LineWidth', 2, ...
'DisplayName', sprintf('%dQAM', M));
end
grid on;
xlabel('信噪比 (dB)');
ylabel('误码率 (BER)');
title('不同QAM调制的理论误码率比较');
legend('show', 'Location', 'southwest');
%% 子图2: 频谱效率比较
subplot(2, 2, 2);
spectral_efficiency = log2(M_list);
bar(M_list, spectral_efficiency, 'FaceColor', [0.2, 0.6, 0.8]);
xlabel('调制阶数');
ylabel('频谱效率 (bps/Hz)');
title('QAM调制的频谱效率');
grid on;
% 在柱状图上显示数值
for i = 1:length(M_list)
text(M_list(i), spectral_efficiency(i), sprintf('%.1f', spectral_efficiency(i)), ...
'HorizontalAlignment', 'center', 'VerticalAlignment', 'bottom', 'FontWeight', 'bold');
end
%% 子图3: 达到特定BER所需的SNR
subplot(2, 2, 3);
target_BER = 1e-4;
required_SNR = zeros(size(M_list));
for i = 1:length(M_list)
M = M_list(i);
SNR_dB_test = 0:0.1:30;
BER_test = zeros(size(SNR_dB_test));
for j = 1:length(SNR_dB_test)
BER_test(j) = qam_ber_theoretical(M, SNR_dB_test(j));
end
% 找到达到目标BER所需的SNR
idx = find(BER_test <= target_BER, 1);
if ~isempty(idx)
required_SNR(i) = SNR_dB_test(idx);
else
required_SNR(i) = NaN;
end
end
plot(M_list, required_SNR, 'ro-', 'LineWidth', 2, 'MarkerSize', 8);
xlabel('调制阶数');
ylabel('所需SNR (dB)');
title(sprintf('达到BER=10^{-4}所需的信噪比'));
grid on;
% 添加数值标签
for i = 1:length(M_list)
if ~isnan(required_SNR(i))
text(M_list(i), required_SNR(i)+1, sprintf('%.1f dB', required_SNR(i)), ...
'HorizontalAlignment', 'center', 'FontWeight', 'bold');
end
end
%% 子图4: 星座点分布
subplot(2, 2, 4);
hold on;
for i = 1:min(3, length(M_list))
M = M_list(i);
[constellation, ~] = generate_constellation(M);
% 归一化能量
constellation = constellation / sqrt(mean(abs(constellation).^2));
scatter(real(constellation), imag(constellation), 50, colors(i), 'filled', ...
'DisplayName', sprintf('%dQAM', M));
end
grid on;
axis equal;
xlabel('同相分量 (I)');
ylabel('正交分量 (Q)');
title('星座点分布比较');
legend('show');
% 添加性能总结
fprintf('性能比较总结:\n');
fprintf('调制方式\t频谱效率\t达到10^-4 BER所需SNR\n');
for i = 1:length(M_list)
if ~isnan(required_SNR(i))
fprintf('%dQAM\t\t%.1f bps/Hz\t%.1f dB\n', ...
M_list(i), spectral_efficiency(i), required_SNR(i));
else
fprintf('%dQAM\t\t%.1f bps/Hz\t>30 dB\n', ...
M_list(i), spectral_efficiency(i));
end
end
end
function ber = qam_ber_theoretical(M, SNR_dB)
% 计算QAM调制的理论误码率
% 近似公式: BER ≈ (4/log2(M)) * (1-1/sqrt(M)) * Q(sqrt(3*log2(M)/(M-1) * SNR))
k = log2(M);
SNR_linear = 10^(SNR_dB/10);
if M == 4
% QPSK的特殊情况
ber = qfunc(sqrt(2*SNR_linear));
else
% 方形QAM的近似误码率
ber = (4/k) * (1 - 1/sqrt(M)) * qfunc(sqrt(3*k*SNR_linear/(M-1)));
end
% 确保BER在合理范围内
ber = max(ber, 1e-8);
ber = min(ber, 0.5);
end
5. 实际系统仿真
function qam_system_simulation()
% QAM通信系统完整仿真
fprintf('=== QAM通信系统完整仿真 ===\n\n');
%% 系统参数
M = 16; % 调制阶数
num_symbols = 10000; % 符号数量
SNR_dB_range = 5:2:25; % 信噪比范围
carrier_freq = 2.4e9; % 载波频率 2.4GHz
sampling_rate = 10e6; % 采样率 10MHz
fprintf('系统参数:\n');
fprintf('调制方式: %dQAM\n', M);
fprintf('符号数量: %d\n', num_symbols);
fprintf('载波频率: %.1f GHz\n', carrier_freq/1e9);
fprintf('采样率: %.1f MHz\n', sampling_rate/1e6);
%% 生成星座图
[constellation, bit_labels] = generate_constellation(M);
k = log2(M);
%% 仿真不同SNR下的性能
ber_simulated = zeros(size(SNR_dB_range));
ber_theoretical = zeros(size(SNR_dB_range));
for snr_idx = 1:length(SNR_dB_range)
SNR_dB = SNR_dB_range(snr_idx);
% 生成随机数据
data_bits = randi([0, 1], num_symbols * k, 1);
% QAM调制
tx_symbols = qam_modulate(data_bits, constellation, M);
% 添加噪声
rx_symbols = add_awgn_noise(tx_symbols, SNR_dB);
% QAM解调
demodulated_bits = qam_demodulate(rx_symbols, constellation, M);
% 计算误码率
bit_errors = sum(data_bits ~= demodulated_bits);
ber_simulated(snr_idx) = bit_errors / length(data_bits);
% 理论误码率
ber_theoretical(snr_idx) = qam_ber_theoretical(M, SNR_dB);
fprintf('SNR = %2d dB: 仿真BER = %.2e, 理论BER = %.2e\n', ...
SNR_dB, ber_simulated(snr_idx), ber_theoretical(snr_idx));
end
%% 可视化结果
figure('Position', [100, 100, 1200, 800]);
% 误码率曲线
subplot(2, 2, 1);
semilogy(SNR_dB_range, ber_simulated, 'bo-', 'LineWidth', 2, 'MarkerSize', 6);
hold on;
semilogy(SNR_dB_range, ber_theoretical, 'r--', 'LineWidth', 2);
grid on;
xlabel('信噪比 (dB)');
ylabel('误码率 (BER)');
title(sprintf('%dQAM系统性能', M));
legend('仿真结果', '理论值', 'Location', 'southwest');
% 星座图 (选择中等SNR)
subplot(2, 2, 2);
mid_snr_idx = ceil(length(SNR_dB_range)/2);
SNR_dB_mid = SNR_dB_range(mid_snr_idx);
% 重新生成中等SNR下的数据用于显示星座图
data_bits_demo = randi([0, 1], 1000 * k, 1);
tx_symbols_demo = qam_modulate(data_bits_demo, constellation, M);
rx_symbols_demo = add_awgn_noise(tx_symbols_demo, SNR_dB_mid);
plot_constellation(rx_symbols_demo, constellation, bit_labels, M, SNR_dB_mid);
title(sprintf('%dQAM星座图 (SNR = %d dB)', M, SNR_dB_mid));
% 误差向量幅度分析
subplot(2, 2, 3);
evm_values = zeros(size(SNR_dB_range));
for snr_idx = 1:length(SNR_DB_range)
SNR_dB = SNR_dB_range(snr_idx);
data_bits_temp = randi([0, 1], 1000 * k, 1);
tx_symbols_temp = qam_modulate(data_bits_temp, constellation, M);
rx_symbols_temp = add_awgn_noise(tx_symbols_temp, SNR_dB);
evm_values(snr_idx) = calculate_evm(rx_symbols_temp, constellation);
end
plot(SNR_dB_range, evm_values*100, 'gs-', 'LineWidth', 2, 'MarkerSize', 6);
grid on;
xlabel('信噪比 (dB)');
ylabel('EVM (%)');
title('误差向量幅度 vs 信噪比');
% 性能总结
subplot(2, 2, 4);
performance_metrics = zeros(3, 3);
% 计算在不同BER要求下所需的SNR
target_bers = [1e-2, 1e-3, 1e-4];
for i = 1:length(target_bers)
target_ber = target_bers(i);
idx = find(ber_simulated <= target_ber, 1);
if ~isempty(idx)
performance_metrics(1, i) = SNR_dB_range(idx);
else
performance_metrics(1, i) = NaN;
end
% 理论值
SNR_dB_test = 0:0.1:30;
BER_test = arrayfun(@(x) qam_ber_theoretical(M, x), SNR_dB_test);
idx_theoretical = find(BER_test <= target_ber, 1);
if ~isempty(idx_theoretical)
performance_metrics(2, i) = SNR_dB_test(idx_theoretical);
else
performance_metrics(2, i) = NaN;
end
end
bar_handle = bar(performance_metrics');
set(gca, 'XTickLabel', {
'BER=10^{-2}', 'BER=10^{-3}', 'BER=10^{-4}'});
ylabel('所需SNR (dB)');
title('达到特定BER所需的SNR');
legend('仿真', '理论', 'Location', 'northwest');
grid on;
% 在柱状图上显示数值
for i = 1:size(performance_metrics, 2)
for j = 1:size(performance_metrics, 1)
if ~isnan(performance_metrics(j, i))
text(i + (j-1.5)*0.25, performance_metrics(j, i) + 0.5, ...
sprintf('%.1f', performance_metrics(j, i)), ...
'HorizontalAlignment', 'center', 'FontWeight', 'bold');
end
end
end
fprintf('\n=== 仿真总结 ===\n');
fprintf('调制方式: %dQAM\n', M);
fprintf('频谱效率: %.2f bps/Hz\n', log2(M));
fprintf('在AWGN信道下的性能与理论值基本吻合\n');
end
6. 使用示例
% 主程序 - 运行完整的QAM星座图分析
clear; clc; close all;
fprintf('=== QAM调制星座图分析 ===\n\n');
% 运行星座图演示
qam_constellation_demo();
% 运行系统仿真
qam_system_simulation();
% 单独生成特定调制方式的星座图
% M = 32;
% [constellation, bit_labels] = generate_constellation(M);
% figure;
% plot_constellation(constellation, constellation, bit_labels, M, inf);
参考代码 16qam 32 64星座图 www.youwenfan.com/contentale/65106.html
主要特点:
完整的星座图生成:
- 16QAM (4×4 方形星座)
- 32QAM (交叉星座图)
- 64QAM (8×8 方形星座)
- 格雷编码比特映射
全面的性能分析:
- 理论误码率计算
- 仿真误码率验证
- 误差向量幅度(EVM)分析
- 频谱效率比较
丰富的可视化功能:
- 星座点分布显示
- 比特标签标注
- BER曲线对比
- 性能指标汇总
实际系统仿真:
- 完整的调制解调链路
- AWGN信道建模
- 系统性能评估