加载中...

载波同步学习及仿真

载波同步相关知识

简单回顾

需要同步的原因

载波环

锁相环关注的是信号的相位分量


在锁相环中,要时刻记住,我们所关注的对象是相位信息,不是输入输出电压或电流的幅值,而是电压信号的瞬时相位;
在有些说法中,锁相环关注的是相位信息或者频率信息,这是因为对瞬时相位进行微分就可以得到瞬时频率,因此也可以说关注的是输入输出信号的频率,这二者并不矛盾。

VCO是一个积分器件

对于VCO是一个积分器件,刚开始很容易不理解,单从VCO的功能上来看,它是一个电压与频率的变换装置在环路中作为压控振荡器,它的振荡频率随输入控制电压线性地变化。

$$
w_v(t)=w_o+K_0u_c(t)
$$

式中,$w_v(t)$是压控振荡器的瞬时角频率(rad/s);$w_o$为压控振荡器的固有角频率,即无输入控制电压情况下的振荡角频率(rad/s);$K_0$为VCO的频率灵敏度或称增益系数rad/(s·V);
模拟压控振荡器的控制特性只有有限的控制范围,超出范围之后控制灵敏度会下降。数字则在范围内都是线性关系。


《GPS原理与接收机设计》谢钢—学习

环路带宽

环路带宽又称噪声带宽,它控制着进入环路的噪声量的多少。噪声带宽越窄,则由于越少频率成分的噪声被允许进入环路,因而环路的滤波效果越好,环路对信号的跟踪就越准确;反之,噪声带宽越宽,环路的噪声性能越差,信号跟踪越不准确,以Hz为单位的定义式如下:

$$
\small B_L=\int^{\infty}_0|H(f)|^2df
$$

$w=2\pi f$ $ s→j2\pi f$

得到一阶环路噪声带宽

$$
{B_L = } {w_n \over 4}
$$

二阶锁相环噪声带宽

$$
B_L = {w_n \over 2} \bigg( \xi + {1\over 4\xi}\bigg)
$$

噪声带宽$B_L$并不能无限的小,由于高动态应力会引起接收信号载波频率和相位跟踪误差的激烈振荡,所以我们希望环路带宽$B_L$能大到足够容忍这种由于用户运动而引起的载波频率和相位的正常波动,以保证环路对信号的持续跟踪;否则,若$B_L$过小,可能将有用信号一起滤除,使环路容易发生信号失锁。
可见,环路带宽$B_L$是锁相环的一个重要参量,越大的环路带宽可使接收机具有越强的支持用户高动态性的能力,但这也同时降低了它的噪声性能。

对于二阶环路来说,给定一个$w_n$,则当阻尼系数$\xi$等于$0.5$时,环路带宽$B_L$达到最小值,此时应当具有最好的噪声性能,然而阻尼系数经常选取$0.7071(即{\sqrt2\over2})$,此时

$$
B_L=0.53w_n
\a_2=1.414 ;B_L={1+a^2_2\over4a_2}w_n=0.53w_n
$$

补充:

I/Q解调

MATLAB仿真

仿真代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
clc; clear; close all;
%%%%%%%%%---------数字锁相环的实现----------%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%-----BPSK基础上加上频偏,实现载波同步-----%%%%%%%%%%%%%%%%%
symbol_rate = 10000; %符号速率
sps = 4; %每个符号4个采样点
fs = sps * symbol_rate; % 采样率
span = 6;
fc = fs / 4; % 载波频率40000/4
alfs = 0.35; % 滚降系数
N = 500; %数据长度
is_plot = 1; %是否打印输出
%data = repmat([0,1], 1,N/2);
data = randi([0 1], 1, N); %生成0,1序列

s = (data - 1/2) * 2; %映射
data_up = upsample(s, sps); %上采样

