当前位置: 首页 > news >正文

【DSP笔记 · 第5章】数字滤波器的蓝图:从数学公式到硬件实现的艺术

数字滤波器的蓝图:从数学公式到硬件实现的艺术

在前几章,我们已经领略了数字信号处理的魅力。在未来的章节(第六、七章),我们将深入学习如何设计一个滤波器——也就是根据需求,计算出一套神奇的数学系数,来“筛”出我们想要的信号。

但是,在拿到这套完美的系数(也就是滤波器的系统函数 H ( z ) H(z) H(z) 或差分方程)之后,我们面临一个更现实的问题:如何将这个数学公式,转化为可以在计算机软件或硬件芯片上高效运行的实际代码或电路?

这,就是数字滤波器网络结构要解决的问题。它就像建筑师(滤波器设计者)完成了宏伟的建筑设计图(系统函数)后,结构工程师(我们)需要绘制出具体的施工蓝图(网络结构),告诉施工队(CPU或FPGA)该如何用最少的材料(计算资源)、最稳固的方式(数值稳定性),把大楼盖起来。

今天,我们将一起探索这些“施工蓝图”。你会发现,同一个滤波器设计,可以有多种不同的实现结构,而选择哪一种结构,将直接影响到你的程序的运行效率、内存占用,甚至是最终结果的精度。

信号流图:滤波器的可视化语言

要讨论结构,我们首先需要一种通用的、可视化的语言来描述它。这就是信号流图(Signal Flow Graph)。它用非常简单的符号,就能清晰地表达出信号在滤波器内部的流动和处理过程。

一个信号流图主要由三种基本构件组成:

  1. 加法器 (Adder): 在图中用一个节点表示,所有指向它的信号在这里相加。
  2. 乘法器 (Multiplier): 在图中用一个带系数的支路表示,流过这条支路的信号会被乘以该系数。
  3. 单位延迟器 (Unit Delay): 在图中用一个标有 z − 1 z^{-1} z1 的支路表示。信号每经过一个延迟器,就会在时间上延迟一个采样周期。这在硬件上对应一个寄存器,在软件上对应数组中的上一个元素。

在这里插入图片描述

(上图展示了信号流图的三个基本构件:加法器、乘法器和单位延迟器)

有了这套语言,我们就可以开始绘制各种滤波器的“施工蓝图”了。我们将分别探讨IIR和FIR这两大家族的结构。

IIR滤波器:构建带有“记忆”的系统

IIR(无限脉冲响应)滤波器的特点是其差分方程中包含输出信号 y ( n ) y(n) y(n) 的反馈项。这意味着它的当前输出,不仅与当前和过去的输入有关,还与过去的输出有关。这种“记忆”或“反馈”特性,使得它的结构设计更为复杂,也更有趣。

一个通用的IIR系统函数如下:
H ( z ) = Y ( z ) X ( z ) = ∑ k = 0 M b k z − k 1 + ∑ k = 1 N a k z − k H(z) = \frac{Y(z)}{X(z)} = \frac{\sum_{k=0}^{M} b_k z^{-k}}{1 + \sum_{k=1}^{N} a_k z^{-k}} H(z)=X(z)Y(z)=1+k=1Nakzkk=0Mbkzk
其中, b k b_k bk 是前向路径的系数(零点相关), a k a_k ak 是反馈路径的系数(极点相关)。

直接型:最直观的翻译

直接型结构,顾名思义,就是将上述系统函数或其对应的差分方程“直译”成信号流图。

直接I型 (Direct Form I)

这是最朴素、最不假思索的实现方式。我们可以把 H ( z ) H(z) H(z) 看成两部分级联:一个只有分母(全极点)的系统 H 1 ( z ) H_1(z) H1(z) 和一个只有分子(全零点)的系统 H 2 ( z ) H_2(z) H2(z)

  1. 先实现 H 2 ( z ) H_2(z) H2(z):输入信号 X ( z ) X(z) X(z) 经过一系列延迟和乘法( b k b_k bk 系数),得到一个中间信号 W ( z ) W(z) W(z)
  2. 再实现 H 1 ( z ) H_1(z) H1(z):中间信号 W ( z ) W(z) W(z) 作为 H 1 ( z ) H_1(z) H1(z) 的输入,经过反馈环路( a k a_k ak 系数)的处理,得到最终输出 Y ( z ) Y(z) Y(z)

