FIR滤波器窗函数选型:主瓣、旁瓣与阻带衰减的工程取舍 做FIR滤波器设计的人大多遇到过这种尴尬指标算得清楚阶数也够代码里一行firwin就把系数拿到了频谱上看阻带明明压到了 -60 dB可把滤波器塞进实际链路一跑底噪还是从某个频段漏了进来。回头查通带平的查阻带深得吓人再查阶数也没缩水。最后把频响图放大到 120 dB 量程才看见阻带靠近过渡带那一段是干净的可再往外走旁瓣又翘起来了像退潮后露出的礁石。这个问题十有八九出在窗函数上。FIR滤波器的设计里窗函数不是可有可无的装饰参数它直接决定了你的阻带是看起来很干净还是真的干净。同样 101 阶的低通把hamming换成blackman阻带能从 -53 dB 拉到 -74 dB代价是过渡带宽度从 3.3/N 涨到 5.5/N几乎翻倍。选窗这件事本质上是在主瓣宽度和旁瓣电平之间做一笔精确的交换交换比率事先就有账可算。这篇内容想聊的就是这笔账怎么算。适合已经会用firwin或fir1、但对自己为什么选这个窗说不清楚的读者也适合被旁瓣泄漏、通带纹波、群延迟这几个问题轮流折磨过的工程实践者。下面会从一次真实排查讲起把常见窗函数的硬指标摊开对照再给一套从规格书推到系数的完整流程最后聊几个反复踩到的坑。1. 一次指标达标但实测不合格的排查把窗函数问题翻了出来1.1 现象通带平坦、阻带够深噪声却还是从缝里漏进来几年前做一个传感器信号调理链路采样率 8 kHz需要一个低通把 1.5 kHz 以上的成分压掉通带截止 1 kHz阻带衰减要求 60 dB。当时用firwin配汉明窗算出来阶数 67频率响应跑出来阻带最低点 -63 dB看着富余 3 dB就下了板。结果实测发现2.2 kHz 附近有一根来路不明的窄带干扰幅度不大但正好落在信号带外不该出现的位置。把滤波器的频响拉到对数坐标上逐点看1.5 kHz 到 3 kHz 这一段确实在 -60 dB 以下可从 3.2 kHz 往 4 kHz 走旁瓣电平慢慢爬升到 -48 dB 左右。那根干扰恰好撞在第三个旁瓣的峰上。问题的根子在于汉明窗的一个特性它的第一旁瓣确实低到 -42.7 dB非常漂亮但它的旁瓣衰减速率只有大约 -6 dB/oct跟矩形窗一个量级。因为汉明窗的表达式0.54 - 0.46cos(2πn/(N-1))里那个 0.54 的常数项不为零它对应频域里的一个冲激分量会跟 sinc 型主瓣卷积把远端旁瓣托起来。汉宁窗的第一旁瓣只有 -31.5 dB比汉明差但它的衰减速率是 -18 dB/oct远端旁瓣掉得飞快。这就是典型的只看第一旁瓣、忽略衰减速率选错窗。汉明在高频段的表现反而不如看起来更温和的汉宁。1.2 理想低通被截断之后到底发生了什么要理解为什么会这样得回到窗函数法的出发点。理想低通的频率响应是一个矩形冲激响应是sinc函数$$h_{ideal}[n] \frac{\sin(\omega_c n)}{\pi n}$$这个序列有两个致命问题无限长而且非因果。工程上必须截断取中间 N 个点。截断这个动作在数学上等价于把理想冲激响应乘以一个长度为 N 的矩形窗。时域相乘对应频域卷积。理想矩形频率响应跟矩形窗的频谱做卷积结果就是通带和阻带边缘出现振铃。矩形窗的频谱是 Dirichlet 核$$W(\omega) \frac{\sin(\omega N/2)}{\sin(\omega/2)}$$它的主瓣宽度正比于 1/N第一旁瓣在 -13.26 dB旁瓣包络按 1/ω 衰减。把它跟理想矩形卷积通带边缘会出现约 9% 的过冲这就是吉布斯现象。无论 N 取多大第一旁瓣永远是 -13 dB 左右只是主瓣变窄、振铃频率变高。换句话说靠加大阶数解决不了旁瓣问题只能靠换窗。换窗的思路是把矩形窗换成一个两端平滑衰减到零的窗这样截断处的跳变被抹平频域卷积的核旁瓣就低了。代价是主瓣变宽因为窗函数在时域被压窄的等效宽度变大了。这就是那笔交易的来源一点都不玄妙。1.3 窗函数的本质用主瓣宽度换旁瓣电平的一笔明码交易把所有窗函数的参数写在一起看会看到一个非常整齐的规律主瓣越宽的窗旁瓣越低旁瓣衰减越快的窗过渡带越宽。这不是巧合是傅里叶变换的不确定性原理在起作用时域能量越集中频域能量越分散反之亦然。矩形窗在时域最窄所有点权重都是 1等效于最硬的截断所以主瓣最窄旁瓣最高。布莱克曼窗在时域被余弦包络压得很软两端几乎归零所以旁瓣极低但主瓣宽度是矩形窗的三倍。工程上选窗就是在这个连续谱上找一个点让主瓣宽度刚好满足过渡带指标同时旁瓣电平刚好低于阻带要求。找这个点之前得先把四个关键参数想清楚。2. 选窗之前必须摆上桌的四个数2.1 主瓣宽度就是过渡带的汇率主瓣宽度决定了从通带到阻带要花多少频率资源。对长度为 N 的滤波器矩形窗主瓣宽度约 4π/N汉宁和汉明约 8π/N布莱克曼约 12π/N。换算成归一化到采样率的过渡带宽度也就是用 cycles/sample 表示常用经验值是矩形窗约 0.9/N汉宁窗约 3.1/N汉明窗约 3.3/N布莱克曼窗约 5.5/N这里的N是滤波器阶数加一也就是抽头数。举个例子采样率 8 kHz要求过渡带从 1 kHz 到 1.5 kHz归一化宽度是 500/8000 0.0625。如果用汉宁窗N ≈ 3.1 / 0.0625 ≈ 50取 51 个抽头就够。如果换成布莱克曼窗N ≈ 5.5 / 0.0625 88得取 89 个抽头。差了将近 40 个抽头在定点 DSP 上就是实打实的乘法周期。所以过渡带指标不是尽量窄一点更好而是越窄越贵。很多项目一开始把过渡带定得极窄最后发现阶数下不来只能降采样率或者改架构。指标阶段就该算一遍看这个窄度在当前窗下要付出多少阶数。2.2 旁瓣峰值与阻带衰减不是同一个概念这里有个特别容易混淆的点第一旁瓣电平不等于阻带最小衰减。滤波器的阻带衰减是通带边缘到阻带边缘这段过渡区之外频率响应能达到的最低电平。它受旁瓣峰值和衰减速率共同影响。汉明窗第一旁瓣 -42.7 dB但阻带最小衰减只有 -53 dB 左右因为合成后的阻带响应是第一旁瓣和主瓣拖尾叠加的结果不是简单的第一旁瓣数值。布莱克曼第一旁瓣 -58 dB阻带最小衰减能到 -74 dB。布莱克曼-哈里斯第一旁瓣 -92 dB阻带能做到 -109 dB。选窗的时候要看的指标是最小阻带衰减这一列而不是第一旁瓣那一列。前者才是你实测会看到的数字。还有一点阻带衰减是最差点不是平均值。有些窗比如切比雪夫窗是等波纹的阻带内所有旁瓣峰值都相等有些窗比如汉明第一旁瓣低但远端会翘起来最差点可能在频率较高处。做验证的时候不能只扫到 2 倍截止频率得把整个 0 到 Nyquist 都扫一遍。2.3 阶数、过渡带、阻带衰减的三角制约三者之间是硬约束关系动一个另外两个必然跟着变。可以把它们想成三角形的三条边你不能同时要求三条边都最短。实际项目里的取舍通常是这样的给定采样率和阻带衰减要求先算过渡带能接受多宽如果算出来的阶数超出算力预算就得回去改指标——要么放宽过渡带要么降采样率要么换用 IIR 或者多相结构。有个粗略的换算可以放在脑子里对窗函数法设计的 FIR阶数 N 与过渡带 Δf归一化和阻带衰减 AdB的关系凯泽给出的经验公式是$$N \approx \frac{A - 7.95}{14.36 \cdot \Delta f}$$这个式子对凯泽窗是精确的对其他窗是量级估计。用它做初步预算非常方便。比如 A 60 dBΔf 0.0625算出来 N ≈ 58取 59 个抽头。跟前面用汉宁窗估的 51 差不太多量级一致。知道了这个式子很多争论就能当场结束。有人说我要 80 dB 阻带过渡带还要 0.02 归一化宽度代入一算 N ≈ 250再问一句 DSP 一个采样周期能不能跑 250 次乘加答案通常就出来了。2.4 常见窗的硬指标对照表下面这张表是多年翻手册、跑仿真攒下来的数值取常用近似实际设计时以scipy.signal.get_window跑出来的频响为准。窗类型主瓣宽度近似第一旁瓣旁瓣衰减速率最小阻带衰减过渡带宽度矩形4π/N-13.3 dB-6 dB/oct21 dB0.9/N汉宁8π/N-31.5 dB-18 dB/oct44 dB3.1/N汉明8π/N-42.7 dB-6 dB/oct53 dB3.3/N布莱克曼12π/N-58 dB-18 dB/oct74 dB5.5/N布莱克曼-哈里斯16π/N-92 dB-6 dB/oct109 dB约 7.9/N平顶很宽-90 dB 量级慢不适用于滤波很宽切比雪夫由旁瓣电平定可指定等波纹等于指定值介于汉宁与布莱克曼之间凯泽由 β 定由 β 定由 β 定由 β 定由 β 与 N 共同决定看这张表有个细节值得留意汉宁和布莱克曼的衰减速率都是 -18 dB/oct汉明的却是 -6 dB/oct。这个差别在实际使用中比第一旁瓣数值更重要。如果你的干扰信号离截止频率比较远汉宁会比汉明更合适尽管它的第一旁瓣高了 11 dB。3. 主流窗函数逐个过一遍谁适合干什么活3.1 矩形窗只在不关心旁瓣的场合才成立矩形窗就是不加窗直接截断。它在 FIR 设计里几乎总是错误选择因为 21 dB 的阻带衰减实在太浅。但它有两个场合是对的。第一个是当你只需要一个粗略的低通、后续还有更强的滤波级时。比如在一个多级抽取链路的第一级先用矩形窗做一个简单的抗混叠预滤波把主要能量挡掉剩下的交给后级。这种情况下省下来的阶数比那点旁瓣泄漏更值钱。第二个是当你做频谱分析而不是滤波的时候。矩形窗在频域主瓣最窄频率分辨率最高适合分析稳定周期的谐波成分。但这跟 FIR 滤波器设计是两件事别混着用。我在实际项目里见过有人用矩形窗设计 200 阶低通理由是阶数高所以阻带深。这是误解。窗函数法的阻带衰减由窗的形状决定跟阶数无关。加到 2000 阶第一旁瓣还是 -13 dB。3.2 汉宁与汉明一个字符的差异决定了通带边缘的表现这两个窗名字只差一个字母公式也只差常数项但行为差别很大。汉宁窗w[n] 0.5 - 0.5cos(2πn/(N-1))两端严格归零一阶导数连续。频域主瓣宽 8π/N第一旁瓣 -31.5 dB衰减速率 -18 dB/oct。汉明窗w[n] 0.54 - 0.46cos(2πn/(N-1))两端不归零端点值是 0.08。这个不归零的设计是为了让第一旁瓣压到 -42.7 dB代价是衰减速率退化到 -6 dB/oct。选择逻辑很清楚如果干扰主要集中在截止频率附近用汉明如果干扰可能出现在整个阻带范围内用汉宁。做音频降噪、语音增强这类应用通常选汉宁因为人耳对宽带噪声更敏感。做单频干扰抑制比如工频 50 Hz 陷波选汉明更划算。还有一个不那么明显的差别汉明窗因为端点不归零通带边缘的纹波会比汉宁略小一点点。有些对通带平坦度极敏感的应用比如精密测量会因为这一点选汉明但差距通常在小数点后第二位不一定值得。3.3 布莱克曼族与 Nuttall拿主瓣换深阻带布莱克曼窗是三项余弦组合0.42 - 0.5cos(2πn/(N-1)) 0.08cos(4πn/(N-1))。主瓣宽 12π/N第一旁瓣 -58 dB衰减速率 -18 dB/oct最小阻带衰减约 74 dB。它是深阻带 快速衰减这个组合里性价比最高的选择之一。再往上走是四项、五项的余弦组合窗比如布莱克曼-哈里斯四项第一旁瓣 -92 dB、Nuttall四项旁瓣 -93 dB 量级、Blackman-Nuttall 等。这些窗的阻带能压到 -100 dB 以下但主瓣宽度是布莱克曼的 1.3 到 1.5 倍。用这类窗的典型场景是高动态范围系统24 位 ADC 采集、地震信号处理、雷达接收链路。这些系统本身的噪声地板就在 -110 dB 以下如果滤波器阻带只有 -60 dB泄漏会直接淹没真实信号。代价要算清楚。假设采样率 48 kHz要求过渡带 2 kHz 宽归一化宽度 0.0417。布莱克曼需要 N ≈ 5.5/0.0417 ≈ 132布莱克曼-哈里斯需要 N ≈ 7.9/0.0417 ≈ 190。多出 58 个抽头在嵌入式平台上可能就是跑得动和跑不动的区别。3.4 凯泽窗用一个参数把指标拧到位凯泽窗的特殊之处在于它不是固定的形状而是由参数 β 控制的连续族。β 0 时退化为矩形窗β 增大时主瓣变宽、旁瓣降低。这让你可以精确命中一个阻带指标而不是在几个固定窗之间跳。凯泽给出的经验公式这是工程上最常用的一组$$\beta \begin{cases} 0.1102(A - 8.7), A 50 \ 0.5842(A - 21)^{0.4} 0.07886(A - 21), 21 \le A \le 50 \ 0, A 21 \end{cases}$$$$N \approx \frac{A - 7.95}{14.36 \Delta f}$$其中 A 是目标阻带衰减dBΔf 是归一化过渡带宽度。举个例子A 70 dBΔf 0.05代入得 β 0.1102 × 61.3 ≈ 6.75N ≈ 62.15/0.718 ≈ 87取 87 个抽头。跑一下仿真阻带最低点通常在 -70 dB 上下误差在 1 到 2 dB 以内。凯泽窗的优点是指哪打哪缺点是它给出的阻带响应不是等波纹的靠近过渡带的旁瓣低远端旁瓣会略微抬升。如果系统对远端阻带特别敏感可能要在凯泽的基础上再加一级。3.5 平顶窗与切比雪夫窗等波纹与幅度精度两条路平顶窗的主瓣极宽第一旁瓣能到 -90 dB 以下通带内的幅度平坦度非常好波动在 0.01 dB 量级。它的典型用途不是滤波而是频谱校准和幅值测量——做 FFT 分析时平顶窗能保证不同频率的正弦分量测出来的幅度一致不会因为频率落在主瓣哪个位置而偏差。切比雪夫窗也叫 Dolph-Chebyshev 窗是另一条思路给定旁瓣电平它能让主瓣宽度最小。所有旁瓣峰值相等成等波纹分布。这在需要严格控制最大泄漏的场合很有用比如多载波系统里防止邻道干扰。scipy.signal.chebwin(N, at)的at参数就是旁瓣衰减值单位 dB。比如chebwin(101, 80)给出 101 点、旁瓣 -80 dB 的切比雪夫窗。它的过渡带介于汉宁和布莱克曼之间阻带严格等于指定值。用切比雪夫窗要小心一点等波纹意味着阻带内处处都顶在指标线上没有余量。实测定点量化之后某些点可能刚好突破指标。建议在设计值上留 3 到 6 dB 余量。3.6 DPSS能量集中度的理论最优解DPSS离散长球序列也叫 Slepian 窗是另一个方向的最优给定主瓣宽度它能让主瓣内的能量占比最大。scipy.signal.windows.dpss(M, NW)里的 NW 参数控制时间带宽积NW 越大主瓣越宽、旁瓣越低。DPSS 在频谱估计领域用得比较多做滤波器设计时用得少因为它的旁瓣衰减不是单调的形状不太可控。但在一些极端场景下它有用武之地比如需要极窄主瓣同时又要压住近端旁瓣的时候。4. 从规格书到滤波器系数一套能跑通的选型流程4.1 先把指标翻译成归一化过渡带规格书通常给的是绝对频率通带截止 1 kHz阻带起始 1.5 kHz采样率 8 kHz。第一步全部归一化到采样率通带截止1000/8000 0.125阻带起始1500/8000 0.1875过渡带宽度0.0625截止频率取中点0.15625取中点是实操里的关键细节。firwin的cutoff参数定义的是 -6 dB 点线性幅度下降到 0.5 的频率如果把它设在通带截止处通带边缘会提前开始衰减如果设在阻带起始处阻带起点会被推后。取中点让通带和阻带各承担一半的过渡损失是最稳的做法。4.2 凯泽公式算初值别当最终答案拿到归一化指标后先用凯泽公式估一版再跑仿真回调。下面这段代码做了完整流程import numpy as np from scipy import signal def design_lowpass(fs, f_pass, f_stop, a_stop, beta_margin0.0): delta_f (f_stop - f_pass) / fs fc (f_pass f_stop) / 2 A a_stop beta_margin if A 50: beta 0.1102 * (A - 8.7) elif A 21: beta 0.5842 * (A - 21) ** 0.4 0.07886 * (A - 21) else: beta 0.0 N int(np.ceil((A - 7.95) / (14.36 * delta_f))) if N % 2 0: # 保证奇数长度得到 Type I 线性相位 N 1 taps signal.firwin(N, fc, window(kaiser, beta), fsfs) return taps, N, beta fs, f_pass, f_stop, a_stop 8000, 1000, 1500, 60 taps, N, beta design_lowpass(fs, f_pass, f_stop, a_stop) print(fN{N}, beta{beta:.4f}) w, H signal.freqz(taps, worN16384, fsfs) mag_db 20 * np.log10(np.abs(H) 1e-12) pass_mask w f_pass stop_mask w f_stop print(通带最大衰减: %.2f dB % (-mag_db[pass_mask].min())) print(阻带最小衰减: %.2f dB % (-mag_db[stop_mask].max()))跑出来通常会发现阻带刚好卡在 60 dB 附近可能富裕 1 到 2 dB也可能差 0.5 dB。差的时候别急着加阶数先把beta_margin加 3 dB 再试往往就够了。加阶数改变的是过渡带加 β 改变的才是阻带深度这个因果链要分清楚。4.3 换几种窗横向对比用数据说话定下阶数之后可以拿同样的 N 换几种窗跑一遍看频响差在哪里。这段代码一次跑出四种窗的对比windows [hann, hamming, blackman, (kaiser, beta)] for wname in windows: taps signal.firwin(N, (f_pass f_stop) / 2, windowwname, fsfs) w, H signal.freqz(taps, worN16384, fsfs) mag 20 * np.log10(np.abs(H) 1e-12) stop -mag[w f_stop].max() # 找到实际过渡带从 -3 dB 到 -a_stop 的频率跨度 idx3 np.where(mag -3)[0][0] idxa np.where(mag -a_stop)[0] bw (w[idxa[0]] - w[idx3]) if len(idxa) else float(nan) label wname if isinstance(wname, str) else kaiser print(f{label:10s} 阻带{stop:6.2f} dB 过渡带{bw:8.1f} Hz)同一阶数下汉宁的过渡带最窄但阻带只有 44 dB 左右布莱克曼阻带最深但过渡带宽出 70%凯泽介于两者之间且能通过 β 微调。这张对比表拿给评审看比嘴上说我觉得布莱克曼比较好有说服力得多。4.4 定点量化之后必须再验一次浮点仿真通过不等于定点能过。把系数缩放到 16 位整数乘以 32767 再取整量化误差会在频域形成一层噪声地板典型值在 -90 dB 量级但会随系数动态范围变化。scale 32767 q np.round(taps / np.max(np.abs(taps)) * scale).astype(np.int16) taps_q q.astype(np.float64) / scale w, H signal.freqz(taps_q, worN16384, fsfs) mag_q 20 * np.log10(np.abs(H) 1e-12) print(量化后阻带: %.2f dB % (-mag_q[w f_stop].max()))实测下来16 位量化通常让阻带衰减恶化 2 到 5 dB24 位则几乎无感。如果设计值只留了 1 dB 余量量化后大概率不达标。这就是前面反复强调留 3 到 6 dB 余量的原因。还要检查系数的动态范围。如果最大系数和最小非零系数差了几个数量级定点实现时小系数会被量化成零等效于滤波器阶数变短频响会整体走形。遇到这种情况要么提高位宽要么换一个系数分布更均匀的窗。5. 真实项目里反复踩到的五个坑5.1 只盯阻带衰减过渡带被悄悄挤爆这是最常见的。设计时盯着阻带指标调参调到 -70 dB 心满意足回头一看过渡带从 500 Hz 涨到了 900 Hz。如果系统里相邻信道只隔 600 Hz那就等于把邻道信号放进来了。规矩很简单两个指标必须同时打印出来一起看。前面那段对比代码里我特意把过渡带也算进去了就是为了防止这种单指标优化。5.2 忘记群延迟实时链路的时序对不上线性相位 FIR 的群延迟是 (N-1)/2 个采样点。N 101、采样率 8 kHz 时延迟是 50/8000 6.25 ms。单看不大但如果链路里串了三级 FIR再加上帧缓冲累积延迟很容易超过 20 ms语音通话里就能听出回声感。更麻烦的是多通道系统。如果不同通道用了不同阶数的滤波器通道间会出现固定的时间偏斜做波束形成或者相位比对时会直接失效。这种情况下要么统一阶数要么在数据通路上做延迟补偿。我个人的习惯是在设计文档里把群延迟当成一个必填项写进去跟通带、阻带并列。写下来就不会忘。5.3 窗长取偶数导致 Type II 的零点FIR 滤波器按对称性和长度分四类。偶数长度、偶对称的是 Type II它在 Nyquist 频率处一定有一个零点。这意味着 Type II 不能用来设计高通或带阻滤波器——在最高频率处增益恒为零高通根本做不出来。用firwin设计低通时这个问题不明显但设计高通时如果 N 取偶数scipy会直接报错或者给出一个奇怪的响应。解决方法是强制取奇数长度。上面代码里if N % 2 0: N 1这一行就是为了这个。设计带通、带阻时也要留意。带阻滤波器如果在 Nyquist 附近有阻带要求Type II 会在那个位置强制归零可能导致阻带指标虽然满足但通带高端被削掉一块。5.4 多通道滤波器组里窗的复用陷阱做信道化时经常把同一个原型低通搬移到不同中心频率上生成一组滤波器。这时候有人图省事所有通道共用一套系数只改调制频率。听起来合理实际上会出问题。原因是每个通道的过渡带要求可能不同。边带通道一侧紧邻 Nyquist另一侧对着邻道对称性被破坏用同一个对称原型会产生不一样的泄漏。正确做法是每个通道单独设计或者至少对边缘通道做特殊处理。还有一个细节调制之后系数的对称性会被破坏如果后续要做对称系数优化把乘法次数减半得在调制之前做不能在调制之后。5.5 把分析窗和设计窗搞混这个坑比较隐蔽。做 FFT 频谱分析时用的窗比如汉宁、平顶和设计 FIR 滤波器用的窗虽然名字一样、公式一样但用途完全不同。分析窗是加在待分析数据上的目的是减少频谱泄漏让 FFT 结果更接近真实频谱。设计窗是加在理想冲激响应上的目的是控制滤波器的频响形状。两者的参数选择逻辑也不一样分析窗主要看主瓣宽度和旁瓣衰减的平衡设计窗还要考虑过渡带、阶数、群延迟。见过有人在滤波器设计代码里直接调np.hanning(N)然后手动乘上去这本身没错但如果他以为这就是给信号加窗那后面的整条链路都会错位。概念上要分清楚一个是频域分析工具一个是时域设计工具。6. 几个典型场景的取舍我会怎么选6.1 音频降噪优先保通带平坦音频链路里人耳对通带内的纹波相当敏感0.5 dB 的波动在某些频段就能听出音色变化。这种情况下我会优先选通带平坦度好的窗汉明或者凯泽β 取小一点。阻带压到 -60 dB 通常够用因为音频系统的本底噪声很少低于这个量级。过渡带可以放宽一些因为音频信号的频谱能量集中在低频截止频率附近很少有强干扰。真要处理特定频率的啸叫单独加一级陷波器比把整条低通的过渡带压窄更划算。6.2 生物电信号低阶数优先于深阻带心电、脑电这类信号采样率通常不高250 Hz 到 1 kHz有效带宽很窄但要求相位失真小、延迟低。这种场景下阶数是稀缺资源因为每一阶都要在低功耗 MCU 上跑。我的选择通常是 3 到 4 阶的巴特沃斯 IIR 做主体滤波再用一个短 FIR31 到 51 阶汉宁窗做线性相位补偿或者工频陷波。纯 FIR 方案在 250 Hz 采样率下要压到 -60 dB 阻带汉宁窗需要 100 阶以上对 MCU 来说负担太重。如果必须用纯 FIR比如要求严格线性相位那就把阻带指标降到 -50 dB用汉明窗阶数能省下三分之一。6.3 通信信道化邻道泄漏是硬指标多载波系统里邻道泄漏比ACLR是硬性规范直接影响能不能入网。这种情况下阻带指标不能打折而且要看的是整个阻带的最差点不是靠近过渡带那一段。我的做法是用凯泽窗做初版跑出频响后看最差点在哪里。如果最差点在远端说明是旁瓣衰减速率不够换汉宁或者布莱克曼如果最差点在近端说明 β 不够加大 β 再跑。两三轮就能收敛。切比雪夫窗在这里也很好用因为它的等波纹特性正好对应规范的最大泄漏定义。但记得留余量前面说过。6.4 振动监测幅值精度比相位精度重要机械振动分析里关注的是各阶次的幅值用来做故障诊断。这种场景对相位不敏感但对幅值精度要求高因为要给报警阈值定标。窗的选择上我会优先考虑通带内幅度平坦度。平顶窗在这里其实是个不错的选择虽然它主瓣宽、过渡带大但通带内的幅度误差在 0.01 dB 量级测出来的振动幅值可以直接跟标准值比对。代价是阶数要加不少如果算力紧张退而求其次用凯泽窗β 取小值。另外这个场景下通常要保留原始数据做离线分析滤波器只是预处理。所以阻带指标可以放宽-50 dB 就够重点是把通带做平。实际操作里还有个细节振动信号往往有很强的低频分量比如转频如果滤波器通带边缘不够陡低频能量会漏到高频段造成虚假的边频成分。这种情况下要把过渡带做窄宁可加阶数。絮絮叨叨写了这么多其实核心就一句话窗函数不是个填空题是个算术题。主瓣宽度、旁瓣电平、衰减速率三个数摆在一起能算出阶数和过渡带剩下的就是按指标挑。我自己后来养成了一个习惯每设计一个 FIR先把这组数写在注释里写不出来就说明还没想清楚。这个习惯帮我省过好几次返工尤其是在指标改来改去、隔了几个月再回头看代码的时候注释里那几行数字比任何文档都好使。