二进制数据BER Vs SNR曲线绘制求助:代码生成直线而非瀑布曲线
解决BER随SNR变化曲线为直线的问题
我一眼就看出问题所在了——你的代码完全没有根据不同的SNR(Eb/N0)生成对应的带噪声接收信号,而是直接用固定从Excel读取的接收数据C和发射数据B对比,错误数自然不会随SNR变化,曲线当然是直线啦!
用户当前生成的曲线如下:
具体问题分析
- 核心bug:你的循环
for ii = 1:length(Eb_N0_dB)里,每次计算错误数都是用固定的B - C找差异,完全没有根据当前SNR调整接收信号。不管Eb/N0怎么变,B和C都是静态的Excel数据,错误数肯定一模一样。 - 额外问题:你定义的
N = 10^4和实际读取的B/C维度(130,1)不匹配,会导致BER计算出现偏差。
正确实现逻辑与修改后的代码
要得到随SNR变化的瀑布曲线,需要模拟不同SNR下的带噪声接收信号,再和原始发射数据对比统计错误。以下是调整后的完整代码:
clc clear all close all % 读取原始发射数据(假设B是BPSK调制后的符号,转为列向量) A = 'sample-25-4-18.xlsx'; sheet1 = 1; Range = 'A1:AN140'; B = xlsread(A, sheet1, Range); B = B(:); % 确保维度为(130,1)的列向量 N = length(B); % 用实际数据长度替换原有的10^4,避免不匹配 % 设置你需要的SNR范围:1到30dB,步长1 Eb_N0_dB = 1:1:30; for ii = 1:length(Eb_N0_dB) % 计算当前Eb/N0对应的噪声功率 Eb_N0 = 10^(Eb_N0_dB(ii)/10); signal_power = var(B); % 发射信号功率用方差表示 noise_power = signal_power / Eb_N0; % 给发射信号添加高斯白噪声,模拟不同SNR下的接收信号 received_signal = B + sqrt(noise_power)*randn(size(B)); % BPSK判决逻辑:假设原始信号为±1,大于0判为1,小于0判为-1 decoded_signal = sign(received_signal); decoded_signal(decoded_signal == 0) = 1; % 处理信号刚好为0的特殊情况 % 统计错误数 nErr(ii) = sum(decoded_signal ~= B); end simBer = nErr/N; % 计算仿真BER theoryBer = 0.5*erfc(sqrt(10.^(Eb_N0_dB/10))); % BPSK理论BER公式 % 绘制曲线 figure semilogy(Eb_N0_dB, theoryBer, 'b.-', 'LineWidth',1.2); hold on semilogy(Eb_N0_dB, simBer, 'r*', 'MarkerSize',8); axis([min(Eb_N0_dB) max(Eb_N0_dB) 1e-5 1]) grid on legend('理论BER', '仿真BER'); xlabel('Eb/No (dB)'); ylabel('误码率 (BER)'); title('BPSK调制的误码率曲线');
额外注意事项
- 如果你Excel中的
C是实际采集的接收数据,那这种模拟SNR的场景不适用。你需要明确:是要模拟不同SNR下的BER,还是要分析实际采集数据的BER(后者需要对应每个SNR的采集数据,而非固定的C)。 - 确保判决逻辑和你的调制方式匹配:如果原始发射数据是0/1比特,需要先转为±1再添加噪声,判决后再转回0/1统计错误。
- 数据量较小时(比如130个符号),仿真BER可能会有较大波动,建议增加数据长度以获得更平滑的曲线。
内容的提问来源于stack exchange,提问作者Roshni191




