二进制频移键控系统的设计与建模
本文探讨了采用二进制频移键控**(Binary Frequency Shift Keying, BFSK)**的数据传输系统的开发与建模过程。 FSK调制是现代通信系统中的基础概念。在其二进制形式中,逻辑“0”和“1”分别对应频率为( f_1 )和( f_2 )的两个不同谐波信号。 BFSK 因其抗噪性能和实现简便性,被广泛应用于低速应用中,例如蓝牙技术、早期 GSM 技术,以及各种遥测和无线电控制系统。
在本文中,我们将构建一个基于BFSK的通信系统模型,并依次进行以下步骤:
- 生成原始数字信号。
- **BFSK调制:**根据比特值选择两个载波频率中的一个来形成信号。
- **BFSK解调:**实现非相干检测方法。 该方法基于利用带通滤波器将信号分为两个频率通道,提取其包络线,并选择包络线振幅较大的通道。
- **结果分析:**比较发送和接收的消息。
本研究的特色在于解调器中采用了**双二次滤波器(Biquad Filter)**级联结构。 为了正确提取BFSK信号中的信息分量,必须确保滤波器调谐到调制器中实际使用的频率。 为此,我们对其幅频响应(AFR)和相频响应(PFR)特性进行了分析。
using JLD2, Plots
SOS = load("filter_matrix.jld2", "SOS")
Scale = load("filter_matrix.jld2", "Scale")
println("Size SOS: $(size(SOS))")
println("Size Scale: $(size(Scale))")
滤波器系数已预先计算并保存在文件filter_matrix.jld2 中。需加载两个关键变量:
- SOS(Second-Order Sections)——每个双二次节点的系数矩阵。 矩阵尺寸
(15, 6)表示该滤波器由15个串联的双二次节组成,每个节由六个系数描述。 - Scale — 每个节的缩放向量。
(16, 1)的尺寸表明,除了15个级外,还添加了一个额外的缩放系数。
这种结构(双二次级级联)是实现高阶滤波器的标准方法,可确保数值稳定性。
频率响应计算函数
该函数用于计算级联滤波器的复传输系数:
-
针对给定频段内的每个频率,计算其归一化角频率
omega -
复变量
z = exp(1im * omega)对应于Z平面单位圆上的一个点 -
针对每个级,计算其传递函数,形式为:
-
总传递系数通过将所有环节的传递函数与最终缩放系数相乘而得
function biquad_freq_response(SOS, Scale, freqs, fs)
n_sections = size(SOS, 1)
n_freqs = length(freqs)
H = ones(ComplexF64, n_freqs)
for i in 1:n_sections
b0, b1, b2, a0, a1, a2 = SOS[i, :]
for j in 1:n_freqs
omega = 2π * freqs[j] / fs
z = exp(1im * omega)
H_section = (b0 + b1/z + b2/z^2) / (a0 + a1/z + a2/z^2)
H[j] *= H_section
end
end
H .*= prod(Scale)
return H
end
计算范围为0至24 MHz(48 MHz采样频率的一半),分辨率为1024个采样点。
Scale_vec = vec(Scale)
fs = 48000000
n_freqs = 1024
freqs = range(0, fs/2, length=n_freqs)
H = biquad_freq_response(SOS, Scale_vec, freqs, fs)
magnitude = 20*log10.(abs.(H))
phase = rad2deg.(angle.(H))
display(plot(freqs, magnitude, xlabel="频率(赫兹)", ylabel="振幅(dB)", title="滤波器的频率响应曲线"))
display(plot(freqs, phase, xlabel="频率(赫兹)", ylabel="相位(度)", title="滤波器的频率响应"))
根据图表可以得出以下几点结论:
-
带外抑制效果显著: 频率响应曲线在通带之外迅速衰减。这表明滤波器具有极佳的选择性——非目标频率的信号几乎被完全抑制。
-
通带内零衰减: 在频率响应曲线的峰值处,数值接近 0 dB(约为 10⁻⁸ dB),这意味着有用信号几乎无衰减地通过。
-
相位偏移非线性: 在通带内观察到复杂的相位行为,这是高阶滤波器的典型特征。 这会导致信号产生一定的相位失真,但对于仅分析包络振幅的非相干检测而言,相位失真并不关键。
.png)
BFSK信号的解调(模块FSK Demodulator )实现了基于带通滤波器的非相干检测器。该方法无需精确知道载波相位,从而简化了实现。
解调器的工作算法包括以下步骤:
- 输入的BFSK信号并行输入到两个乘法器(Product)中。
- 形成两个不同频率的并行通道:
- 在上行信道中,信号与频率为“1”的参考振荡信号相乘(
Carrier Mark Freq1)。乘积包含低频分量(与相位差的余弦成正比)和高频谐波。 - 在下通道中,信号与频率为“0”的参考振荡信号相乘(
Carrier Space Freq1)。
- 在上行信道中,信号与频率为“1”的参考振荡信号相乘(
- 乘法器输出的信号进入相同的带通滤波器(
Biquad Filter和Biquad Filter-1)。 这些滤波器起着关键作用:- 它们抑制乘法过程中产生的高频分量。
- 其通带经过调谐,旨在精确提取与该信道对应的频率。 实际上,每个滤波器都像一个包络检测器一样工作。在滤波器输出端,我们得到的信号振幅与滤波器调谐频率下输入信号的振幅成正比。
- 放大与比较:
- 经过滤波的信号以不同的增益系数(Gain)进行放大,以补偿损耗并将信号范围调整到便于比较的水平。
- 随后,信号被送入减法器。
- 最终的差分信号被送至控制端口
Switch。- 若差值
> 0(即通道“1”的能量大于通道“0”),则开关向输出端输出值“1”。 - 否则,若差值
< 0,则输出“0”。
- 若差值
- 由此生成的数字信号(
Demodulated Signal)与原始传输序列相对应。
接下来,我们运行模型。
.png)
function run_model( name_model)
Path = (@__DIR__) * "/" * name_model * ".engee"
if name_model in [m.name for m in engee.get_all_models()]
model = engee.open( name_model )
model_output = engee.run( model, verbose=true );
else
model = engee.load( Path, force=true )
model_output = engee.run( model, verbose=true );
engee.close( name_model, force=true );
end
sleep(0.1)
return model_output
end
run_model("Binary_FSK")
现在依次提取模拟结果:
- Input_Signal - 原始比特序列。
- Modulated_Signal - 生成的BFSK信号。
- filt_1_minus_filt_2 - 经过滤波后的差分信号。
- Demodulated_Signal - 复原的数字信号。
Input_Signal = (collect(simout["Binary_FSK/Signal From Workspace.1"]).value)
Input_Signal = [x for subvec in Input_Signal for x in subvec]
println("Input_Signal: $Input_Signal")
BFSK调制器的工作原理极其简单,它像一个受控开关一样工作:
- 调制器输入端接收到数字信号
Digital Data(比特序列:0和1)。 - 调制器包含两个谐波信号发生器(Sine Wave):
*Carrier Mark Freq:生成频率与逻辑“1” (标记频率)。在本模型中,该频率为 (f_1),其周期为每时钟周期 5 次(Samples=5)。
*Carrier Space Freq:生成频率与逻辑“0”相对应的信号(间隔频率)。 在本模型中,该频率为 ( f_2 ),其周期在每个时钟周期内可重复 5 次(采样数=50)。 - 控制信号
Digital Data输入到开关的控制端口,调制器输出端形成可直接传输的 BFSK 信号。
.png)
下图展示了针对本比特序列的调制信号波形。
Modulated_Signal = (collect(simout["Binary_FSK/FSK Modulator.Modulated Signal"]).value)
Modulated_Signal = [x for subvec in Modulated_Signal for x in subvec]
println("Input_Signal: $Input_Signal")
plot(Modulated_Signal)
filt_1_minus_filt_2 信号是解调器中“1”和“0”通道经过滤波后的分量之差。 其波形由以下因素决定:
-
比特切换会导致正负区域之间发生剧烈跳变,这对应于传输符号的变化。
-
滤波器的惯性(系统记忆效应)会在每次切换后产生衰减振荡,这可归因于滤波器的有限通带宽度(从频率响应曲线中可见)。
-
符号间干扰源于前几个比特的响应叠加,这使得信号波形变得复杂。
关键点:解调时并非使用整个复杂的信号波形,而是仅使用采样时刻的符号,这使得能够唯一地重建原始比特序列。
filt_1_minus_filt_2 = (collect(simout["Binary_FSK/FSK Demodulator/Add.1"]).value)
filt_1_minus_filt_2 = [x for subvec in filt_1_minus_filt_2 for x in subvec]
println("Input_Signal: $Input_Signal")
plot(filt_1_minus_filt_2)
如我们所见,最终输入比特序列被无误地解码。
Demodulated_Signal = (collect(simout["Binary_FSK/FSK Demodulator.Demodulated Signal"]).value)
Demodulated_Signal = [x for subvec in Demodulated_Signal for x in subvec]
println("Input_Signal: $Input_Signal")
println("Demodulated_Signal: $(Demodulated_Signal[2:1100:end])")
display(plot(Demodulated_Signal))
结论
通过上述工作,成功创建并测试了采用二进制频移调制 (BFSK)通信系统的仿真模型已成功建立并经过测试。通过比较发送([1, 0, 0, 1, 0] )和接收的序列,证实了所开发的解调方案在理想通信信道条件下能够正确恢复原始数据。 这一结果证实了所提出的双平方滤波器级联架构的可行性,以及系统参数选择的正确性,这为进一步复杂化该模型奠定了基础,例如通过在通信信道中添加噪声来评估抗噪性能。