fir_rcos = rcosdesign(alfs, span, sps, "sqrt"); %根升余弦
data_bx = conv(data_up, fir_rcos); %通过滤波器
data_bx_valid = data_bx(1, (1 + length(fir_rcos)) / 2:end - (length(fir_rcos) - 1) / 2);
t = 0:length(data_bx_valid) - 1;
carrier = cos(2 * pi * fc / fs .* t); %载波
s_up = data_bx_valid .* carrier; %上变频
r_n = awgn(s_up, 10, 'measured'); %加高斯白噪声
%正交下变频
delta_f = 100; %设置频偏参数
carrier_cos = cos(2 * pi * (fc + delta_f) / fs * t); %加频偏
carrier_sin = sin(2 * pi * (fc + delta_f) / fs * t);
sig_I = r_n .* carrier_cos;
sig_Q = r_n .* carrier_sin;
r_bx_I = conv(sig_I, fir_rcos);
r_bx_I_valid = r_bx_I(1, (1 + length(fir_rcos)) / 2:end - (length(fir_rcos) - 1) / 2);
r_bx_Q = conv(sig_Q, fir_rcos);
r_bx_Q_valid = r_bx_Q(1, (1 + length(fir_rcos)) / 2:end - (length(fir_rcos) - 1) / 2);
r_complex = complex(r_bx_I_valid, r_bx_Q_valid);
r_complex_de = r_complex(1:sps:end);

%%%%%%%载波同步
pll_detector = zeros(1, N);
nco = zeros(1, N);

BL = 300;
Wn = BL / 0.53;
T = 1 / symbol_rate;
%近似求法
c1 = sqrt(2) * Wn * T;
c2 = (Wn * T)^2;
%准确求法
%c1 = (4 * (Wn * T)^2 + 4 * sqrt(2) * Wn * T) / (4 + 2 * sqrt(2) * Wn * T + (Wn * T)^2);
%c2 = (4 * (Wn * T)^2) / (4 + 2 * sqrt(2) * Wn * T + (Wn * T)^2);
%c1 = 1/2^8; c2 = 1/2^17; %环路滤波器系数
w = [1, zeros(1, N - 1)]; %环路滤波器输出寄存器,初值设为0.5
I_pll = zeros(1, N);
Q_pll = zeros(1, N);
pll_out = [r_complex_de(1), zeros(1, N - 1)];
%w = zeros(1,sps*N);
A = zeros(1, N);
%% 载波环
for ii = 2:N
pll_out(ii) = r_complex_de(ii) * exp(-1i * mod(nco(ii - 1), 2 * pi));
%数字鉴相器
I_pll(ii) = real(pll_out(ii));
Q_pll(ii) = imag(pll_out(ii));
pll_detector(ii) = atan(Q_pll(ii) / I_pll(ii)); %鉴相器输出
%通过环路滤波器
% if (ii > 1)
% w(ii + 1) = w(ii) + c1 * (pll_detector(ii) - pll_detector(ii - 1)) + c2 * pll_detector(ii);
% else
% w(ii + 1) = w(ii) + c1 * pll_detector(ii) + c2 * pll_detector(ii);
% end
A(ii) = c2 * pll_detector(ii) + A(ii - 1);
w(ii) = c1 * pll_detector(ii) + A(ii - 1);
%NCO
nco(ii) = nco(ii - 1) + w(ii);
end

y_decision = real(pll_out) > 0;
%y_decision = pll_out(1:1:end) > 0;
error_bit = sum(abs(y_decision - data));

if is_plot
%figure(1);
%plot(w); title('环路滤波器输出');
%figure(2);
%plot(nco); title('NCO输出');

scatterplot(r_complex_de);
grid on; axis tight;
scatterplot(pll_out);
end


输出结果

验证输出结果是否正确,直观检验误码率

修改**N = 50000; %数据长度**输出星座图

环路滤波器输出图像和NCO输出图像

完成上述操作之后,再进行误码率分析即可减少错误来源,即模块化分析;


