MATLAB仿真8DPSK信号在AWGN信道下的误码率分析 商品形式:程序 实现功能:MATLAB仿真8DPSK信号在AWGN信道下的误码率与误比特率分析,与理论值进行比较。
首先搞点随机数据当原料。生成二进制序列的时候,我习惯用randi这个老伙计,毕竟生成随机比特它最利索:
bit_len = 1e6; % 百万量级数据才够看趋势
tx_bits = randi([0 1], bit_len, 1);
这里有个小技巧,把比特流按3位一组打包(因为8DPSK每个符号带3个bit),直接上reshape变形大法:
symbol_idx = bi2de(reshape(tx_bits, 3, [])', 'left-msb')';
调制环节用dpskmod函数,重点是把相位偏移设成0,记得打开格雷编码开关。为什么要用格雷码?这货能让相邻符号只错1个bit,误码率能降不少:
M = 8; % 调制阶数
tx_sym = dpskmod(symbol_idx, M, 0, 'gray');
接下来给信号加点料——AWGN噪声。注意这里有个坑:awgn函数默认按信号功率归一化,但实际操作中咱们更关心Eb/N0:
EbN0_dB = 0:2:12; % 信噪比范围
ber_sim = zeros(size(EbN0_dB)); % 误比特率容器
ser_sim = zeros(size(EbN0_dB)); % 误符号率容器
for i = 1:length(EbN0_dB)
% 信噪比转换小课堂
snr = EbN0_dB(i) + 10*log10(log2(M));
rx_sym = awgn(tx_sym, snr, 'measured');
% 解调环节
rx_symbols = dpskdemod(rx_sym, M, 0, 'gray');
rx_bits = de2bi(rx_symbols, 'left-msb');
rx_bits = reshape(rx_bits', [], 1);
% 算误码率,注意除之前先转double防溢出
[~, ser_sim(i)] = symerr(symbol_idx, rx_symbols);
[~, ber_sim(i)] = biterr(tx_bits, rx_bits);
end
理论值计算不能少,用berawgn函数直接调取理论曲线。不过要注意8DPSK的理论BER公式其实长这样:
% 理论误比特率计算公式
EbN0 = 10.^(EbN0_dB/10);
ber_theory = (1/log2(M)) * (1 - 1/sqrt(1 + 3/(log2(M)*EbN0))));
画图对比的时候,建议用对数坐标才能看清低误码率区域:
semilogy(EbN0_dB, ber_sim, 'ro-', 'LineWidth', 2);
hold on;
semilogy(EbN0_dB, ber_theory, 'k--', 'LineWidth', 1.5);
grid on;
xlabel('Eb/N0 (dB)');
ylabel('BER');
legend('仿真值', '理论值');
跑完代码会发现个有趣现象:当Eb/N0大于10dB后,仿真结果和理论曲线几乎重合,但在低信噪比区域会出现偏差。这不是代码有bug,而是因为理论公式做了近似假设,实际仿真中噪声的随机性导致统计波动。
MATLAB仿真8DPSK信号在AWGN信道下的误码率分析 商品形式:程序 实现功能:MATLAB仿真8DPSK信号在AWGN信道下的误码率与误比特率分析,与理论值进行比较。
最后给个实用小技巧:如果发现仿真时间太长,可以试试用parfor并行计算替换for循环,特别是跑大批量数据时能省不少咖啡钱。不过要注意数据分割的方式,别让worker之间抢内存打起来。


1万+

被折叠的 条评论
为什么被折叠?



