OQPSK调制解调仿真

OQPSK(偏移四相相移键控)调制解调系统的MATLAB仿真程序,包含信号生成、调制、传输、解调和性能分析。

%% OQPSK调制解调系统仿真
clear all; close all; clc;

%% 参数设置
N = 10000;              % 传输的比特数
fc = 1000;              % 载波频率 (Hz)
fs = 10000;             % 采样频率 (Hz)
Ts = 1/fs;              % 采样间隔
T_symbol = 0.01;        % 符号周期 (秒)
Ns = T_symbol * fs;     % 每个符号的采样点数
EbN0_dB = 0:2:12;       % 信噪比范围 (dB)
N0 = 1;                 % 噪声功率谱密度

% 计算比特能量
Eb = 1;                 % 每比特能量

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

%% OQPSK调制
% 将比特序列分为I路和Q路
I_bits = data_bits(1:2:end);
Q_bits = data_bits(2:2:end);

% 确保I路和Q路长度相同
if length(I_bits) > length(Q_bits)
    I_bits = I_bits(1:length(Q_bits));
elseif length(Q_bits) > length(I_bits)
    Q_bits = Q_bits(1:length(I_bits));
end

% 将比特映射到符号:0->-1, 1->+1
I_symbols = 2 * I_bits - 1;
Q_symbols = 2 * Q_bits - 1;

% 创建时间序列
t = 0:Ts:(length(I_symbols)*T_symbol - Ts);

% 对I路和Q路符号进行脉冲成形(矩形脉冲)
I_baseband = rectpulse(I_symbols, Ns);
Q_baseband = rectpulse(Q_symbols, Ns);

% Q路延迟半个符号周期(OQPSK的关键特性)
delay_samples = floor(Ns/2);
Q_baseband_delayed = [zeros(1, delay_samples), Q_baseband(1:end-delay_samples)];

% 确保I路和Q路长度相同
min_length = min(length(I_baseband), length(Q_baseband_delayed));
I_baseband = I_baseband(1:min_length);
Q_baseband_delayed = Q_baseband_delayed(1:min_length);
t = t(1:min_length);

% 生成载波信号
carrier_I = cos(2*pi*fc*t);
carrier_Q = sin(2*pi*fc*t);

% 调制信号:I路乘以cos载波,Q路乘以sin载波
modulated_signal = I_baseband .* carrier_I + Q_baseband_delayed .* carrier_Q;

%% 绘制调制过程中的信号
figure('Position', [100, 100, 1200, 800]);

% 原始比特序列
subplot(4,2,1);
stem(data_bits(1:40), 'filled');
title('原始比特序列 (前40个比特)');
xlabel('比特索引');
ylabel('幅度');
grid on;

% I路和Q路基带信号
subplot(4,2,2);
plot(t(1:5*Ns), I_baseband(1:5*Ns), 'b', 'LineWidth', 1.5);
hold on;
plot(t(1:5*Ns), Q_baseband_delayed(1:5*Ns), 'r', 'LineWidth', 1.5);
title('I路和Q路基带信号 (前5个符号)');
xlabel('时间 (秒)');
ylabel('幅度');
legend('I路', 'Q路(延迟)');
grid on;

% I路和Q路调制信号
subplot(4,2,3);
plot(t(1:5*Ns), I_baseband(1:5*Ns).*carrier_I(1:5*Ns), 'b', 'LineWidth', 1.5);
hold on;
plot(t(1:5*Ns), Q_baseband_delayed(1:5*Ns).*carrier_Q(1:5*Ns), 'r', 'LineWidth', 1.5);
title('I路和Q路调制信号 (前5个符号)');
xlabel('时间 (秒)');
ylabel('幅度');
legend('I路×cos(ωt)', 'Q路×sin(ωt)');
grid on;

% 已调制信号
subplot(4,2,4);
plot(t(1:5*Ns), modulated_signal(1:5*Ns), 'm', 'LineWidth', 1.5);
title('OQPSK已调制信号 (前5个符号)');
xlabel('时间 (秒)');
ylabel('幅度');
grid on;

