Matlab实现2PSK调制及误码率仿真
Matlab实现2PSK调制及误码率仿真
本文提供了一份Matlab代码,用于实现2PSK调制并进行误码率仿真。
代码说明
代码主要包含以下几个部分:
- 参数设置: 包括载波振幅、载波频率、信噪比范围、每个码元的采样点数、码元数、码元宽度等。2. 理论误码率计算: 根据信噪比计算理论误码率。3. 2PSK调制与解调: 对随机生成的双极性二进制码元进行2PSK调制,并加入高斯白噪声模拟信道传输。在接收端,进行解调和判决。4. 误码率统计: 统计仿真得到的误码率。5. 结果绘图: 将理论误码率和仿真得到的误码率绘制在同一张图中,方便对比。
Matlab代码matlabclear allclose all
A = 1; % 载波振幅fc = 2; % 载波频率(Hz)SNRindB1 = -5:1:12; % SNR取值范围SNRindB2 = -5:0.2:12; % SNR取值范围N_sample = 100; % 每个码元的采样点数N = 10000; % 码元数Ts = 1; % 码元宽度d = sign(rand(1, N) - 0.5 + eps); % 产生双极性二进制码元df = 0.01;simu_err_prb = zeros(1, length(SNRindB1));
% 理论误码率theo_err_prb = zeros(1, length(SNRindB2));theo_err_prb1 = zeros(1, length(SNRindB2));for i = 1:length(SNRindB2) SNR = 10^(SNRindB2(i)/10); theo_err_prb(i) = 0.5 * erfc(sqrt(SNR)); theo_err_prb1(i) = 0.5 * erfc(sqrt(2 * SNR));end
% 普通2PSK接收机实际误码率for i = 1:length(SNRindB1) [numoferr, panjue, desingal, t] = bpskberr(A, fc, SNRindB1(i), N_sample, N, Ts, d, df); simu_err_prb(i) = numoferr;end
% 画误码率曲线图semilogy(SNRindB2, theo_err_prb, SNRindB1, simu_err_prb, 'o', SNRindB2, theo_err_prb1, '*');axis([-5 12 0.00000001 1]);xlabel('SNR in dB');ylabel('Prb of Err');legend('蒙特卡洛仿真误码率', '2psk接收机实际误码率', '最佳接收机理论误码率');
% 2psk误码率计算子程序function [numoferr, panjue, desingal, t] = bpskberr(A, fc, snr, N_sample, N, Ts, d, df) % 求误码率 % -------------------系统仿真参数 % A; %载波振幅 % fc; %载波频率(Hz) % snr; % % N_sample;% % N; % 码元数 % Ts; % 码元宽度 % d;输入二进制代码 % df:频率分辨率 % -------------------输出(返回)参数 % numoferr;%误码率 % panjue 恢复的二进制代码1用1表示,0用-1表示 % desingal;%恢复的数字基带信号 % t;时域采样时序 % ----------------------生成调制信号 B = 1 / Ts; f_start = fc - B; f_cutoff = fc + B; fs = fc * N_sample; ts = Ts / fs; t = 0:ts:N * Ts - ts; Lt = length(t);
% 产生二进制信源 dd = sigexpand((d + 1) / 2, fc * N_sample); gt = ones(1, fc * N_sample); d_NRZ = conv(dd, gt); d_sjx = 2 * d_NRZ - 1;
% 对数字基带信号进行2PSK调制 ht = A * sin(2 * pi * fc * t); s_2psk = d_sjx(1:Lt) .* ht;
% 生成高斯白噪声噪声 snr_lin = 10^(snr / 10); signal_energy = 0.5 * A^2 * Ts; noise_power = (signal_energy * fs) / (snr_lin * 4); noise_std = sqrt(noise_power); noise = noise_std * randn(1, Lt);
% 将已调信号送入信道 r = s_2psk(1:Lt) + noise(1:Lt); [rf, r, df1, f] = fft_func(r, ts, fs);
% 在接收端先通过带通滤波器 [H, f] = bp_f(length(rf), f_start, f_cutoff, df1, fs, 1); DEM = H .* rf; [dem] = ifft_func(DEM, fs); der = dem(1:Lt) .* ht; [derf, der, df1, f] = fft_func(der, ts, fs);
% 再经过低通滤波器 [LPF, f] = lp_f(length(derf), B, df1, fs, 1); DM = LPF .* derf; [dm] = ifft_func(DM, fs);
% 最后对LPF输出信号抽样判决 panjue = zeros(1, N); for i = 1:N if dm(fc * N_sample * (i - 1) + fc * N_sample / 2 + 1) >= 0 panjue(i) = 1; else panjue(i) = -1; end end
% 生成判决出的基带信号波形 dd1 = sigexpand(panjue, fc * N_sample); gt1 = ones(1, fc * N_sample); desinga = conv(dd1, gt1); desingal = desinga(1:Lt);
% 统计误码数 numoferr = sum(abs(panjue - d) / 2) / N;end
% 快速傅里叶变换function [output, f] = fft_func(signal, ts, fs) N = length(signal); f = (-fs/2) : (fs/N) : (fs/2 - fs/N); output = fftshift(fft(signal)) * ts;end
% 快速逆傅里叶变换function [output] = ifft_func(signal, fs) N = length(signal); output = ifft(ifftshift(signal)) * N / fs;end
% 带通滤波器函数function [output, f] = bp_f(N, f_start, f_cutoff, df, fs, delay) f = f_start:df:f_cutoff; output = zeros(1, N); output(f >= f_start & f <= f_cutoff) = 1;end
% 低通滤波器函数function [output, f] = lp_f(N, B, df, fs, delay) f = -fs/2:df:fs/2-df; output = zeros(1, N); output(abs(f) <= B/2) = 1;end
% 信号扩展函数function [output] = sigexpand(signal, factor) output = repelem(signal, factor);end
总结
本文提供的Matlab代码可以帮助您理解2PSK调制原理,并进行误码率仿真。您可以根据需要修改代码参数,进行更深入的研究。
原文地址: https://www.cveoy.top/t/topic/p3p 著作权归作者所有。请勿转载和采集!