雷竞技注册
技术文章

Scilab中的数字信号处理:如何解码FSK信号

2018年9月25日通过罗伯特Keim

了解一种从解调的移频键控基带信号中提取原始数字数据的DSP技术。

了解一种从解调的移频键控基带信号中提取原始数字数据的DSP技术。

相关信息

基于scilab的数字信号处理以前的文章

一种用于在正弦波形中编码二进制数据的方法叫做频移键控(FSK)。这是一个简单的概念:一个频率代表0,另一个频率代表1。例如:

一个低频FSK信号(比如说,数万赫兹)可以被转移到一个更高的频率,然后传送。这是创建实现数字数据无线传输的射频系统的一种有效且相当直接的方法——假设我们有一个可以将所有这些正弦波形转换为1和0的接收器。

从发送的FSK信号中提取数字数据的过程可以分为两个一般任务:首先,将接收到的高频信号转换为低频基带信号。我称之为“解调”。第二,基带波形必须转换为1和0。我不认为将第二步称为“解调”是错误的,但为了避免混淆,当我谈到将低频模拟波形转换为数字位时,我总是使用“解码”这个术语。

解码软件

对于中等数据速率的系统,将FSK基带信号数字化并通过软件进行解码是完全可行的。你可以看看我们的软件无线电简介有关在软件中执行重要信号处理任务的射频系统的更多信息。)在我看来,这是一个很好的方法,因为它允许接收器受益于数字信号处理的通用性,而且它也提供了一个方便的方法来记录和分析测试期间接收的信号。

在本文中,我们将使用Scilab来解码FSK信号,但是所涉及的计算并不复杂,可以很容易地在数字信号处理器中以C代码的形式实现。

最重要的是:数学

我们的FSK解码技术是基于正弦信号的乘法。考虑下列三角恒等式:

$ $ \ sin (x) * \罪(y) = \压裂{1}{2}(\ cos (x - y) - \ cos (x + y)) $ $

$ $ \ cos (x) * \ cos (y) = \压裂{1}{2}(\ cos (x - y) + \ cos (x + y)) $ $

让我们用ω让它更符合工程世界1t和ω2用T代替x和y。

$ $ \罪(\ omega_1t) * \罪(\ omega_2t) = \压裂{1}{2}(\ cos ((\ omega_1 - \ omega_2) t) - \ cos ((\ \ omega_2 omega_1 +) t)) $ $

$ $ \ cos (\ omega_1t) * \ cos (\ omega_2t) = \压裂{1}{2}(\ cos ((\ omega_1 - \ omega_2) t) + \ cos ((\ \ omega_2 omega_1 +) t)) $ $

(注意,我们忽略了相位效应差异;在本文中,我们假设所有信号的相位相等。)我们可以将两个正弦波或两个余弦波相乘,结果由两个余弦波组成,其频率等于两个原始频率的和和之差。这里的关键观察是cos((ω1- - - - - -ω2)t)波形将有一个非常频率,如果两个输入波有一个非常类似的频率。在理想的数学领域中,我们可以输入两个频率相同的波形和cos((ω)1- - - - - -ω2)t)变成cos0t = cos0 = 1。因此,如果我们将两个频率相同的正弦波或余弦波相乘,得到的波形将有一个相对较大的直流偏移。

