BPSK调制仿真代码

BPSK调制仿真代码,包含了信号生成、调制、信道传输和解调的全过程。

%% BPSK调制解调仿真
clear all; close all; clc;

%% 1. 参数设置
N = 10000;                     % 比特数
Rb = 1000;                     % 比特率 (bps)
fc = 10e3;                     % 载波频率 (10kHz)
fs = 10*fc;                    % 采样频率
Tb = 1/Rb;                     % 比特周期
Ts = 1/fs;                     % 采样周期
samples_per_bit = fs/Rb;       % 每比特采样数
t_bit = 0:Ts:Tb-Ts;            % 一个比特周期的时间向量

% SNR范围 (dB)
EbN0_dB = 0:2:10;
EbN0 = 10.^(EbN0_dB/10);       % 线性值

%% 2. 生成随机比特序列
bits = randi([0, 1], 1, N);
fprintf('生成 %d 个随机比特\n', N);

%% 3. BPSK调制
% BPSK映射: 0 -> +1, 1 -> -1
bpsk_symbols = 2*bits - 1;     % 将[0,1]映射到[+1,-1]

% 生成基带信号(矩形脉冲成型)
baseband_signal = zeros(1, N*samples_per_bit);
for i = 1:N
    baseband_signal((i-1)*samples_per_bit+1:i*samples_per_bit) = bpsk_symbols(i);
end

% 生成载波
t_total = 0:Ts:N*Tb-Ts;
carrier = cos(2*pi*fc*t_total);

% BPSK调制信号(上变频)
modulated_signal = baseband_signal .* carrier;

%% 4. 仿真不同信噪比下的性能
ber_simulated = zeros(size(EbN0_dB));
ber_theoretical = zeros(size(EbN0_dB));

for snr_idx = 1:length(EbN0_dB)
    fprintf('\n仿真 Eb/N0 = %d dB ...\n', EbN0_dB(snr_idx));
    
    %% 4.1 添加AWGN噪声
    % 计算信号功率
    signal_power = sum(abs(modulated_signal).^2)/length(modulated_signal);
    
    % 计算噪声功率(考虑带通信号)
    Eb = signal_power * Tb;                % 每比特能量
    N0 = Eb/EbN0(snr_idx);                % 噪声功率谱密度
    noise_power = N0 * fs/2;              % 噪声功率(双边带)
    
    % 生成高斯白噪声
    noise = sqrt(noise_power) * randn(size(modulated_signal));
    
    % 添加噪声到调制信号
    received_signal = modulated_signal + noise;
    
    %% 4.2 BPSK相干解调
    % 下变频(乘以同频同相的载波)
    demod_signal = received_signal .* carrier;
    
    % 低通滤波(积分清零)
    recovered_symbols = zeros(1, N);
    for i = 1:N
        start_idx = (i-1)*samples_per_bit + 1;
        end_idx = i*samples_per_bit;
        % 积分运算
        recovered_symbols(i) = sum(demod_signal(start_idx:end_idx));
    end
    
    % 判决
    recovered_bits = recovered_symbols < 0;  % 负值判为1,正值判为0
    
    %% 4.3 计算误码率
    errors = sum(bits ~= recovered_bits);
    ber_simulated(snr_idx) = errors/N;
    
    % 理论误码率(BPSK在AWGN信道)
    ber_theoretical(snr_idx) = 0.5 * erfc(sqrt(EbN0(snr_idx)));
    
    fprintf('误码数: %d, 误码率: %.6f\n', errors, ber_simulated(snr_idx));
end

%% 5. 可视化结果
figure('Position', [100, 100, 1200, 800]);

% 5.1 原始比特序列
subplot(3, 3, 1);
stem(bits(1:20), 'filled', 'LineWidth', 1.5);
title('原始比特序列 (前20个比特)');
xlabel('比特序号'); ylabel('幅度');
grid on; ylim([-0.2 1.2]);

% 5.2 BPSK符号
subplot(3, 3, 2);
stem(bpsk_symbols(1:20), 'filled', 'LineWidth', 1.5);
title('BPSK调制符号 (0->+1, 1->-1)');
xlabel('符号序号'); ylabel('幅度');
grid on; ylim([-1.5 1.5]);

% 5.3 基带信号波形
subplot(3, 3, 3);
plot((1:5*samples_per_bit)*Ts, baseband_signal(1:5*samples_per_bit), 'LineWidth', 1.5);
title('基带信号波形 (前5个比特)');
xlabel('时间 (s)'); ylabel('幅度');
grid on;

% 5.4 载波信号
subplot(3, 3, 4);
plot(t_total(1:500), carrier(1:500), 'LineWidth', 1.5);
title('载波信号 (部分波形)');
xlabel('时间 (s)'); ylabel('幅度');
grid on;

% 5.5 调制信号
subplot(3, 3, 5);
plot(t_total(1:5*samples_per_bit), modulated_signal(1:5*samples_per_bit), 'LineWidth', 1.5);
title('BPSK调制信号 (前5个比特)');
xlabel('时间 (s)'); ylabel('幅度');
grid on;

