MATLAB实现16QAM调制与解调

MATLAB实现16QAM调制与解调,包括串并转换、瑞利多径信道建立和星座映射。

%% 16QAM调制与解调系统仿真
clear all;
close all;
clc;

%% 参数设置
M = 16;                     % 调制阶数(16QAM)
k = log2(M);                % 每个符号的比特数
numBits = 100000;           % 总比特数
sps = 4;                    % 每符号样本数
fs = 1e6;                   % 采样率 (Hz)
fc = 100e3;                 % 载波频率 (Hz)
snr = 20;                   % 信噪比 (dB)
numPaths = 3;               % 多径数量
maxDopplerShift = 30;       % 最大多普勒频移 (Hz)

%% 生成随机比特流
dataIn = randi([0 1], numBits, 1);

%% 串并转换:将串行比特流转换为并行符号
% 将比特流分组,每组k比特
reshapedData = reshape(dataIn, k, length(dataIn)/k).';
% 将二进制转换为十进制符号
dataSymbolsIn = bi2de(reshapedData);

%% 16QAM调制(星座映射)
% 使用MATLAB内置函数进行16QAM调制
txSig = qammod(dataSymbolsIn, M, 'bin', 'InputType', 'integer', 'UnitAveragePower', true);

%% 上采样和脉冲成形
% 创建升余弦滤波器
rolloff = 0.25;             % 滚降因子
span = 10;                  % 滤波器跨度
rrcFilter = rcosdesign(rolloff, span, sps);

% 上采样
txSigUp = upsample(txSig, sps);
% 脉冲成形
txWaveform = filter(rrcFilter, 1, txSigUp);

%% 载波调制(上变频)
t = (0:length(txWaveform)-1)'/fs;
txWaveform = real(txWaveform .* exp(1i*2*pi*fc*t));

%% 创建瑞利多径衰落信道
% 设置多径延迟和增益
pathDelays = [0, 1e-5, 2.2e-5]; % 延迟 (秒)
avgPathGains = [0, -2, -4];      % 平均路径增益 (dB)

% 创建瑞利信道对象
rayleighChan = comm.RayleighChannel(...
    'SampleRate', fs, ...
    'PathDelays', pathDelays(1:min(numPaths, length(pathDelays))), ...
    'AveragePathGains', avgPathGains(1:min(numPaths, length(avgPathGains))), ...
    'MaximumDopplerShift', maxDopplerShift, ...
    'RandomStream', 'mt19937ar with seed', ...
    'Seed', 73, ...
    'PathGainsOutputPort', true);

%% 信号通过瑞利多径信道
[chanOut, pathGains] = rayleighChan(txWaveform);

%% 添加高斯白噪声
rxWaveform = awgn(chanOut, snr, 'measured');

%% 载波解调(下变频)
rxWaveform = rxWaveform .* exp(-1i*2*pi*fc*t);

%% 匹配滤波
rxFiltered = filter(rrcFilter, 1, rxWaveform);

%% 下采样
rxSymbols = downsample(rxFiltered, sps, span*sps/2);

%% 16QAM解调(星座逆映射)
% 移除由于滤波引入的延迟
rxSymbols = rxSymbols(span+1:end);
dataSymbolsOut = qamdemod(rxSymbols, M, 'bin', 'OutputType', 'integer', 'UnitAveragePower', true);

%% 并串转换:将并行符号转换为串行比特流
% 将十进制符号转换为二进制
dataOutMatrix = de2bi(dataSymbolsOut, k);
% 将矩阵转换为向量
dataOut = dataOutMatrix(:);

%% 计算误码率
[numErrors, ber] = biterr(dataIn(1:length(dataOut)), dataOut);
fprintf('误码率 = %e, 错误比特数 = %d\n', ber, numErrors);

%% 可视化结果

% 绘制发送端星座图
figure;
subplot(2,2,1);
plot(real(txSig), imag(txSig), 'o');
title('发送端星座图');
axis([-1.5 1.5 -1.5 1.5]);
grid on;

% 绘制接收端星座图(均衡前)
subplot(2,2,2);
plot(real(rxSymbols), imag(rxSymbols), '.');
title('接收端星座图(均衡前)');
axis([-1.5 1.5 -1.5 1.5]);
grid on;

% 绘制瑞利信道脉冲响应
subplot(2,2,3);
stem(pathDelays, 10.^(avgPathGains/10), 'filled');
title('多径信道增益');
xlabel('延迟 (秒)');
ylabel('增益');
grid on;