在FSK解码的背景下,我们可以这样说:即使频率是相似的,而不是相同的,仍然会有很大的直流偏置,因为cos((ω1- - - - - -ω2(t)波形将从1开始并缓慢下降相对于一个比特周期.位周期是编码一个数字位所需的时间量;在上图中,位周期对应于二进制0频率的一个周期(或二进制1频率的三个周期)。包含在一个比特周期内的模拟波形的那部分称为符号。在本文中,我们使用二进制(即双频)FSK,因此一个符号对应一个数字位。可以使用两个以上的频率,这样一个符号可以传输多个比特。

解码FSK,一步一步

现在我们有了制定FSK解码程序所需的信息:

  1. 对接收的基带信号进行数字化处理。
  2. 确定位周期的开始。这可以在训练序列的帮助下完成;有关更多信息,请单击在这里向下滚动到“数据包剖析”部分的“序言”标题。对于本文,我们假设数据被编码为正弦波(如上图所示)而不是余弦波。
  3. 每个符号乘以一个频率为0的正弦波和频率为1的正弦波。
  4. 计算每个符号的直流偏移量。
  5. 选择一个阈值,并根据符号的直流偏移量是否高于或低于阈值在二进制0和二进制1之间进行判断。

Scilab的实现

我们将开始生成二进制0频率(10 kHz)和二进制1频率(30 kHz)的单符号正弦波形。

ZeroFrequency = 10 e3;OneFrequency = 30 e3;SamplingFrequency = 300年e3;Samples_per_Symbol = SamplingFrequency / ZeroFrequency;n = 0: (Samples_per_Symbol-1);Symbol_Zero = sin(2*%pi*n / (SamplingFrequency/ zeroffrequency));Symbol_One = sin(2*%pi*n / (SamplingFrequency/ onfrequency));plot(n, Symbol_Zero)

现在让我们创建接收的基带信号。我们可以通过连接来实现Symbol_ZeroSymbol_One数组;我们将使用序列0101:

ReceivedSignal = [Symbol_Zero Symbol_One Symbol_Zero Symbol_One];情节(ReceivedSignal)

接下来,我们将接收信号中的每个符号乘以二进制0符号的波形和二进制1符号的波形。我们通过连接来完成这一步Symbol_ZeroSymbol_One数组根据接收信号中的符号数,然后采用逐元素乘法;指这篇文章参阅Scilab(或MATLAB)中元素乘法的更多信息。

Decoding_Zero = ReceivedSignal .* [Symbol_Zero Symbol_Zero Symbol_Zero Symbol_Zero Symbol_Zero];Decoding_One = ReceivedSignal .* [Symbol_One Symbol_One Symbol_One Symbol_One];情节(Decoding_Zero)

情节(Decoding_One)

不要被这些相当复杂的波形分心;我们感兴趣的是直流偏移,用数学术语来说就是平均值。如果我们想要显示每个符号对应的DC偏移量,首先需要生成一些新的数组:

for k=1:(length(Decoding_Zero)/Samples_per_Symbol) > SymbolOffsets_Zero(((k-1)*Samples_per_Symbol)+1:k*(Samples_per_Symbol)) = mean(Decoding_Zero(((k-1)*Samples_per_Symbol)+1:k*(Samples_per_Symbol)));> end for k=1:(length(Decoding_One)/Samples_per_Symbol) > SymbolOffsets_One(((k-1)*Samples_per_Symbol)+1:k*(Samples_per_Symbol)) = mean(Decoding_One(((k-1)*Samples_per_Symbol));>结束

您可能需要仔细考虑一下这些命令,以便准确地理解我在做什么,但基本思想如下:for循环用于一次执行一个符号Decoding_ZeroDecoding_One数组。在SymbolOffsets_ZeroSymbolOffsets_One数组中,与一个符号对应的所有数据点都用该符号的平均值填充Decoding_ZeroDecoding_One数组。每个符号有30个样本,所以第一个命令对数组值1到30进行操作,下一个命令对数组值31到60进行操作,以此类推。结果如下:

情节(SymbolOffsets_Zero)

情节(SymbolOffsets_One)

SymbolOffsets_Zero阵列向我们展示了由接收基带符号与二进制0频率相乘产生的直流偏移量,以及SymbolOffsets_One阵列向我们显示了由接收基带符号与二进制1频率相乘产生的直流偏移量。我们知道,将两个相似的频率相乘会产生一个相对较大的直流偏置。因此,在SymbolOffsets_Zero数组表示接收的符号是二进制0,并且在SymbolOffsets_One数组表示接收到的符号是二进制1。

结论

本文提出了一种FSK译码的数学方法。这个过程是在Scilab中实现的,但将Scilab命令转换成高级编程语言(如c)并不困难。在下一篇文章中,我们将继续研究FSK解码。

1评论