FIR滤波器

news/2024/12/19 23:54:17/

1.原理

FIR滤波器是非递归型滤波器的简称,又叫有限长单位冲激响应滤波器。带有常系数的FIR滤波器是一种LTI(线性时不变)数字滤波器。冲激响应是有限的意味着在滤波器中没有发反馈。长度为N的FIR输出对应于输入时间序列x(n)的关系由一种有限卷积和的形式给出,具体形式如下:

                                                             

直接形式FIR滤波器图解:

                                                       

上式表达的是一个N-1阶的FIR滤波器,它有N个抽头(系数)。因此有N个乘法器,N-1个累加器组成。每一个抽头需要消耗逻辑资源的乘法器累加器( Mac )单元。

输入信号是有时间性的,随着时间的改变而改变,FIR滤波器最终的输出是各个时刻的输入乘以相应的权重(系数),然后进行叠加输出:

           


FIR数字滤波器“移动平均数”为例子:

“移动平均数”就是按我们事先设定的信号个数将输入信号加以平均。譬如,如果我们按每4个信号就做一次平均,那么这个4点的“移动平均数”滤波器就如下图所示:

                             

下图是经过11点和51点“移动平均数”滤波器过滤的信号图:

                                       

“移动平均数”滤波器的频率响应如下图所示:

                                       

如上图所示,随着点数的增加,滚降(ROLLOFF)变陡了,但对旁瓣(sidelobe,衰减部分)的高低影响不大。但是如果我们考虑对滤波器的每个系数采用不同的权重(加权),而不是像“移动平均数”滤波器那样,用相同的权重(1/4,对4点“移动平均数”滤波器来说),那么可以期待旁瓣的大小会大大的降低。

对系数采用不同权重的滤波器,我们可以用下面的数学公式来表达:

                              

2.FPGA实现fir滤波器

2.1在MATLAB中输入fdatool即可打开滤波器设计工具,如图7所示。里面可以设置滤波器的类型,采样频率,截止频率等。本设计设置的参数如图所示。

然后将此滤波器系数导出,然后用以下命令将系数放大、取整:

>> Num=round(Num*256)//将系数放大并取整

num=[ 5    17    43    63    63    43    17     5]; 

本设计用于仿真的输入波形是2个正弦波叠加而成,分别是5HZ、45HZ。

Fs = 1000; %采样频率决定了两个正弦波点之间的间隔
N = 256; %采样点数
N1 = 0 : 1/Fs : N/Fs-1/Fs;
s = cos(5*2*pi*N1) + cos(45*2*pi*N1) ;%
fidc = fopen('mem.txt','wb');  %将结果写入mem.txt文件,便于modesim使用for x = 1 : NA = round(s(x)*20);%放大if (A >= 0)bin_x = dec2bin(A, 8);        % 正数的反码和补码都和原码一样,转换位8位fprintf(fidc,'%s\n',bin_x);elsebin_x = dec2bin(2^8 + A, 8);fprintf(fidc,'%s\n',bin_x);end
end fclose(fidc);

2.verilog

module fir(clk,rst,din,dout,ordy);input clk;input rst;input [7:0] din;output [15:0] dout;output ordy;//matlab fir生成系数 * 256  该滤波器采样率为100Hz,截止频率为10Hzparameter coeff1=8'd5,coeff2=8'd17,coeff3=8'd43,coeff4=8'd63,coeff5=8'd63,coeff6=8'd43,coeff7=8'd17,coeff8=8'd5;//8个寄存器reg  signed [7:0]  sample_1;reg  signed [7:0]  sample_2;reg  signed [7:0]  sample_3;reg  signed [7:0]  sample_4;reg  signed [7:0]  sample_5;reg  signed [7:0]  sample_6;reg  signed [7:0]  sample_7;reg  signed [7:0]  sample_8;reg [18:0] dout;reg ordy;//输入数据,移位寄存always @(posedge clk )beginif(rst)beginsample_1 <= 8'd0;sample_2 <= 8'd0;sample_3 <= 8'd0;sample_4 <= 8'd0;sample_5 <= 8'd0;sample_6 <= 8'd0;sample_7 <= 8'd0;sample_8 <= 8'd0;endelsebeginsample_1 <= din;sample_2 <= sample_1;sample_3 <= sample_2;sample_4 <= sample_3;sample_5 <= sample_4;sample_6 <= sample_5;sample_7 <= sample_6;sample_8 <= sample_7;//8个周期完成移位endend//调用ip,执行乘法wire [15:0] p[8:1];mult_8 u1 (.CLK(clk),  // input wire CLK.A(sample_1),      // input wire [7 : 0] A.B(coeff1),      // input wire [7 : 0] B.P(p[1])      // output wire [15 : 0] P 设置pipline stage 为3,表示3级延时
);mult_8 u2 (.CLK(clk),  // input wire CLK.A(sample_2),      // input wire [7 : 0] A.B(coeff2),      // input wire [7 : 0] B.P(p[2])      // output wire [15 : 0] P
);mult_8 u3 (.CLK(clk),  // input wire CLK.A(sample_3),      // input wire [7 : 0] A.B(coeff3),      // input wire [7 : 0] B.P(p[3])      // output wire [15 : 0] P
);mult_8 u4 (.CLK(clk),  // input wire CLK.A(sample_4),      // input wire [7 : 0] A.B(coeff1),      // input wire [7 : 0] B.P(p[4])      // output wire [15 : 0] P
);mult_8 u5 (.CLK(clk),  // input wire CLK.A(sample_5),      // input wire [7 : 0] A.B(coeff5),      // input wire [7 : 0] B.P(p[5])      // output wire [15 : 0] P
);mult_8 u6 (.CLK(clk),  // input wire CLK.A(sample_6),      // input wire [7 : 0] A.B(coeff6),      // input wire [7 : 0] B.P(p[6])      // output wire [15 : 0] P
);mult_8 u7 (.CLK(clk),  // input wire CLK.A(sample_7),      // input wire [7 : 0] A.B(coeff7),      // input wire [7 : 0] B.P(p[7])      // output wire [15 : 0] P
);mult_8 u8 (.CLK(clk),  // input wire CLK.A(sample_8),      // input wire [7 : 0] A.B(coeff8),      // input wire [7 : 0] B.P(p[8])      // output wire [15 : 0] P
);//加法第一级wire [16:0] s1 [4:1];//加法器的延时为2add_16 a1 (.A(p[1]),      // input wire [15 : 0] A.B(p[2]),      // input wire [15 : 0] B.CLK(clk),  // input wire CLK.S(s1[1])      // output wire [16 : 0] S
);add_16 a2 (.A(p[3]),      // input wire [15 : 0] A.B(p[4]),      // input wire [15 : 0] B.CLK(clk),  // input wire CLK.S(s1[2])      // output wire [16 : 0] S
);add_16 a3 (.A(p[5]),      // input wire [15 : 0] A.B(p[6]),      // input wire [15 : 0] B.CLK(clk),  // input wire CLK.S(s1[3])      // output wire [16 : 0] S
);add_16 a4 (.A(p[7]),      // input wire [15 : 0] A.B(p[8]),      // input wire [15 : 0] B.CLK(clk),  // input wire CLK.S(s1[4])      // output wire [16 : 0] S
);//加法第二级wire [17:0] s2 [2:1];add_17 a21 (.A(s1[1]),      // input wire [16 : 0] A.B(s1[2]),      // input wire [16 : 0] B.CLK(clk),  // input wire CLK.S(s2[1])      // output wire [17 : 0] S
);add_17 a22 (.A(s1[3]),      // input wire [16 : 0] A.B(s1[4]),      // input wire [16 : 0] B.CLK(clk),  // input wire CLK.S(s2[2])      // output wire [17 : 0] S
);//加法第三级wire [18:0] s3;add_18 a31 (.A(s2[1]),      // input wire [17 : 0] A.B(s2[2]),      // input wire [17 : 0] B.CLK(clk),  // input wire CLK.S(s3)      // output wire [18 : 0] S
);//计数reg [4:0] counter;always @(posedge clk)beginif(rst)begincounter <= 5'd0;dout <= 19'd0;ordy <= 1'b0;endelse if(counter == 17)begindout <= s3;ordy <= 1'b1;endelsebegindout <= 19'd0;counter <= counter + 1'b1;endend
endmodule