% 绘制误码率性能曲线
subplot(2,2,4);
snrRange = 0:2:30;
berArray = zeros(size(snrRange));
for i = 1:length(snrRange)
    % 重新运行仿真以计算不同SNR下的BER
    rxTest = awgn(chanOut, snrRange(i), 'measured');
    rxTest = rxTest .* exp(-1i*2*pi*fc*t);
    rxFilteredTest = filter(rrcFilter, 1, rxTest);
    rxSymbolsTest = downsample(rxFilteredTest, sps, span*sps/2);
    rxSymbolsTest = rxSymbolsTest(span+1:end);
    dataSymbolsOutTest = qamdemod(rxSymbolsTest, M, 'bin', 'OutputType', 'integer', 'UnitAveragePower', true);
    dataOutMatrixTest = de2bi(dataSymbolsOutTest, k);
    dataOutTest = dataOutMatrixTest(:);
    [~, berArray(i)] = biterr(dataIn(1:length(dataOutTest)), dataOutTest);
end
semilogy(snrRange, berArray, 'b-o');
hold on;
% 理论BER曲线
berTheory = berawgn(snrRange, 'qam', M);
semilogy(snrRange, berTheory, 'r--');
title('误码率性能');
xlabel('SNR (dB)');
ylabel('BER');
legend('仿真结果', '理论值');
grid on;

% 绘制眼图
figure;
eyediagram(real(rxFiltered(1:2000)), 2*sps, 2*sps);
title('接收信号眼图');

% 绘制信号功率谱密度
figure;
pwelch(txWaveform, [], [], [], fs, 'centered');
title('发送信号功率谱密度');

1. 系统参数设置

  • 调制方式:16QAM(每个符号携带4比特信息)
  • 比特数:100,000比特
  • 采样率:1MHz
  • 载波频率:100kHz
  • 信噪比:20dB
  • 多径数量:3径
  • 最大多普勒频移:30Hz

2. 主要处理步骤

串并转换

将串行比特流转换为并行符号,每4比特一组(因为16QAM每个符号代表4比特):

reshapedData = reshape(dataIn, k, length(dataIn)/k).';
dataSymbolsIn = bi2de(reshapedData);

16QAM调制(星座映射)

使用MATLAB的qammod函数进行调制:

txSig = qammod(dataSymbolsIn, M, 'bin', 'InputType', 'integer', 'UnitAveragePower', true);

脉冲成形

使用升余弦滤波器进行脉冲成形,以减少码间干扰:

rrcFilter = rcosdesign(rolloff, span, sps);
txSigUp = upsample(txSig, sps);
txWaveform = filter(rrcFilter, 1, txSigUp);

载波调制

将基带信号调制到载波频率上:

txWaveform = real(txWaveform .* exp(1i*2*pi*fc*t));

瑞利多径信道

创建并应用瑞利多径衰落信道:

rayleighChan = comm.RayleighChannel(...
    'SampleRate', fs, ...
    'PathDelays', pathDelays, ...
    'AveragePathGains', avgPathGains, ...
    'MaximumDopplerShift', maxDopplerShift);
[chanOut, pathGains] = rayleighChan(txWaveform);

添加高斯白噪声

使用awgn函数添加高斯白噪声:

rxWaveform = awgn(chanOut, snr, 'measured');

解调过程

包括载波解调、匹配滤波、下采样和16QAM解调:

rxWaveform = rxWaveform .* exp(-1i*2*pi*fc*t);
rxFiltered = filter(rrcFilter, 1, rxWaveform);
rxSymbols = downsample(rxFiltered, sps, span*sps/2);
dataSymbolsOut = qamdemod(rxSymbols, M, 'bin', 'OutputType', 'integer', 'UnitAveragePower', true);

并串转换

将解调后的并行符号转换回串行比特流:

dataOutMatrix = de2bi(dataSymbolsOut, k);
dataOut = dataOutMatrix(:);

参考代码 运用matlab,实现16QAM调制与解调,串并转换,信道建立(瑞利多径信道),星座映射 www.youwenfan.com/contentcnf/50640.html

3. 性能评估与可视化

  • 计算误码率(BER)
  • 绘制发送端和接收端星座图
  • 绘制多径信道增益
  • 绘制误码率性能曲线(仿真结果与理论值对比)
  • 绘制眼图
  • 绘制信号功率谱密度

运行结果分析

运行上述代码后,你将得到:

  1. 星座图:显示发送端和接收端的符号分布,可以直观地看到噪声和多径效应的影响
  2. 误码率:显示系统在当前信噪比下的误码性能
  3. 误码率曲线:显示不同信噪比下的误码率变化,并与理论值进行比较
  4. 眼图:显示信号的时间域特性,可以评估码间干扰的程度
  5. 功率谱密度:显示信号的频率域特性
posted @ 2025-09-05 15:48  晃悠人生  阅读(118)  评论(0)    收藏  举报