这种结构非常直观,但它有一个明显的缺点:延迟器是冗余的。全零点部分和全极点部分各自用了一套延迟器,总共需要 N + M N+M N+M 个。在硬件实现中,每一个延迟器都意味着一个存储单元,这无疑是一种浪费。

直接II型 (Direct Form II)

为了解决直接I型的浪费问题,聪明的工程师想到了一个绝妙的办法。既然两套延迟器链上的信号是一样的(都是中间信号的延迟版本),我们为什么不把它们合并呢?

于是,我们交换一下 H 1 ( z ) H_1(z) H1(z) H 2 ( z ) H_2(z) H2(z) 的顺序,让输入信号 X ( z ) X(z) X(z) 先经过全极点部分,再经过全零点部分。这样做之后,两条延迟器链就奇迹般地可以合并成一条了!

在这里插入图片描述

(上图清晰地对比了直接I型和直接II型结构。可以看到,直接II型通过交换零点和极点部分,将两串延迟器合并为一串,大大节省了存储资源。)

直接II型是IIR最经典的结构之一。它使用的延迟器数量为 max ⁡ ( N , M ) \max(N, M) max(N,M),是所有直接型结构中最少的,因此也被称为典范型(Canonical Form)。在软件实现(如MATLAB的filter函数)和教科书中,这是一种非常常见的结构。

但是,直接型有一个潜在的“致命”弱点:当滤波器的阶数很高时(比如N>4),系数 a k , b k a_k, b_k ak,bk 的微小量化误差(由于计算机使用有限字长存储)会被反馈环路不断放大,可能导致滤波器的极点偏离单位圆,从而使系统变得不稳定,或者频率响应严重偏离设计目标。这就像盖一栋超高层摩天大楼,如果地基有微小的沉降不均,到了顶层就会被放大成巨大的倾斜。

级联型:化整为零的智慧

为了解决高阶直接型结构的数值稳定性问题,我们引入了级联型(Cascade Form) 结构。

它的核心思想是 “分而治之”。我们不直接实现那个高阶的、敏感的系统函数 H ( z ) H(z) H(z),而是先在数学上将它因式分解成一系列低阶(通常是一阶或二阶)系统函数的乘积:
H ( z ) = G ⋅ H 1 ( z ) ⋅ H 2 ( z ) ⋯ H K ( z ) H(z) = G \cdot H_1(z) \cdot H_2(z) \cdots H_K(z) H(z)=GH1(z)H2(z)HK(z)
其中,每个 H k ( z ) H_k(z) Hk(z) 都是一个简单的二阶系统(也称为二阶节,Second-Order Section, SOS):
H k ( z ) = b 0 k + b 1 k z − 1 + b 2 k z − 2 1 + a 1 k z − 1 + a 2 k z − 2 H_k(z) = \frac{b_{0k} + b_{1k}z^{-1} + b_{2k}z^{-2}}{1 + a_{1k}z^{-1} + a_{2k}z^{-2}} Hk(z)=1+a1kz1+a2kz2b0k+b1kz1+b2kz2
然后,我们在硬件或软件上,将这些简单的二阶节的直接II型结构一个个串联起来,前一个的输出是后一个的输入。

在这里插入图片描述

(上图展示了一个级联型IIR滤波器结构,它由多个简单的二阶节(SOS)串联而成。)

为什么这样做更好?

  1. 提高数值稳定性:每个二阶节都是一个低阶系统,其系数的量化误差对极点位置的影响被限制在节内部,不会像高阶直接型那样被累积放大。这使得整个滤波器的性能对系数的精度不那么敏感。就像用预制好的、坚固的楼层模块来盖高楼,比从地基开始一点点往上浇筑要稳固得多。
  2. 模块化设计:这种结构非常适合模块化实现。你只需要设计和优化一个标准的二阶节模块,然后根据需要复制和串联它们即可。

在专业的DSP库和硬件实现中,级联型是实现高阶IIR滤波器的首选方法,因为它极大地改善了实际应用中的稳定性和精度问题。

并联型:多路并进的策略

除了级联,还有一种“分而治之”的策略,叫做并联型(Parallel Form)

这次,我们不是将 H ( z ) H(z) H(z) 分解为乘积,而是通过部分分式展开,将其分解为一系列简单系统函数的
H ( z ) = C + ∑ k = 1 K H k ( z ) H(z) = C + \sum_{k=1}^{K} H_k(z) H(z)=C+k=1KHk(z)
其中,每个 H k ( z ) H_k(z) Hk(z) 通常也是一个简单的一阶或二阶系统。

