关于PLL的具体原理详见这里,在这着重介绍如何编程实现.
clear;
clc;
%相关参数设定
fs=7e5; %采样率
N=1e3; %序列点数
f1=7e3; %输入信号频率
fvco=8e3; %vco自由震荡频率(无输入时输出)
pvco=4e3; %电压频率转化系数 V/Hz
fc=3e3; %bpf截至频率
filter_coefficient_num=100; %bpf系数个数
bpf = fir1(filter_coefficient_num,fc/(fs/2)); %bpf设计
%设置输入波形
Ts=1/fs;
t=0:Ts:(N-1)*Ts;
y=sin(2*pi*f1*t);
%初始化输出
VCO=zeros(1,N);
Phi=zeros(1,N);
error=zeros(1,N);
for n=2:N
now_t=n*Ts;
%实现乘法器
error_mult(n)=y(n)*VCO(n-1);
%实现loop filter
for m=1:length(bpf)
if n-m+1>=1
error_array(m)=error_mult(n-m+1);
else
error_array(m)=0;
end
end
error(n)=sum(error_array.*(bpf));
%实现vco
Phi(n)=Phi(n-1)+2*pi*pvco*error(n)*Ts;
VCO(n)=sin(2*pi*fvco*now_t+Phi(n));
end
%数据可视化处理
figure
plot(t,y,t,VCO);
grid on
legend('原信号','PLL输出');
xlabel('time [s]')
title('input and output signal')
figure
plot(t,error)
xlabel('time [s]')
title('Error signal')
center_freq(VCO,fs)
在设计中遇到的问题:
-
采样率与检测信号频率
在一开始,对采样率的理解只有防止抽样混叠,但在PLL中采样率的设定不仅仅由这一个因素决定.我一开始用4.8e4Hz的采样率,而检测信号的频率为7e3Hz,这看起来似乎没有什么问题,但是我们返回到时域考察一下.
抽样间隔为2.0833e-05 s,而检测信号的周期为1.4286e-04 s,也就是说在检测信号的一个周期内,仅能得到6.8571 个样值点,相邻两点之间数字角频率间隔很大,从而影响PLL的性能,运行结果如下
为了缩短间隔,需要在一个检测信号周期内获得更多的点,这里我设定一个周期内需要100个样值点,因此 f s = 100 T 1 f_s = \frac{100}{T_1}