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)
- 绘制发送端和接收端星座图
- 绘制多径信道增益
- 绘制误码率性能曲线(仿真结果与理论值对比)
- 绘制眼图
- 绘制信号功率谱密度
运行结果分析
运行上述代码后,你将得到:
- 星座图:显示发送端和接收端的符号分布,可以直观地看到噪声和多径效应的影响
- 误码率:显示系统在当前信噪比下的误码性能
- 误码率曲线:显示不同信噪比下的误码率变化,并与理论值进行比较
- 眼图:显示信号的时间域特性,可以评估码间干扰的程度
- 功率谱密度:显示信号的频率域特性
浙公网安备 33010602011771号