MATLAB中16-QAM调制解调仿真BER与理论值不符问题求助
嘿,我看了你的代码,发现几个关键问题导致实验BER远差于理论值,而且刚好4-QAM时没触发这些bug,所以表现正常。下面逐一拆解并修复:
1. 解调与调制的功率归一化参数不匹配
你用qammod时加了'UnitAveragePower',true,把16-QAM星座图缩放到平均功率为1,但qamdemod默认用的是标准星座(平均功率不是1),两者的星座点位置完全对不上,判决阈值自然错得离谱,误码率不高才怪!
修复:给qamdemod也加上相同的参数:
e = qamdemod(d,16,'UnitAveragePower',true);
2. 数值转二进制的逻辑彻底错了
你在把解调后的0-15数值转回4比特时,减法逻辑完全不对。比如数值是5,你先取最高位floor(5/8)=0,然后直接temp=5-8=-3,接下来floor(-3/4)=-1,这直接得到了负数的比特位,完全不符合二进制的要求!
正确的转换逻辑应该是每次提取比特后,用数值减去「该比特值×对应权重」,而不是直接减固定的8/4/2:
for j=1:length(k) for i=1:250000 temp = e(j,i); % 提取最高位(8的权重) f(j,4*i-3) = floor(temp/8); temp = temp - f(j,4*i-3)*8; % 提取次高位(4的权重) f(j,4*i-2) = floor(temp/4); temp = temp - f(j,4*i-2)*4; % 提取第三位(2的权重) f(j,4*i-1) = floor(temp/2); temp = temp - f(j,4*i-1)*2; % 最低位就是剩下的数值 f(j,4*i) = temp; end end
或者更省心的方式用Matlab自带的de2bi函数,避免手动计算出错:
for j=1:length(k) % 设置'left-msb'让最高位在前,刚好匹配你的分组顺序 temp_bits = de2bi(e(j,:),4,'left-msb'); f(j,:) = reshape(temp_bits',1,[]); end
3. 理论BER公式误用了dB值
你定义的k是0-20的dB值,但理论公式里需要的是线性SNR(功率比),直接代入dB值会导致理论曲线完全偏离实际。
修复:先把dB值转成线性SNR再计算:
M = 16; for i=1:length(k) snr_linear = 10^(k(i)/10); % dB转线性SNR t(1,i) = 1-(1-2*sqrt(M-1)/sqrt(M)*qfunc(sqrt(3*snr_linear/(M-1)))).^2; end
额外优化:BER计算更高效
原来的双层循环计算BER效率很低,用sum函数可以一步搞定:
r(i) = sum(a ~= f(i,:)) / length(a);
完整修复后的代码
整合所有修复点后的代码如下,运行后实验BER应该会和理论曲线贴合得很好:
clear all clc a = randi([0 1], 1, 1000000);%random binary array b = zeros(1,250000); for i=1:250000%4-bits grouped into one b(i) = 8*a(4*i-3) + 4*a(4*i-2) + 2*a(4*i-1) + a(4*i); end c = qammod(b,16,'UnitAveragePower',true);%16-QAM modulation k = 0:20;%SNR in dB d = zeros(length(k),250000); for i=1:length(k) d(i,1:250000) = awgn(c,k(i),'measured');%noise is added for different SNR values end % 匹配解调参数 e = qamdemod(d,16,'UnitAveragePower',true);%demodulation of 16-QAM f = zeros(length(k),1000000); % 用de2bi简化二进制转换 for j=1:length(k) temp_bits = de2bi(e(j,:),4,'left-msb'); f(j,:) = reshape(temp_bits',1,[]); end r = zeros(1,length(k));%BER is calculated for i=1:length(k) r(i) = sum(a ~= f(i,:)) / length(a); end t = zeros(1,length(k));%Theoritical result for BER is calculated M = 16; for i=1:length(k) snr_linear = 10^(k(i)/10); t(1,i) = 1-(1-2*sqrt(M-1)/sqrt(M)*qfunc(sqrt(3*snr_linear/(M-1)))).^2; end plot(k,t,'b-','LineWidth',1.5) hold on plot(k,r,'ro','MarkerSize',6) xlabel('SNR (dB)') ylabel('Bit Error Rate (BER)') legend('Theory','Simulation') grid on hold off
为什么4-QAM时没问题?
大概率是你测试4-QAM时,二进制转换的逻辑是对的(比如2比特分组时用floor(temp/2)和rem(temp,2),不会出现减法错误),而且4-QAM的星座图对功率归一化的敏感度更低,即使解调参数不匹配,误码率的提升没16-QAM这么夸张,所以没暴露问题。
内容的提问来源于stack exchange,提问作者user6210457

