在 Matlab 中模拟 BPSK Costas 循环

信息处理 matlab 数字通信 bpsk
2021-12-31 10:55:24

我正在尝试在 FPGA 中实现 BPSK 解调器。首先,我在 MATLAB 中对系统进行建模。现在,我正在尝试设计用于载波同步的 Costas Loop。这是我要实现的框图: 在此处输入图像描述

我使用 RRC 作为低通滤波器。这是 MATLAB 代码:

load RRC.mat

fc = 0.05; % 0.11  %0.09
N = length(rf_signal);
bb = zeros(1, N);
bb_f = zeros(1, N);
I_f = zeros(1, N);
Q_f = zeros(1, N);
I_r = zeros(1, N);
Q_r = zeros(1, N);
error = zeros(1, N);
PhErr = zeros(1, N);
error_integral = zeros(1, N);
Theta = zeros(1, N);

% Loop Filter Coefficients
BW = 100;  % Hz
loop_theta = 2*pi*BW;
C1 = 4*(loop_theta)^2/(1+sqrt(2)*loop_theta+loop_theta^2);
C2 = 2*sqrt(2)*loop_theta/(1+sqrt(2)*loop_theta+loop_theta^2);

for i = 2:N
    % Downconverting to Baseband
    bb(i) = rf_signal(i).*exp(j*2*pi*fc*i).*exp(j*Theta(i-1));

    % Filtering
    bb_f = filter(RRC, bb(1:i));
    I_f(i) = real(bb_f(i));
    Q_f(i) = imag(bb_f(i));

    % Error
    error(i) = I_f(i).*Q_f(i);

    % Loop Filter
    error_integral(i) = error(i).*C1 + error_integral(i-1);
    PhErr(i) = error(i).*C2 + error_integral(i);

    % Phase Accumulator
    Theta(i) = Theta(i-1) + PhErr(i);

end

figure; subplot 221; plot(real(bb)); title('I Channel')
subplot 222; plot(imag(bb)); title('Q Channel')
subplot 223; plot(I_f); title('I Channel Filter')
subplot 224; plot(Q_f); title('Q Channel Filter')

figure; subplot 311; plot(error); title('Phase Error');
subplot 312; plot(PhErr); title('Loop Filter');
subplot 313; plot(Theta); title('Control Signal \theta');

rf_signal来自另一个生成 BPSK 信号的脚本。但是,当我关闭环路并完全按照发射器设置频率时,我会得到这些波形: 在此处输入图像描述 在此处输入图像描述

虽然当我打开环路时信号解调得很好。我用余弦波测试了环路,它通过产生直流信号工作得很好。

任何意见,将不胜感激。

1个回答

我想到了。事实证明,我真的不需要那个“相位累加器”,我应该反转 NCO 中的控制信号。因此,我将-PhErr(i-1)其用作 NCO 的控制信号。这是修改后的代码:

% Siraj Muhammad
% 25/3/2015
% BPSK Demodulator
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

load RRC.mat

fc = 0.05000001;
phase_offset = pi/7;

N = length(rf_signal);
bb = zeros(1, N);
bb_f = zeros(1, N);
I_f = zeros(1, N);
Q_f = zeros(1, N);
I_r = zeros(1, N);
Q_r = zeros(1, N);
error = zeros(1, N);
PhErr = zeros(1, N);
error_integral = zeros(1, N);

% Loop Filter Coefficients
BW = 100;  % Hz
loop_theta = 2*pi*BW;
C1 = 4*(loop_theta)^2/(1+sqrt(2)*loop_theta+loop_theta^2);
C2 = 2*sqrt(2)*loop_theta/(1+sqrt(2)*loop_theta+loop_theta^2);

for i = 2:N
    % Downconverting to Baseband
    bb(i) = rf_signal(i).*exp(j*2*pi*fc*i+j*phase_offset).*exp(-j*PhErr(i-1));

    % Filtering
    bb_f = filter(RRC, bb(1:i));
    I_f(i) = real(bb_f(i));
    Q_f(i) = imag(bb_f(i));

    % Error
    error(i) = I_f(i).*Q_f(i);

    % Loop Filter
    error_integral(i) = error(i).*C1 + error_integral(i-1);
    PhErr(i) = error(i).*C2 + error_integral(i);
end

figure; subplot 321; plot(real(bb)); title('I Channel')
subplot 322; plot(imag(bb)); title('Q Channel')
subplot 323; plot(I_f); title('I Channel Filter')
subplot 324; plot(Q_f); title('Q Channel Filter')

subplot 325; plot(error); title('Phase Error');
subplot 326; plot(PhErr); title('Loop Filter');

我添加了一个变量phase_offset来测试具有不同偏移量的循环,我可以稍微漂移频率并且循环会很好地锁定。

我希望这对某人有所帮助,因为我在网上找不到任何适用于 Costas Loop 的 MATLAB 代码。