% 调制信号频谱
subplot(4,2,5);
[Pxx, f] = pwelch(modulated_signal, 1024, 512, 1024, fs);
plot(f, 10*log10(Pxx), 'LineWidth', 1.5);
title('OQPSK信号功率谱密度');
xlabel('频率 (Hz)');
ylabel('功率谱密度 (dB/Hz)');
xlim([0, 2*fc]);
grid on;

%% 信号传输(添加AWGN噪声)
ber_sim = zeros(1, length(EbN0_dB));
ber_theory = zeros(1, length(EbN0_dB));

for i = 1:length(EbN0_dB)
    % 计算当前信噪比对应的噪声功率
    EbN0 = 10^(EbN0_dB(i)/10);
    noise_power = Eb / EbN0;
    
    % 生成高斯白噪声
    noise = sqrt(noise_power) * randn(1, length(modulated_signal));
    
    % 添加噪声到调制信号
    received_signal = modulated_signal + noise;
    
    % 绘制第一个信噪比的接收信号
    if i == 1
        subplot(4,2,6);
        plot(t(1:5*Ns), received_signal(1:5*Ns), 'g', 'LineWidth', 1.5);
        title(['接收信号 (Eb/N0 = ', num2str(EbN0_dB(i)), ' dB)']);
        xlabel('时间 (秒)');
        ylabel('幅度');
        grid on;
    end
    
    %% OQPSK解调
    % 相干解调:乘以载波
    demod_I = received_signal .* carrier_I;
    demod_Q = received_signal .* carrier_Q;
    
    % 低通滤波(使用移动平均滤波器)
    filter_taps = ones(1, Ns) / Ns;
    filtered_I = filter(filter_taps, 1, demod_I);
    filtered_Q = filter(filter_taps, 1, demod_Q);
    
    % Q路提前半个符号周期(补偿调制时的延迟)
    Q_advanced = [filtered_Q(delay_samples+1:end), zeros(1, delay_samples)];
    
    % 确保I路和Q路长度相同
    min_length = min(length(filtered_I), length(Q_advanced));
    filtered_I = filtered_I(1:min_length);
    Q_advanced = Q_advanced(1:min_length);
    
    % 采样(在每个符号周期的中间采样)
    sample_points = floor(Ns/2):Ns:min_length;
    I_samples = filtered_I(sample_points);
    Q_samples = Q_advanced(sample_points);
    
    % 判决:大于0判为1,小于0判为0
    I_decisions = (I_samples > 0);
    Q_decisions = (Q_samples > 0);
    
    % 重新组合I路和Q路比特
    received_bits = zeros(1, 2*length(I_decisions));
    received_bits(1:2:end) = I_decisions;
    received_bits(2:2:end) = Q_decisions;
    
    % 截取与原始数据相同长度的比特
    received_bits = received_bits(1:N);
    
    % 计算误比特率
    bit_errors = sum(data_bits ~= received_bits);
    ber_sim(i) = bit_errors / N;
    
    % 计算理论误比特率(QPSK与OQPSK相同)
    ber_theory(i) = 0.5 * erfc(sqrt(EbN0));
    
    fprintf('Eb/N0 = %.1f dB: 误比特率 = %.4f (理论值: %.4f)\n', ...
            EbN0_dB(i), ber_sim(i), ber_theory(i));
end

%% 绘制误比特率曲线
subplot(4,2,7:8);
semilogy(EbN0_dB, ber_sim, 'bo-', 'LineWidth', 2, 'MarkerFaceColor', 'b');
hold on;
semilogy(EbN0_dB, ber_theory, 'r--', 'LineWidth', 2);
grid on;
xlabel('Eb/N0 (dB)');
ylabel('误比特率 (BER)');
title('OQPSK系统性能');
legend('仿真结果', '理论值');
axis tight;