在实现时,输入信号 X ( z ) X(z) X(z) 同时送入所有并联的支路 H k ( z ) H_k(z) Hk(z),每个支路独立进行处理,最后将所有支路的输出相加,得到最终的输出 Y ( z ) Y(z) Y(z)

并联型结构同样具有很好的数值稳定性。它在某些特定的分析和设计(如控制系统中根据极点进行模式分解)中非常有用。不过,在通用的数字信号处理应用中,它的普及程度略低于级联型。

FIR滤波器:稳定可靠的“流水线”

与IIR不同,FIR(有限脉冲响应)滤波器没有反馈环路,它的输出只依赖于当前和过去的输入。这使得它的结构更加简单,并且天生稳定。你可以把它想象成一条“流水线”,信号从一端流入,经过一系列工位(延迟、乘法、加法)的处理,从另一端流出。

其系统函数是一个只包含分子的多项式:
H ( z ) = ∑ n = 0 N − 1 h ( n ) z − n H(z) = \sum_{n=0}^{N-1} h(n) z^{-n} H(z)=n=0N1h(n)zn
其中 h ( n ) h(n) h(n) 就是滤波器的系数。

直接型结构

FIR的直接型结构非常简单,就是对上述公式的直接翻译:输入信号经过一串 N − 1 N-1 N1 个延迟器,每个延迟器的输出(以及原始输入)分别乘以对应的系数 h ( n ) h(n) h(n),然后全部相加得到最终输出。这种结构也被称为横截型(Transversal) 结构。

线性相位结构:天才的优化

在关于FIR设计的博客中我们会讲到,FIR滤波器最大的魅力在于能实现线性相位,而实现线性相位的秘诀是其系数 h ( n ) h(n) h(n) 具有对称性,即 h ( n ) = h ( N − 1 − n ) h(n) = h(N-1-n) h(n)=h(N1n)

这个对称性,不仅带来了完美的相位特性,还为我们提供了一个绝佳的优化结构的机会!

思考一下,在一个直接型FIR结构中,如果系数 h ( 0 ) h(0) h(0) h ( N − 1 ) h(N-1) h(N1) 是相等的,我们为什么需要两个独立的乘法器来执行 x(n)*h(0)x(n-(N-1))*h(N-1) 呢?既然乘数一样,我们可以先把两个输入信号加起来,然后再做一次乘法!
x ( n ) ⋅ h ( 0 ) + x ( n − N + 1 ) ⋅ h ( N − 1 ) = [ x ( n ) + x ( n − N + 1 ) ] ⋅ h ( 0 ) x(n) \cdot h(0) + x(n-N+1) \cdot h(N-1) = [x(n) + x(n-N+1)] \cdot h(0) x(n)h(0)+x(nN+1)h(N1)=[x(n)+x(nN+1)]h(0)
这一步简单的代数变换,在硬件实现上是巨大的胜利!我们用一个加法器,换掉了一个乘法器。在数字电路中,乘法器通常比加法器占用更多的芯片面积、消耗更多的功率、运算速度也更慢。

通过利用系数的对称性,我们可以将延迟链“对折”,将对称位置的信号先相加,再共享一个乘法器。如果有一个长度N=7的线性相位FIR滤波器结构,通过把延迟链“对折”,对称位置的信号在乘法前相加,使得乘法器的数量从7个减少到了4个。

这种线性相位结构,可以将FIR滤波器的乘法器数量减少近一半!这对于需要在资源受限的嵌入式系统或追求高性能的FPGA上实现滤波器的工程师来说,是至关重要的优化。因此,只要是设计线性相位的FIR滤波器,几乎总会采用这种优化结构。

频率采样结构

除了直接型和线性相位结构,FIR还有一种比较特殊的结构,叫做频率采样结构。它的思路与我们在FIR设计中会提到的频率采样法相对应。

它将滤波器分解为一个梳状滤波器和一个并联谐振器组的级联。

  • 梳状滤波器 ( 1 − z − N 1 - z^{-N} 1zN) 在频域上产生了一系列等间隔的零点。
  • 并联的谐振器组则在这些零点的位置上放置极点,以“抵消”掉梳状滤波器的零点,并根据期望的频率采样值来设定增益。

这种结构在理论上很有启发性,因为它直观地将滤波器的实现与频域上的采样点联系了起来。在某些需要动态调整滤波器频响的应用中,它可能提供便利。但在通用滤波任务中,它的量化噪声特性不如直接型,且可能需要复数乘法,因此应用相对较少。

总结:结构的选择是一门艺术