😌

误码率仿真分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
clc; clear; close all;
%%%%%%%%%---------数字锁相环的实现----------%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%-----BPSK基础上加上频偏,实现载波同步-----%%%%%%%%%%%%%%%%%
symbol_rate = 10000; %符号速率
sps = 4; %每个符号4个采样点
fs = sps * symbol_rate; % 采样率
span = 6;
fc = fs / 4; % 载波频率
alfs = 0.35; % 滚降系数
N = 500000; %数据长度
is_plot = 1; %是否打印输出
%data = repmat([0,1], 1,N/2);
data = randi([0 1], 1, N); %生成0,1序列

s = (data - 1/2) * 2; %映射
data_up = upsample(s, sps); %上采样

fir_rcos = rcosdesign(alfs, span, sps, "sqrt"); %根升余弦
data_bx = conv(fir_rcos, data_up); %通过滤波器
data_bx_valid = data_bx(1, (1 + length(fir_rcos)) / 2:end - (length(fir_rcos) - 1) / 2);

t = 0:length(data_bx_valid) - 1;
carrier = cos(2 * pi * fc / fs * t); %载波
s_up = data_bx_valid .* carrier; %上变频
errbit = zeros(1, 10);
snr = zeros(1, 10);
i = 1;

for ebn0 = 1:10
snr(i) = ebn0 + 10 * log10(2) - 10 * log10(sps); %SNR和EbN0的转化
r_n = awgn(s_up, snr(i), 'measured'); %加高斯白噪声

%%%%正交下变频
delta_f = 100; %设置频偏参数
carrier_cos = cos(2 * pi * (fc + delta_f) / fs * t); %加频偏
carrier_sin = sin(2 * pi * (fc + delta_f) / fs * t);
sig_I = r_n .* carrier_cos;
sig_Q = r_n .* carrier_sin;
r_bx_I = conv(sig_I, fir_rcos);
r_bx_I_valid = r_bx_I(1, (1 + length(fir_rcos)) / 2:end - (length(fir_rcos) - 1) / 2);
r_bx_Q = conv(sig_Q, fir_rcos);
r_bx_Q_valid = r_bx_Q(1, (1 + length(fir_rcos)) / 2:end - (length(fir_rcos) - 1) / 2);
r_complex = complex(r_bx_I_valid, r_bx_Q_valid);
r_complex_de = r_complex(1:sps:end);

%%%%%%%载波同步
BL = 300;
Wn = BL / 0.53;
T = 1 / symbol_rate;
%近似求法
% c1 = sqrt(2) * Wn * T;
% c2 = (Wn * T)^2;
%准确求法
c1 = (4 * (Wn * T)^2 + 4 * sqrt(2) * Wn * T) / (4 + 2 * sqrt(2) * Wn * T + (Wn * T)^2);
c2 = (4 * (Wn * T)^2) / (4 + 2 * sqrt(2) * Wn * T + (Wn * T)^2);
% c1 = 1/2^8; c2 = 1/2^17; %环路滤波器系数
w = [1, zeros(1, N - 1)]; %环路滤波器输出寄存器,初值设为1
I_pll = zeros(1, N);
Q_pll = zeros(1, N);
pll_out = [r_complex_de(1), zeros(1, N - 1)];
pll_detector = [atan(Q_pll(1) / I_pll(1)), zeros(1, N - 1)];
nco = zeros(1, N);
%w = zeros(1,sps*N);
A = zeros(1, N);
%% 载波环
for ii = 2:N
pll_out(ii) = r_complex_de(ii) * exp(-1i * mod(nco(ii - 1), 2 * pi));
%数字鉴相器
I_pll(ii) = real(pll_out(ii));
Q_pll(ii) = imag(pll_out(ii));
pll_detector(ii) = atan(Q_pll(ii) / I_pll(ii)); %鉴相器输出
%通过环路滤波器
% if (ii > 1)
% w(ii + 1) = w(ii) + c1 * (pll_detector(ii) - pll_detector(ii - 1)) + c2 * pll_detector(ii);
% else
% w(ii + 1) = w(ii) + c1 * pll_detector(ii) + c2 * pll_detector(ii);
% end
A(ii) = c2 * pll_detector(ii) + A(ii - 1);
w(ii) = c1 * pll_detector(ii) + A(ii - 1);
%NCO
nco(ii) = nco(ii - 1) + w(ii);
end

