AnyMath 文档
Notebook

接收FM信号时的锁相频率

在这个例子中,我们将组装一个基于锁相频率(PLL)的FM信号接收器。 我们正在研究噪声信号的捕获,调制和输出纹波的恢复。 该模型由AnyMath基块组成,因此所有内部环路信号都可用。

FM信号由表达式给出

载波的频率为10赫兹,调制信号 — glad/s.调制指数 .

相位检测器将输入信号和振荡器信号相乘:

滤波器抑制加倍载波的分量。 具有小的相位差,检测器系数 . 环路使用两个低通和一个PI控制器。:

哪里 与, , .

线性化回路模型具有传递函数

在调制频率 确定重建信号的增益和相移。

循环特性的计算

计算调制指数、加倍载波的抑制和0.5hz时的环路响应。

In [ ]:
using Main: engee, plot, plot!, histogram, hline!, savefig, Animation, frame, gif
Kd = 0.5                 # 鉴相系数,1/rad
τ = 0.02                 # 每个低通滤波器的时间常数,用
Kp, Ki = 15.0, 100.0     # PI控制器系数
ω0 = 62.8319             # 载波频率,rad/s
Am, Ω = 1.5, π           # 频偏幅度和调制频率,rad/s

pll_F(s) = 1 / (τ * s + 1)^2         # 连续两次低通
pll_C(s) = Kp + Ki / s               # PI控制器
pll_L(s) = Kd * pll_F(s) * pll_C(s) / s      # 开环:GONG将频率集成到相位
pll_H(s) = pll_L(s) / (1 + pll_L(s))         # 从输入频率到控制信号的偏差

β = Am / Ω
ripple = Kp * Kd * abs(pll_F(2im * ω0))   # 在滤波器和Kp之后,分量的幅度为2ω0
Hm = pll_H(im * Ω)

println("调制指数β= ", round(β, digits = 3))
println("2ω0分量的衰减由两个低通: ", round(abs(pll_F(2im * ω0)), digits = 3))
println("控制信号中2ω0纹波的估计: ", round(ripple, digits = 2), " рад/с")
println("|H/在调制频率: ", round(abs(Hm), digits = 3),
        ", фаза ", round(rad2deg(angle(Hm)), digits = 1), "°")
Индекс модуляции β = 0.477
Ослабление составляющей 2ω0 двумя ФНЧ: 0.137
Оценка пульсаций 2ω0 в сигнале управления: 1.03 рад/с
|H| на частоте модуляции: 1.203, фаза -3.8°

在调制频率下,计算给出了大约1.2的增益和约-4°的相移。 在双载波频率(20Hz)下,滤波器通过的幅度约为14%。 因此,预期在输出处会出现明显的波纹。

模型描述

image.png

模型包含以下部分:

循环的一部分 工程师座
FM源和噪声 正弦波,积分器,随机数
相位检测器 产品
滤波器和PI控制器 转移Fcn,增益,积分器
受控发电机 积分器,三角函数
信号的记录 到工作区

计算步骤为0.5ms,仿真时间为6s,我们分析了调制,解调器的输出,接收器的输入,发生器的信号及其频率控制。

从示例文件夹下载模型并运行计算。

In [ ]:
using Statistics

model_name = "PLL_FM"
model_file = joinpath(@__DIR__, "PLL_FM.engee")

model = engee.load(model_file; force=true)

# 运行模拟;到工作区信号将出现在工作区中
engee.run(model)

我们将从到工作区块接收信号。

In [ ]:
# To Workspace将信号存储为表格:时间,值。
function signal_data(signal)
    table = collect(signal)
    return table[!, 1], table[!, 2]
end

t_mod,  x_mod  = signal_data(Core.eval(Main, :(mod_sig)))
t_fm,   x_fm   = signal_data(Core.eval(Main, :(fm_in)))
t_vco,  x_vco  = signal_data(Core.eval(Main, :(pll_vco_sig)))
t_dem,  x_dem  = signal_data(Core.eval(Main, :(demod_sig)))
t_ctrl, x_ctrl = signal_data(Core.eval(Main, :(ctrl_sig)))
t_freq, x_freq = signal_data(Core.eval(Main, :(vco_freq)))

omega0 = 62.8319
freq_deviation = x_freq .- omega0

println("计数数目: ", length(t_mod))
println("持续时间: ", last(t_mod), " 与")
println("RMS mod_sig: ", round(sqrt(mean(x_mod .^ 2)), digits=4))
println("RMS demod_sig: ", round(sqrt(mean(x_dem .^ 2)), digits=4))
Число отсчётов: 12001
Длительность: 6.0 с
RMS mod_sig: 1.0606
RMS demod_sig: 1.4994