%% 绘制星座图
% 选择中间部分样本以避免过渡区域
start_idx = floor(length(I_samples)/4);
end_idx = floor(3*length(I_samples)/4);

figure;
plot(I_samples(start_idx:end_idx), Q_samples(start_idx:end_idx), 'b.');
axis equal;
grid on;
title('OQPSK解调后星座图');
xlabel('I路分量');
ylabel('Q路分量');

%% 眼图分析
figure;
% I路眼图
subplot(2,1,1);
plot_eye_diagram(filtered_I, Ns, 3);
title('I路眼图');
xlabel('时间(符号周期)');
ylabel('幅度');
grid on;

% Q路眼图
subplot(2,1,2);
plot_eye_diagram(Q_advanced, Ns, 3);
title('Q路眼图');
xlabel('时间(符号周期)');
ylabel('幅度');
grid on;

%% 眼图绘制函数
function plot_eye_diagram(signal, samples_per_symbol, num_eyes)
    % 计算每个轨迹的长度
    trace_length = samples_per_symbol;
    
    % 确定要绘制的轨迹数量
    num_traces = min(floor(length(signal) / trace_length), 50);
    
    % 创建时间轴
    t = (0:trace_length-1) / samples_per_symbol;
    
    hold on;
    for i = 1:num_traces
        start_idx = (i-1)*trace_length + 1;
        end_idx = i*trace_length;
        if end_idx <= length(signal)
            plot(t, signal(start_idx:end_idx), 'b');
        end
    end
    hold off;
    xlim([0, num_eyes]);
end

%% 显示最终结果
fprintf('\nOQPSK仿真完成!\n');
fprintf('在Eb/N0 = 12 dB时,误比特率 = %.6f\n', ber_sim(end));

功能说明

1. OQPSK调制原理

OQPSK(偏移四相相移键控)是QPSK的一种改进形式,其特点是:

  • I路和Q路数据在时间上偏移半个符号周期
  • 避免了QPSK中可能出现的180°相位跳变
  • 具有更好的包络特性,适合非线性放大器

2. 程序组成部分

  1. 参数设置:定义仿真基本参数,如比特数、载波频率、采样率等
  2. 信号生成:产生随机比特序列作为信源
  3. OQPSK调制
    • 将比特流分为I路和Q路
    • Q路延迟半个符号周期
    • 分别用正交载波调制
  4. 信道模拟:添加高斯白噪声(AWGN)
  5. OQPSK解调
    • 相干解调
    • 低通滤波
    • 采样判决
  6. 性能分析
    • 计算误比特率(BER)
    • 绘制BER曲线
    • 显示星座图和眼图

3. 关键特性

  • 偏移处理:Q路信号延迟半个符号周期,这是OQPSK与普通QPSK的主要区别
  • 脉冲成形:使用矩形脉冲,也可替换为升余弦等脉冲形状
  • 相干解调:使用与发射端同频同相的载波进行解调
  • 性能比较:同时显示仿真结果和理论值进行对比

4. 输出结果

程序运行后会显示:

  1. 调制过程中各阶段的信号波形
  2. OQPSK信号的功率谱密度
  3. 不同信噪比下的误比特率曲线
  4. 解调后的星座图
  5. I路和Q路的眼图

参考代码 OQPSK的仿真程序 www.youwenfan.com/contentcnk/100054.html

扩展应用

此程序可以进一步扩展用于:

  1. 不同脉冲成形滤波器:尝试升余弦、高斯等脉冲形状
  2. 多径信道仿真:添加多径效应模拟无线信道
  3. 同步误差分析:研究载波同步和定时同步误差的影响
  4. 硬件损伤建模:加入功率放大器非线性等实际硬件损伤
  5. 与其他调制方式比较:与QPSK、π/4-QPSK等调制方式比较性能

这个仿真程序提供了OQPSK调制解调的完整实现,可以帮助理解OQPSK的工作原理和性能特性。

posted @ 2025-10-29 15:55  bqyfa66984  阅读(31)  评论(0)    收藏  举报