%抽样判决
y_decision = real(pll_out) > 0;
%errbit(i) = sum(abs(y_decision(301:N) - data(301:N))) / (N - 300);
errbit(i) = sum(abs(y_decision - data)) / N;
i = i +1;
end

if is_plot
% figure;
% subplot(2, 1, 1);
% stem(data, 'filled');
% subplot(2, 1, 2);
% stem(yI_decision, 'filled');
figure;
ebn0 = 1:10;
ber_theory = 0.5 * erfc(sqrt(power(10, ebn0 / 10))); %理论误码率
semilogy(ebn0, ber_theory, '-or');
grid on; hold on;
semilogy(ebn0, errbit, '-sb');
grid on; hold on;
xlabel('EbN0(dB)'); ylabel('BER')
title('BPSK误码率曲线图');
legend('理论误码率曲线', '仿真误码率曲线');
end

  • 验证一行代码 conv(a,b,'same')

    根据信号与系统中卷积的知识,卷积完的序列长度为$M+N-1$,通过滤波器,相当于卷积,但输出应该和原来的数据长度一致,比如输入长度为$N$,输出也应该为$N$,其余数据是无用数据,包括滤波器的时延以及拖尾带来的无用数据,对此需要截断处理,越早截断,越不容易出错。
    滤波器时延为${\tau-2}\over 2$;根据公式结合滤波器长度即可截断,当然 conv(a,b,'same') 更为方便,输出长度与$a$一致,且为有效数据,下面举相关的例子进行验证。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    symbol_rate = 10000; %符号速率
    sps = 4; %每个符号4个采样点
    fs = sps * symbol_rate; % 采样率
    span = 6;
    fc = fs / 4; % 载波频率
    alfs = 0.35; % 滚降系数
    N = 500; %数据长度
    is_plot = 1; %是否打印输出
    data = randi([0 1], 1, N); %生成0,1序列

    s = (data - 1/2) * 2; %映射
    data_up = upsample(s, sps); %上采样

    fir_rcos = rcosdesign(alfs, span, sps, "sqrt"); %根升余弦
    data_bx = conv(data_up, fir_rcos); %通过滤波器
    data_bx_valid = data_bx(1, (1 + length(fir_rcos)) / 2:end - (length(fir_rcos) - 1) / 2);
    data_bx_2 = conv(data_up, fir_rcos,'same');
    y = data_bx_valid - data_bx_2;
    plot(y);

    对上述结果进行分析, data_bx 为直接卷积输出, fir_rcos 为滤波器序列(长度为$25$),s_up为输入滤波器的信号序列(长度为$2000$),根据卷积理论,data_bx长度为($25+2000-1=2024$);时延为$(25-1)/2=12$,所以根据MATLAB语法,有效序列应该从第$13$个数算起,即:${ {(length-1)} \over{2} }+1={ {(length+1)} \over{2} }$,和代码data_bx(1, (1 + length(fir_rcos)) / 2:end - (length(fir_rcos) - 1) / 2)对应。
    data_bx_2 = conv(data_up, fir_rcos,'same'); y = data_bx_valid - data_bx_2;由图中可以看出,y恒为0,说明两者得出的结果完全一致;
    就以后编程而言,优先选择加“$same$”,简单而不容易错,但从理解卷积与滤波器的角度来看,显然从数学公式的截断角度更为直观。