我们今天走过了一趟数字滤波器内部的结构之旅。现在,让我们站在宏观的视角回顾一下:

  • 没有“最好”的结构,只有“最合适”的结构。你的选择取决于你的应用需求:是追求最低的计算成本,还是最高的数值精度?是在PC上用浮点数编程,还是在单片机上用定点数实现?
  • IIR滤波器结构
    • 直接II型:最节省延迟器,是理论分析和简单软件实现的基础。但对高阶系统,数值稳定性是隐患。
    • 级联型高阶IIR实现的首选。通过“分而治之”,大大提高了数值稳定性和对系数误差的鲁棒性。
    • 并联型:提供了另一种高稳定性的实现方式,在特定领域有其优势。
  • FIR滤波器结构
    • 直接型:最基础的实现,稳定可靠。
    • 线性相位型线性相位FIR实现的首选。利用系数对称性,节省了近一半的乘法器,是极致优化的典范。

理解了这些“施工蓝图”,你才真正掌握了从理论到实践的桥梁。当你拿到一个滤波器设计任务时,你不仅会思考“我需要一个什么样的频率响应?”,更会思考“我应该用哪种结构来实现它,才能在满足性能的同时,最大限度地节省资源?”。这就是从一个信号处理的“使用者”到“创造者”的转变。


习题

来吧,用几个小问题检验一下你是否已经掌握了这些“蓝图”的精髓。

第1题 (看图写函数)

一个直接II型IIR滤波器,反馈系数为 a 1 , a 2 a_1, a_2 a1,a2,前向系数为 b 0 , b 1 , b 2 b_0, b_1, b_2 b0,b1,b2),写出它的系统函数 H ( z ) = Y ( z ) / X ( z ) H(z) = Y(z)/X(z) H(z)=Y(z)/X(z)

第2题 (概念选择题)

你被要求在-一个资源非常有限的8位单片机上,实现一个10阶的IIR低通滤波器。你主要担心的问题是,有限的8位字长会导致系数存在较大的量化误差,可能会使滤波器变得不稳定。在这种情况下,你优先选择哪种实现结构?
A. 直接II型
B. 级联型
C. 频率采样型

第3题 (资源计算题)

一个线性相位FIR滤波器的脉冲响应为 h = [ 1 , 2 , 3 , 2 , 1 ] h = [1, 2, 3, 2, 1] h=[1,2,3,2,1]。如果使用直接型结构来实现,需要多少个乘法器?如果使用线性相位结构来实现,需要多少个乘法器?


答案

第1题答案:

首先,我们定义中心延迟链上的信号为 W ( z ) W(z) W(z)。我们可以得出:
W ( z ) = X ( z ) − a 1 z − 1 W ( z ) − a 2 z − 2 W ( z ) W(z) = X(z) - a_1 z^{-1} W(z) - a_2 z^{-2} W(z) W(z)=X(z)a1z1W(z)a2z2W(z)
整理得到 W ( z ) W(z) W(z) X ( z ) X(z) X(z) 的关系:
W ( z ) ( 1 + a 1 z − 1 + a 2 z − 2 ) = X ( z ) W(z)(1 + a_1 z^{-1} + a_2 z^{-2}) = X(z) W(z)(1+a1z1+a2z2)=X(z)

然后,根据流图的前向部分,写出输出 Y ( z ) Y(z) Y(z)
Y ( z ) = b 0 W ( z ) + b 1 z − 1 W ( z ) + b 2 z − 2 W ( z ) Y(z) = b_0 W(z) + b_1 z^{-1} W(z) + b_2 z^{-2} W(z) Y(z)=b0W(z)+b1z1W(z)+b2z2W(z)
整理得到 Y ( z ) Y(z) Y(z) W ( z ) W(z) W(z) 的关系:
Y ( z ) = ( b 0 + b 1 z − 1 + b 2 z − 2 ) W ( z ) Y(z) = (b_0 + b_1 z^{-1} + b_2 z^{-2}) W(z) Y(z)=(b0+b1z1+b2z2)W(z)

将两个式子联立,消去中间变量 W ( z ) W(z) W(z),即可得到系统函数 H ( z ) H(z) H(z):
H ( z ) = Y ( z ) X ( z ) = b 0 + b 1 z − 1 + b 2 z − 2 1 + a 1 z − 1 + a 2 z − 2 H(z) = \frac{Y(z)}{X(z)} = \frac{b_0 + b_1 z^{-1} + b_2 z^{-2}}{1 + a_1 z^{-1} + a_2 z^{-2}} H(z)=X(z)Y(z)=1+a1z1+a2z2b0+b1z1+b2z2