由于抽头系数N=8,滤波的效果不是太好,可以采用更高阶数的fir滤波器,这里只是做个演示,有何错误之处还请指教!!


http://www.ppmy.cn/news/530779.html

相关文章

一欧元滤波器(OneEuroFilter)

引言 在查阅人脸关键点防抖动相关资料时&#xff0c;留意到一篇2012发布的防止抖动滤波器-----一欧元滤波器 链接 论文&#xff1a; Casiez, G., Roussel, N., & Vogel, D. (2012). 1€ filter: a simple speed-based low-pass filter for noisy input in interactive s…

数字滤波器

数字滤波器 前言传统数字滤波器比较专家观点现代数字滤波器推荐书籍功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表…

FARROW 滤波器

采样速率转换&#xff08;SRC&#xff09;在通信中非常普遍。一般有两种方法&#xff1a;一种是通过D/A重构信号&#xff0c;再采样&#xff0c;从而实现采样速率的转换&#xff1b;另一种是利用数字滤波器直接进行采样转换。数字滤波器有CIC&#xff0c;多相&#xff0c;FARRO…

数字滤波器--线性滤波(Linear Filter)

目录 一、什么是数字滤波器 二、数字滤波器的几个重要的基础概念 三、数字滤波器的基本单元 differentiator 差分器 Integrator 积分器 FIR滤波器 IIR滤波器&#xff08;无限冲击响应滤波器&#xff09; 一、什么是数字滤波器 Analog filter &#xff1a;滤波器从模拟时代产生…

FAIG滤波器

还是搬运者学习记 一切感恩于大佬 单分支网络如何自动学习区分退化&#xff1f;本文提出了一种盲超分网络解释的方法 FAIG&#xff0c;一种基于积分梯度的对 Filter 进行归因的方法。 发现盲超分模型中具有特定退化作用的滤波器 论文名称&#xff1a;Finding Discriminative…

Linux之快速入门和换源

目录 1.Linux的一些基本的语句 2.换源 1.Linux的一些基本的语句 mv 文件或者目录的改名或者移动以及修改文件名 pwd 查看用户当前目录 touch 新建文件 mkdir 新建文件夹 clear 清除屏幕 su 切换用户 mkdir -p 多个文件夹创建 cat 文件查看内容 mkdir -p {} 创建多成相同…

STM32F4 点亮灯泡【顺序点亮、按键点亮】

一、顺序点亮灯泡 ①初始化 在user.c文件中&#xff0c;我们需要对LED进行初始化设置。 在函数LED_GPIO_Config中&#xff0c;可以修改代码如下&#xff1a; /*********************************************************************** LED初始化 备注 LED 接在GPC14引脚上…

索尼爱立信手机摇杆失灵的维修方法

摇杆失灵的维修方法&#xff1a;本方法适用于各种带摇杆的各种手机&#xff0c;先关机&#xff0c;拆开前面板&#xff0c;拿下摇杆按钮&#xff0c;会看到有一个方形的手柄&#xff0c;按下摇杆&#xff0c;用竹签蘸取一点无水酒精&#xff0c;滴在摇杆的侧面&#xff0c;让它…