记录12001次计数。 均方根调制值接近1.06rad/s;解调器的输出还包含环路波纹。

收到数据后,我们将关闭模型。

In [ ]:
engee.close(model_name; force = true)

让我们比较解调器的调制和输出,输入信号和振荡器,以及频率控制和偏差。

In [ ]:
# 1. 调制和解调信号。
p1 = plot(
    t_mod, x_mod;
    label="调制方式",
    linewidth=2,
    ylabel="的振幅",
    title="调制和解调信号",
    legend=:topright, legendfontsize=8, xlabel="时间,从",
    grid=true
)
plot!(
    p1, t_dem, x_dem;
    label="解调器输出",
    linewidth=1.5,
    linestyle=:dash
)

# 2. FM信号和短程VCO信号。
p2 = plot(
    t_fm, x_fm;
    label="FM输入信号",
    linewidth=1.2,
    xlims=(2.0, 2.4),
    ylabel="的振幅",
    title="FM信号和VCO",
    legend=:topright, legendfontsize=8, xlabel="时间,从",
    grid=true
)
plot!(
    p2, t_vco, x_vco;
    label="古恩",
    linewidth=1.2,
    linestyle=:dash
)

# 3. 制信号和VCO频率偏差。
p3 = plot(
    t_ctrl, x_ctrl;
    label="控制信号",
    linewidth=2,
    ylabel="рад/с",
    title="VCO管理",
    legend=:topright, legendfontsize=8, xlabel="时间,从",
    grid=true
)
plot!(
    p3, t_freq, freq_deviation;
    label="频率偏差",
    linewidth=1.2,
    linestyle=:dash
)

# 4. PLL反应的放大片段。
p4 = plot(
    t_mod, x_mod;
    label="调制方式",
    linewidth=2,
    xlims=(2.0, 4.0),
    ylabel="的振幅",
    title="PLL反应",
    legend=:topright, legendfontsize=8, xlabel="时间,从",
    grid=true
)
plot!(
    p4, t_dem, x_dem;
    label="解调器输出",
    linewidth=1.5,
    linestyle=:dash
)

plot(
    p1, p2, p3, p4;
    layout=(2, 2),
    size=(1400, 1050)
)

输出以0.5hz的频率重复调制。 在其顶部可以看到大约20Hz的脉动-双倍载波的分量。 发生器的信号与输入正交,控制对应于其频率的偏差。

让我们估计过渡过程结束后的振幅,从2s开始。

In [ ]:
# 段t中信号x(t)中谐波频率f(Hz)的幅值≥t_start
function harmonic_amplitude(t, x, f; t_start = 2.0)
    mask = t .>= t_start
    tt, xx = t[mask], x[mask]
    c = sum(xx .* cos.(2π * f .* tt))
    s = sum(xx .* sin.(2π * f .* tt))
    return 2 * hypot(c, s) / length(tt)
end

a_mod = harmonic_amplitude(t_mod, x_mod, 0.5)
a_dem = harmonic_amplitude(t_dem, x_dem, 0.5)
a_2f0 = harmonic_amplitude(t_dem, x_dem, 20.0)

println("mod_sig,0.5赫兹:   ", round(a_mod, digits = 3), " рад/с")
println("解调,0.5赫兹: ", round(a_dem, digits = 3), " рад/с; отношение ", round(a_dem / a_mod, digits = 3),
        " (теория |H| = ", round(abs(Hm), digits = 3), ")")
println("解调,20赫兹:  ", round(a_2f0, digits = 3), " рад/с")
@assert length(t_mod) > 100 && all(isfinite, x_dem)
string("PLL FM passed; samples=", length(t_mod), "; modulation gain=", round(a_dem/a_mod; digits=3))
mod_sig, 0.5 Гц:   1.5 рад/с
demod_sig, 0.5 Гц: 1.753 рад/с; отношение 1.169 (теория |H| = 1.203)
demod_sig, 20 Гц:  0.808 рад/с

调制频率下测得的增益约为1.17,与计算接近。 剩余的20Hz分量与有限的滤波器抑制相关联。 通过改变它们的参数和PI控制器的系数,可以研究环路频带对解调的影响。

结论

PLL监视FM信号并恢复调制,增益约为1.17,接近计算的增益。 倍载波的残余脉动表明环路滤波器对解调质量的影响。