% 5.6 频谱分析
subplot(3, 3, 6);
% 基带信号频谱
[P_baseband, f_baseband] = pwelch(baseband_signal, [], [], [], fs);
% 调制信号频谱
[P_mod, f_mod] = pwelch(modulated_signal, [], [], [], fs);

plot(f_baseband/1000, 10*log10(P_baseband), 'b', 'LineWidth', 1.5);
hold on;
plot(f_mod/1000, 10*log10(P_mod), 'r', 'LineWidth', 1.5);
title('信号频谱');
xlabel('频率 (kHz)'); ylabel('功率谱密度 (dB/Hz)');
legend('基带信号', '调制信号');
grid on; xlim([0, 20]);

% 5.7 接收信号(加噪声后)
subplot(3, 3, 7);
plot(t_total(1:5*samples_per_bit), received_signal(1:5*samples_per_bit), 'LineWidth', 1.5);
title('接收信号 (Eb/N0 = 10dB, 前5个比特)');
xlabel('时间 (s)'); ylabel('幅度');
grid on;

% 5.8 解调后的信号
subplot(3, 3, 8);
plot(t_total(1:5*samples_per_bit), demod_signal(1:5*samples_per_bit), 'LineWidth', 1.5);
title('解调信号 (下变频后)');
xlabel('时间 (s)'); ylabel('幅度');
grid on;

% 5.9 误码率曲线
subplot(3, 3, 9);
semilogy(EbN0_dB, ber_simulated, 'bo-', 'LineWidth', 2, 'MarkerSize', 8, 'MarkerFaceColor', 'b');
hold on;
semilogy(EbN0_dB, ber_theoretical, 'r--', 'LineWidth', 2);
title('BPSK系统误码率性能');
xlabel('Eb/N0 (dB)'); ylabel('误码率 (BER)');
legend('仿真结果', '理论曲线', 'Location', 'best');
grid on;

% 星座图(Eb/N0=10dB时的最后1000个符号)
figure('Position', [100, 100, 600, 500]);
last_N = min(1000, N);
scatter(real(recovered_symbols(end-last_N+1:end)), imag(recovered_symbols(end-last_N+1:end)), 30, 'filled');
title('BPSK星座图 (Eb/N0=10dB)');
xlabel('同相分量 (I)'); ylabel('正交分量 (Q)');
grid on; axis equal;
xlim([-3, 3]); ylim([-3, 3]);
hold on;
plot([0, 0], [-3, 3], 'k--', [-3, 3], [0, 0], 'k--');

% 眼图
figure('Position', [100, 100, 800, 400]);
% 使用低通滤波后的信号生成眼图
eye_diagram_signal = demod_signal;  % 这里使用解调后的信号
samples_per_eye = 2 * samples_per_bit;  % 显示2个比特周期的眼图

subplot(1, 2, 1);
hold on;
for i = 1:min(50, N-1)
    start_idx = (i-1)*samples_per_bit + 1;
    end_idx = start_idx + samples_per_eye - 1;
    if end_idx <= length(eye_diagram_signal)
        t_eye = (0:samples_per_eye-1)*Ts;
        plot(t_eye*1000, eye_diagram_signal(start_idx:end_idx), 'b');
    end
end
title('BPSK解调信号眼图');
xlabel('时间 (ms)'); ylabel('幅度');
grid on;

subplot(1, 2, 2);
% 平均眼图
num_eyes = min(100, floor(length(eye_diagram_signal)/samples_per_bit) - 1);
eye_matrix = zeros(num_eyes, samples_per_eye);
for i = 1:num_eyes
    start_idx = (i-1)*samples_per_bit + 1;
    end_idx = start_idx + samples_per_eye - 1;
    eye_matrix(i, :) = eye_diagram_signal(start_idx:end_idx);
end
eye_mean = mean(eye_matrix, 1);
t_eye = (0:samples_per_eye-1)*Ts;
plot(t_eye*1000, eye_mean, 'r', 'LineWidth', 2);
title('平均眼图');
xlabel('时间 (ms)'); ylabel('幅度');
grid on;

%% 6. 显示关键结果
fprintf('\n========== BPSK调制仿真结果 ==========\n');
fprintf('比特数: %d\n', N);
fprintf('比特率: %d bps\n', Rb);
fprintf('载波频率: %.1f kHz\n', fc/1000);
fprintf('采样频率: %.1f kHz\n', fs/1000);
fprintf('每比特采样数: %d\n', samples_per_bit);
fprintf('\n');

fprintf('误码率比较:\n');
fprintf('Eb/N0(dB)\t仿真BER\t理论BER\n');
for i = 1:length(EbN0_dB)
    fprintf('  %2d\t\t%.2e\t%.2e\n', EbN0_dB(i), ber_simulated(i), ber_theoretical(i));
end

代码说明

1. 主要模块

2. 可视化内容

3. BPSK调制原理

4. 使用方法

  1. 直接运行MATLAB代码
  2. 调整参数(N, Rb, fc等)进行不同条件下的仿真
  3. 观察各种图形输出和分析结果

参考代码 BPSK调制仿真 www.youwenfan.com/contentcsp/98097.html

5. 扩展建议

 

专注于matlab/simulink,电子电路,编程