FIR滤波器:窗函数法
一、FIR滤波器基础
FIR(有限脉冲响应)滤波器的三大特点:
-
绝对稳定:没有反馈回路,不会出现失控振荡
-
线性相位:信号通过后波形不失真
-
直观设计:通过窗函数法、频率采样法等方法实现
二、窗函数法原理
设计步骤解析:
-
理想滤波器:先画出想要的矩形频率响应
-
时域截断:用窗函数"剪裁"无限长的理想脉冲响应
-
频域修正:通过选择不同窗函数优化性能
经典窗函数对比:
三、Matlab实现
%% 低通滤波器窗函数对比仿真
clc; clear; close all;
% ========== 参数设置 ==========
fs = 1000; % 采样率1kHz
t = 0:1/fs:1; % 时间序列(1秒)
f_clean = 50; % 基频信号频率
f_noise = 250; % 高频噪声频率
fc = 100; % 截止频率(Hz)
filter_order = 64; % 滤波器阶数
% ========== 生成测试信号 ==========
signal_clean = sin(2*pi*f_clean*t); % 纯净信号
signal_noise = 0.5*sin(2*pi*f_noise*t); % 噪声信号
signal = signal_clean + signal_noise; % 合成信号
% ========== 设计不同窗函数的滤波器 ==========
window_types = {'rectwin', 'hann', 'hamming', 'blackman', 'kaiser'};
filter_coeff = cell(1,5);
filtered_signals = zeros(5, length(signal));
for i = 1:length(window_types)
% 生成窗函数
if strcmp(window_types{i}, 'kaiser')
win = kaiser(filter_order+1, 5); % 凯塞窗(beta=5)
else
win = window(window_types{i}, filter_order+1);
end
% 设计滤波器
b = fir1(filter_order, fc/(fs/2), 'low', win);
filter_coeff{i} = b;
% 执行滤波
filtered_signals(i,:) = filter(b, 1, signal);
end
% ========== 可视化分析 ==========
% 时域信号对比
figure('Name','时域信号对比', 'Position',[100 100 1200 800])
subplot(3,1,1)
plot(t, signal)
title('原始含噪信号'), xlabel('时间(s)'), grid on
xlim([0 0.2]) % 显示前0.2秒细节
subplot(3,1,2)
hold on
for i = 1:5
plot(t, filtered_signals(i,:), 'LineWidth',1.2)
end
title('不同窗函数滤波结果'), xlabel('时间(s)')
legend(window_types), grid on
xlim([0 0.2])
subplot(3,1,3)
plot(t, signal_clean, 'k--', 'LineWidth',2)
title('理想纯净信号'), xlabel('时间(s)'), grid on
xlim([0 0.2])
% 频域响应对比
figure('Name','频率响应对比', 'Position',[100 100 1200 600])
colors = lines(5);
for i = 1:5
[h,f] = freqz(filter_coeff{i}, 1, 1024, fs);
subplot(2,1,1)
hold on
plot(f, 20*log10(abs(h)), 'Color',colors(i,:), 'LineWidth',1.5)
subplot(2,1,2)
hold on
plot(f, unwrap(angle(h))*180/pi, 'Color',colors(i,:), 'LineWidth',1.5)
end
subplot(2,1,1)
title('幅频特性'), ylabel('幅度(dB)'), grid on
xlim([0 fs/2]), ylim([-200 20])
line([fc fc], [-200 20], 'Color','k','LineStyle','--')
legend([window_types, '截止频率'])
set(gca, 'XScale','log')
subplot(2,1,2)
title('相频特性'), xlabel('频率(Hz)'), ylabel('相位(°)')
grid on, xlim([0 fs/2])
legend(window_types)
% 频谱对比
figure('Name','频谱分析', 'Position',[100 100 1200 400])
NFFT = 2^nextpow2(length(signal));
f = fs/2*linspace(0,1,NFFT/2+1);
hold on
for i = 1:5
Y = fft(filtered_signals(i,:), NFFT);
plot(f, 2*abs(Y(1:NFFT/2+1)), 'LineWidth',1.5)
end
% 计算原始信号的FFT
Y_original = fft(signal, NFFT);
Y_original = Y_original(1:NFFT/2+1); % 取单边频谱
% 绘制原始信号频谱
plot(f, 2*abs(Y_original), 'k--', 'LineWidth', 1.2);
title('信号频谱对比'), xlabel('频率(Hz)'), ylabel('幅度');
xlim([0 300]), grid on;
legend([window_types, '原始信号']);