FIR滤波器:窗函数法

发布于:2025-02-10 ⋅ 阅读:(48) ⋅ 点赞:(0)

一、FIR滤波器基础

FIR(有限脉冲响应)滤波器的三大特点:

  1. 绝对稳定:没有反馈回路,不会出现失控振荡

  2. 线性相位:信号通过后波形不失真

  3. 直观设计:通过窗函数法、频率采样法等方法实现

二、窗函数法原理

设计步骤解析

  1. 理想滤波器:先画出想要的矩形频率响应

  2. 时域截断:用窗函数"剪裁"无限长的理想脉冲响应

  3. 频域修正:通过选择不同窗函数优化性能

经典窗函数对比

三、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, '原始信号']);


网站公告

今日签到

点亮在社区的每一天
去签到