第2题答案:

B. 级联型

原因: 题目中的核心痛点是高阶(10阶)系统在资源受限(8位字长)平台上的数值稳定性问题。

  • 直接II型在高阶时对系数误差非常敏感,8位字长带来的量化误差很可能会使极点偏移到单位圆外,导致系统不稳定。
  • 级联型通过将10阶系统分解为5个独立的二阶节,将系数误差的影响限制在各个节内部,极大地增强了滤波器的鲁棒性和数值稳定性,是解决这个问题的标准方案。
  • 频率采样型本身对系数的量化也比较敏感,且不是IIR的标准结构。

第3题答案:

该FIR滤波器的长度 N = 5 N=5 N=5,脉冲响应为 h ( n ) h(n) h(n)
h ( 0 ) = 1 , h ( 1 ) = 2 , h ( 2 ) = 3 , h ( 3 ) = 2 , h ( 4 ) = 1 h(0)=1, h(1)=2, h(2)=3, h(3)=2, h(4)=1 h(0)=1,h(1)=2,h(2)=3,h(3)=2,h(4)=1
这是一个偶对称的线性相位FIR滤波器( h ( n ) = h ( 4 − n ) h(n) = h(4-n) h(n)=h(4n))。

  • 使用直接型结构:
    需要 N N N 个乘法器,即 5个 乘法器。

  • 使用线性相位结构:
    我们利用系数的对称性: h ( 0 ) = h ( 4 ) = 1 h(0)=h(4)=1 h(0)=h(4)=1, h ( 1 ) = h ( 3 ) = 2 h(1)=h(3)=2 h(1)=h(3)=2

    • 信号 x ( n ) x(n) x(n) x ( n − 4 ) x(n-4) x(n4) 相加后,与系数 h ( 0 ) = 1 h(0)=1 h(0)=1 相乘(1个乘法器)。
    • 信号 x ( n − 1 ) x(n-1) x(n1) x ( n − 3 ) x(n-3) x(n3) 相加后,与系数 h ( 1 ) = 2 h(1)=2 h(1)=2 相乘(1个乘法器)。
    • 中心的信号 x ( n − 2 ) x(n-2) x(n2) 自己与系数 h ( 2 ) = 3 h(2)=3 h(2)=3 相乘(1个乘法器)。
      总共需要的乘法器数量为 1 + 1 + 1 = ⌈ N / 2 ⌉ = ⌈ 5 / 2 ⌉ = 3 1 + 1 + 1 = \lceil N/2 \rceil = \lceil 5/2 \rceil = 3 1+1+1=N/2=5/2=3 个。
      所以,使用线性相位结构需要 3个 乘法器。

相关文章:

  • 时间序列数据库技术深度解析:核心原理与最佳实践
  • FWFW - Find Websites From World
  • GeoTools:gt-referencing模块
  • MVVM框架:让前端开发像搭积木一样简单!
  • 山东大学软件学院项目实训:基于大模型的模拟面试系统项目总结(九)
  • wifi架构
  • 2.5 Rviz使用教程
  • 平均数与倍数
  • Hashcat使用教程:快速上手密码恢复工具
  • 03.利用显卡内核模块等特性为算法提速百倍
  • 速度与精度的结合:Faster R-CNN模型的性能剖析
  • flask JWT 认证
  • IDEA—配置MySQL的驱动程序,引入jar包没有配置不成功问题解决
  • 访问vLLM启动的大模型,报错The model `XXX/XXX` does not exist
  • 嵌入式学习笔记 - HAL库对外设的封装
  • 【卫星通信】Skylo与ViaSat标准建议详解:基于NB-IoT NTN通过GEO卫星实现IMS语音通话的解决方案
  • 【卫星通信】3GPP标准提案:面向NB-IoT(GEO)场景的IMS信令优化方案-降低卫星通信场景下的语音呼叫建立时延
  • Python装饰器:优雅增强函数行为的艺术
  • import引入api报select.default is not a function异常解析
  • 细节致胜:如何重塑反向海淘用户体验
  • 织梦cms怎样做网站/自动点击器免费下载
  • 无锡微网站制作/免费推广的网站有哪些
  • 上海微网站建设/网络营销学什么
  • python做网站显示表格/网络营销推广专家
  • 网站专题制作教程/西安seo排名收费
  • 网站系统建设思想如何写/网站开发建站