-
v1.0
可编辑可修改
基于
MATLAB
的滤波器设计
由于
MATLAB
的广泛使用和功能的
不断更新,
基于
MATLAB
的滤波器
设计方法以其方便快捷的特点,
受到了设计者的欢迎。下面将举例说明基于
MATLAB
的
FIR
滤波
器的设计。
1
基于
FDATool
的
FIR
滤
波器设计
使用
FDATool
设计
FIR
滤波器的具体步骤如下:
滤波器指标
p>
若需要设计一个
16
阶的
< br>FIR
滤波器(
h(0)=0
)
,给定的参数如下:
(1)
低通滤波器
(2)
采样频率
F
S
为
48kHz
,滤波器
F
C<
/p>
为
(3)
输
入序列位宽为
9
位(最高位为符号位)
在此利用
MATLAB
来完成
FIR
滤波器系数的确定。
打开
MATLAB
< br>的
FDATool
MATLA
B
集成了一套功能强大的滤波器设计工具
FDATool
(
Filter Design & Analysis Tool<
/p>
)
,可
以完成多种滤波器的设计、分析和
性能评估。
单击
MATLAB
主窗口下方的
“
Start
< br>”
按钮,
如图所示,
选择菜单<
/p>
“
ToolBox
”
→
“
Filter
Design
”
→“
Filter Design & Analysis T
ool
(
FDATool
)
”命令,打开
FDATool
,如图所示。
1
v1.0
可编辑可修改
图
FDATool
的启动
图
FDATool
的主界面
另外,在<
/p>
MATLAB
主命令窗口内键入“
fda
tool
”
,同样可打开
FDAToo
l
程序界面。
2
v1.0
可编辑可修改
选择
Design
Filter
FDATool
界面左
下侧排列了一组工具按钮,其功能分别如下所述:
●
滤波器转换(
TransForm
Filter
)
●
设置量化参数(
Set Quantization
Parameters
)
●
实现模型(
Realize
Model
)
●
导入滤波器(
Import
Filter
)
●
多速率滤波器(
Multirate
Filter
)
●
零极点编辑器(
Pole-zero
Editor
)
●
设计滤波器(
Design
Filter
)
选择其中的按钮,进
入设计滤波器界面,进行下列选择,如图所示。
图
FDATool
设计
FIR
滤波器
●
滤波器类型(
Filer
Type
)为低通(
Low
Pass
)
●
设计方法(
Design Method
)为
FIR
,采用窗函数法(
Win
dow
)
●
滤波器阶数(
Filter
order
)定制为
15
●
窗口类型为
Kaiser
,
Beta
为
●
F
S
为
48kHz
,
F
C
为
3
v1.0
可编辑可修改
最后单击
Design Filter
图标,让
MATLAB
计算
FIR
p>
滤波器系数并作相关分析。
其系统函数<
/p>
H(z)
可用下式来表示:
H(z)=
?
b
k
z
?
k
k
?
1
16
显然上式可以写成
:
H(
z)=
z
?
1
?
b
z
k
k<
/p>
?
0
15
?
p>
k
?
1
即可以看成是一个
15
阶的
FIR
滤波器的输出结果经过了一个单位延时单元
z
,所以在
FDATool
中
< br>,
把它看成
15
阶
FIR
滤波器来计算参数。
滤波器分析
计算完
FIR
滤波器系数以后,
往往
需要对设计好的
FIR
滤波器进行相关的性能分析,
以便了解该
滤波器是否满足设计要求。分析操作步骤如下:
选择
FDATool
的菜单
“
Analysis
”→“
Magni
tude Response
”
,启动幅频响应分析如图所示,
x
轴为频率,
y
轴为幅度值(单位为
dB
)
。
图
FIR
滤波器幅频响应
在图的左侧列出了当前滤波器的相关信息:
●
滤波器类型为
Direct Form FIR
(直接
I
型
FIR
滤波器)
●
滤波器阶数为
15
< br>选择菜单“
Analysis
”→“
Phase Response
”
,启动相频响应分析,如
图所示。由该图可以看到
设计的
FIR
滤波器在通带内其相位响应为线性的,即该滤波器是一个线性相位的滤波器。
4
v1.0
可编辑可修改
图
滤波器相频响应
图显示了滤波器幅频
特性与相频特性的比较,这可以通过菜单“
Analysis
”
→“
Magnitude and
Phase
Response
”来启动分析。
图
滤波器幅频和相频响应
选择菜单“<
/p>
Analysis
”→“
Group
Delay Response
”
,启动群时延分析。
FDATool
还提供了以下几种分析工具:
●
群时延响应分析。
●
冲激响应分析(
Impulse
Response
)
,如图所示。
●
阶跃响应分析(
Step
Response
)
,如图所示。
●
零极点图分析(
Pole/Zero
Plot
)
,如图所示。
5
v1.0
可编辑可修改
图
冲激响应
图
阶跃响应
图
零极点图
求出的
FIR
滤波器的系数可以通过选
择菜单“
Analysis
”→“
Fi
lter Coefficients
”来观察。
如图所示,图
中列出了
FDATool
计算的
15<
/p>
阶直接
I
型
FI
R
滤波器的部分系数。
6
v1.0
可编辑可修改
图
滤波器系数
量化
可以看到,
FDATool
计算出的值是一个有符号的小数,如果建立的
FIR
滤波器模型需要一个整数
作为滤波器系数,就必须进行
量化,并对得到的系数进行归一化。为此,单击
FDATool
左下侧的工具
按钮进行量化参数设置。量化参数有三种方式:双精度、单精度和定点。在
使用定点量化前,必须确
保
MATLAB
中已经安装定点工具箱并有相应的授权。
导出滤波器系数
为导出设计好的滤波
器系数,选择
FDATool
菜单的“
File
”→“
Export
”命令,
打开
Export
(导
出)对话框,如
图所示。
图
滤波器系数
Export
对话框
在该窗口中,
选择导出到工作区
(
Workplac
e
)
。
这时滤波器系数就存入到一个一
维变量
Num
中了。
不过这时
Num
中的元素是以小数形式出现的:
Num=
7
v1.0
可编辑可修改
Columns 1 through 9
Columns 10 through 16
2 <
/p>
基于
MATLAB
内建函数的
FIR
设计
在
Matlab
中已经内建有各种滤波器的设计函数,可以直接在程序中调
用,这里介绍其中几个函
数。
fir1
函数
功能:设计标准频率响
应的基于窗函数的
FIR
滤波器。
<
/p>
语法:
b=fir1(n
,
Wn)
;
b=fir1(
n
,
Wn
,
‘
ftytpe
’
)
;
b=fir1(n
,
Wn
,
Window)
;
b=fir1(n
,
Wn
,
‘
ftype
’
,
Window)
;
说明:
fir1
< br>函数可以实现加窗线形相位
FIR
数字滤波器设计,它可
以设计出标准的低通、高通、
带通和带阻滤波器。
b=fir1(n
,
Wn)
可得到
n
阶低通,
截至频率为
Wn
的汉明加窗线形相位
FIR
滤波器,
0
≤
Wn
≤
1
,
Wn=1
相当于。滤波器系数包含在
b
中,可表示为<
/p>
b
(
z
)
?
b
(
1
)
?
b
(
2
)
z
?
1
?
?
?
b
(
n
?<
/p>
1
)
Z
?
n
当
Wn=[W<
/p>
1
W
2
]
p>
时,
fir1
函数可得到带通滤波器,其通
带为
W
1
<
w
<
W
2
。
p>
当
ftype=high
时,设计高通
FIR
滤波器;当
ftype=stop
时,设计带阻滤波器。
在设计高通和带阻滤波器时,
由于对奇次阶的滤波器,
其在
Nyquist
频率处的频率响应为零,
不
适合构成高通和带阻滤波器。
因此
< br>fir1
函数总是使用阶数为偶数的滤波器,
当输入的阶
数为奇数时,
fir1
函数会自动将阶数加
1
。
b=fir1(n
,
Wn
,
Window
)
利用参数
Window
来指定滤波器
采用的窗函数类型。其默认值为汉明窗。
b=fir1(n<
/p>
,
Wn
,
‘
p>
ftype
’
,
W
indow)
可利用
ftype
和
p>
Window
参数,设计各种滤波器。
fir2
函数
功能:设计任意频率响应的基于窗函数的
FIR
滤波器。<
/p>
8
v1.0
可编辑可修改
语法:
b=fir2
(
n
,
f
,
m
)
;
b=fir2
(
n
,
f
,
m
,
Window
)
p>
;
b=fir2
(
n
,
f
,<
/p>
m
,
npt
)<
/p>
;
b=fir2
(
n
,
f
,
m
,
npt
,
window
)
;
b=fir2
(
n
,
f
,
m
< br>,
npt
,
lap
)
;
b=fir2
(
n
,
f
,
m
,
npt
,
lap
,
Window
)
;
说明:
fir2
函数可以用于设计有任意频率响应的加窗
FIR
滤波器,对标准的低通、带通、高通
和带阻滤
波器的设计可使用
fir1
函数。
<
/p>
b=fir2
(
n
,
f
,
m
)
可设计出一个
n
阶的
FIR
滤波器,其滤波器的频率特性由参数
f
和
m
决定。
参数
f
为频率点矢量,且
f
∈
[0
,
1]
,
f=1
对应于。矢量
f
按升序排列,
且第一个元素必须是
0
,最
后一个必须
为
1
,
并可以包含重复的频率点。
p>
矢量
m
中包含了与
f
相对应的期望得到的滤波器的幅度。
b=fir2
(
n
,
f
,
m
,
Window
)中用参数
Window
来指定使用的窗函数类型,默认值为汉明窗。
b=fir
2
(
n
,
f<
/p>
,
m
,
npt<
/p>
)中用参数
npt
来指定
fir2
函数对频率响应进行内插的点数。
b=fir2
(
n
,<
/p>
f
,
m
,
npt
,
lap
)中
用参数
lap
来指定
fir2
在重复频率点附近插入的区域大小。
3 <
/p>
基于
FDATool
的
< br>HDL
代码产生
在
MATLAB 7
中,对数字滤波
器的设计提供了与若干种现实方案的接口。此类接口提供
MATLAB
< br>到设计工具的无缝连接,即
MATLAB
根据设计工具的
文件格式,将包含滤波器设计参数的文件输出。
设计工具导入该文件,
< br>并作为设计模块的一部分。
在此类接口中包括与
Xili
nx
公司和
TI
公司的接口,
还包括
C
头文件以及
H
DL
代码。
与
FDATool
的启动类似,
单击
M
ATLAB
主窗口下方的
“
Start
”
按钮,
选择
“
ToolBox
”
→
“
Filter
Design HDL
coder
”→“
Filter Design &
Analysis Tool(FDATool)
”
,
打开
FDATool
。
根据上节相同的设计和分析步骤,
对
F
IR
滤波器进行分析和设计,
在设计完毕之后,
可以得到滤
波器系数。此时就可以应用设计工具接口。
3.1 C
语言头文件的产生
选择
FDATool
菜单的“
Targets
”→“
Generate
C
Header
”命令,打开产生<
/p>
C
语言头文件的窗口,
如图所示。
9
v1.0
可编辑可修改
图
产生
C<
/p>
语言头文件
可以看到输出的头文件中,
变量名和变量长度名可以自定义,
变量输出的格式也有很多种可
以选
择。根据在
FDATool
量化时
选用的量化方式,窗口中会显示推荐使用的输出格式。
产生的头文件内容如下:
/*
* Filter
Coefficients (C Source) generated by the Filter
Design and Analysis Tool
*
Generated by MATLAB(R)
*
Generate on
:
22-Dec-2005
11:42:24
*/
/*
*
Discrete-Time FIR Filter (real)
*------------------------------------
* Filter Structure
:
Direct-Form FIR
* Filter Order
:
15
*
Stable
:
Yes
*
Linear Phase
:
Yes (Type
2)
*/
/* General type conversion for MATLAB
generated C-code */
#
include
“”
10
v1.0
可编辑可修改
/*
* Expected
path to
*
C:MATLAB7externinclude
*/
const int BL
= 16
;
const
real64_T B[16]={
, , ,
,
, , 0.,
, 0., , ,
, , ,
}
;
Xilinx
系数文件的产生
p>
选择
FDATool
菜单的“
Targets
”→“
Xilinx Coeffi
cients
(
.COE
)
file
”命令,
MATLAB
< br>直接
提示文件的保存位置,保存完毕之后另开一个窗口显示该文件的内容。典型的
文件内容如下所示。
;
; XILINX CORE Generator(tm) Distributed
Arithmetic FIR filter coefficient (.COE)
File
; Generated by MATLAB
(R) and the Filter Design Toolbox .
;
; Generated
on
:
22-Dec-2005 12
:
03
:
10
;
Radix = 16
;
Coefficient_Width = 16
;
CoefData =
0000,
079c,
05a2,
f90b,
f166,
0000,
11
v1.0
可编辑可修改
2272,
4000,
4000,
2272,
0000,
f166,
f90b,
05a2,
079c,
0000;
这些系数已经运用二进制
补码对其进行了运算,所以可以表示成十六进制。
CCS
接口
CCS
(
Code Composer
Studio
)是
TI
公司为其数字信
号处理器开发的集成开发环境(
IDE
)
。在
HDL
coder
中,可以向
CCS
输出
C
语言头文件或者直接写入处理器的存储空间中,然后由
CCS
本
身作
进一步的处理。
在此接口中,
可以
选择目标板和目标处理器的型号,
在这里目标板的型号一般只能是
TI
公司提供的专用
EVM
板。上述
型号必须手动输入。
选择
FDATo
ol
菜单的“
Targets
”→“<
/p>
Code Composer Studio(R)IDE
”命令
,打开
CCS
接口。此
接口的窗口如图
所示。
图
CCS
接口窗口
12
v1.0
可编辑可修改
HDL
语言的生成
选择
FDATool
菜单的“
Targets
”→“
Generate HDL
”命令,打开生成
HDL
源代码的窗口,该窗
口如图所示。
图
生成
HD
L
源代码的窗口
在生成
HDL
文件时,可以选择生成
VHDL
或是
Verilog
HDL
。可以对时钟信号、复位信号、进程、
构造体和实体的定义等等进行设置。最后可以选
择文件输出的文件夹和文件名。
文件一般有如下内容和格式:
--
--------------------------------------------------
--------
-- Module :
filter
-- Generated by
MATLAB(R) and the Filter Design HDL Coder
-- Generated on :
2005-12-22 12:33:35
--
HDL Code
--
此处显
示滤波器特性以及输出
HDL
代码时的设置
------------------------------------
------------------------------
LIBRARY IEEE;
USE
filter IS
PORT ( clk
: IN std_logic;
clk_enable : IN std_logic;
13
v1.0
可编辑可修改
reset : IN std_logic;
filter_in : IN
std_logic_vector (15 DOWNTO 0) --
sfix16_En15
filter_out : OUT std_logic_vector (15 DOWNTO 0)
--sfix16_En9
);
END filter;
-----
--------------------------------------------------
--------------
--Module
Architecture : filter
-----
--------------------------------------------------
--------------
ARCHITECTURE
rt1 OF filter IS
--
局部函数
--
类定义
TYPE delay_pipeline_type IS ARRAY (NATURAL
range
<>
) OF signed (15
DOWNTO 0);
--sfix16_En15
--
定义常数
CONSTANT coeff1:signed(15 DOWNTO
0):=to_signed(0,16);--sfix16_En14
CONSTANT coeff2:signed(15 DOWNTO
0):=to_signed(1948,16);--sfix16_En14
CONSTANT coeff3:signed(15 DOWNTO
0):=to_signed(1442,16);--sfix16_En14
CONSTANT coeff4:signed(15 DOWNTO
0):=to_signed(-1781,16);--sfix16_En14
CONSTANT coeff1:signed(15 DOWNTO
0):=to_signed(0,16);--sfix16_En14
CONSTANT coeff2:signed(15 DOWNTO
0):=to_signed(1948,16);--sfix16_En14
CONSTANT coeff3:signed(15 DOWNTO
0):=to_signed(1442,16);--sfix16_En14
CONSTANT coeff4:signed(15 DOWNTO
0):=to_signed(-1781,16);--sfix16_En14
CONSTANT coeff5:signed(15 DOWNTO
0):=to_signed(-3738,16);--sfix16_En14
CONSTANT coeff6:signed(15 DOWNTO
0):=to_signed(0,16);--sfix16_En14
CONSTANT coeff7:signed(15 DOWNTO
0):=to_signed(8818,16);--sfix16_En14
CONSTANT coeff8:signed(15 DOWNTO
0):=to_signed(16384,16);--sfix16_En14
CONSTANT coeff9:signed(15 DOWNTO
0):=to_signed(16384,16);--sfix16_En14
CONSTANT coeff10:signed(15 DOWNTO
0):=to_signed(8818,16);--sfix16_En14
14
v1.0
可编辑可修改
CONSTANT
coeff11:signed(15 DOWNTO
0):=to_signed(0,16);--sfix16_En14
CONSTANT coeff12:signed(15DOWNTO
0):=to_signed(-3738,16);--sfix16_En14
CONSTANT coeff13:signed(15DOWNTO
0):=to_signed(-1781,16);--sfix16_En14
CONSTANT coeff14 :signed(15DOWNTO
0):=to_signed(1442,16);--sfix16_En14
CONSTANT coeff15:signed(15 DOWNTO
0):=to_signed(1948,16);--sfix16_En14
CONSTANT coeff16:signed(15 DOWNTO
0):=to_signed(0,16);--sfix16_En14
--
信号
SIGNAL delay_pipeline
:delay_pipeline_type (0 To
15);sfix16_En15
SIGNAL product15
:signed(31 DOWNTO
0);--Sfix32_En29
SIGNAL product14
:signed(31 DOWNTO
0);--Sfix32_En29
SIGNAL product13
:signed(31 DOWNTO
0);--Sfix32_En29
SIGNAL product12
:signed(31 DOWNTO 0);--
Sfix32_En29
SIGNAL product10
:signed(31 DOWNTO 0);--
Sfix32_En29
SIGNAL product9
:signed(31 DOWNTO 0);--
Sfix32_En29
SIGNAL product8
:signed(31 DOWNTO 0);--
Sfix32_En29
SIGNAL product7
:signed(31 DOWNTO 0);--
Sfix32_En29
SIGNAL product5
:signed(31 DOWNTO 0);--
Sfix32_En29
SIGNAL product4
:signed(31 DOWNTO 0);--
Sfix32_En29
SIGNAL product3
:signed(31 DOWNTO 0);--
Sfix32_En29
SIGNAL product2
:signed(31 DOWNTO 0);--
Sfix32_En29
SIGNAL sum1
:signed(39 DOWNTO
0);--sfix40_En29
SIGNAL add_temp
:signed(32 DOWNTO
0);--sfix33_En29
SIGNAL sum2
:signed(39 DOWNTO
0);--sfix40_En29
SIGNAL add_temp_1
:signed(40 DOWNTO
0);--sfix41_En29
SIGNAL sum3
:signed(39 DOWNTO
0);--sfix40_En29
SIGNAL add_temp_2
:signed(40 DOWNTO
0);--sfix41_En29
SIGNAL sum4
:signed(39 DOWNTO
0);--sfix40_En29
SIGNAL add_temp_3
:signed(40 DOWNTO 0);--sfix41_En29
15
v1.0
可编辑可修改
SIGNAL
sum5 :signed(39 DOWNTO
0);--sfix40_En29
SIGNAL
add_temp_4 :signed(40 DOWNTO
0);--sfix41_En29
SIGNAL sum6
:signed(39 DOWNTO 0);--sfix40_En29
SIGNAL add_temp_5 :signed(40
DOWNTO 0);--sfix41_En29
SIGNAL sum7 :signed(39
DOWNTO 0);--sfix40_En29
SIGNAL add_temp_6 :signed(40
DOWNTO 0);--sfix41_En29
SIGNAL sum8 :signed(39
DOWNTO 0);--sfix40_En29
SIGNAL add_temp_7 :signed(40
DOWNTO 0);--sfix41_En29
SIGNAL sum9 :signed(39
DOWNTO 0);--sfix40_En29
SIGNAL add_temp_8 :signed(40
DOWNTO 0);--sfix41_En29
SIGNAL sum10 :signed(39
DOWNTO 0);--sfix40_En29
SIGNAL add_temp_9 :signed(40
DOWNTO 0);--sfix41_En29
SIGNAL sum11 :signed(39
DOWNTO 0);--sfix40_En29
SIGNAL add_temp_10 :signed(40
DOWNTO 0);--sfix41_En29
SIGNAL output_typeconvert :signed (15
DOWNTO 0); -- Sfix16_EN9
SIGNAL output_register :signed (15
DOWNTO 0); -- Sfix16_EN9
BEGIN
--
块声明
Delay_pipeline_process : PROCESS (clk ,
reset )
BEGIN
IF reset = ‘1’ THEN
d
elay_pipeline(0 to 15
)<=(OTHERS=>(OTHERS=>’0’));
ELSIF clk’event AND clk = ‘1’ THEN
IF clk_enable=’1’ THEN
delay_pipeline(0)<=signed(fliter_in);
delay_pipeline(1 to 15
)<=delay_pipeline(0 to 14)
END IF
END IF
;
16
v1.0
可编辑可修改
END
PROCESS Delay_pipeline_process;
Product15 <= delay_pipeline(14) *
coeff15
Product14 <=
delay_pipeline(13) * coeff14
Product13 <= delay_pipeline(12) *
coeff13
Product12 <=
delay_pipeline(11) * coeff12
Product10 <= delay_pipeline(9) *
coeff10;
Product9 <=
resize(delay_pipeline(8)(15 DOWNTO 0) & “
00”,32);
Product8 <=
resize(delay_pipeline(7)(15 DOWNTO 0) & “
00”,32);
Product7 <=
delay_pipeline(6) * coeff7;
Product5 <= delay_pipeline(4) * coeff5
;
Product4<=
delay_pipeline(3) * coeff4
Product3 <= delay_pipeline(2) * coeff3
;
Product2 <=
delay_pipeline(1) * coeff2
add_temp<=resize(product2 ,33)
+resize(product3,33);
Sum1<=resize(add_temp,40);
add_temp_1<=resize(sum1 ,41)
+resize(product4,41);
Sum2<=
add_temp_1 (39 DOWNTO 0);
add_temp_2<=resize(sum2 ,41)
+resize(product5,41);
Sum3<=
add_temp_2 (39 DOWNTO 0);
add_temp_3<=resize(sum3 ,41)
+resize(product7,41);
Sum4<=
add_temp_3 (39 DOWNTO 0);
add_temp_4<=resize(sum4 ,41)
+resize(product8,41);
Sum5<=
add_temp_4 (39 DOWNTO 0);
add_temp_5<=resize(sum5 ,41)
+resize(product9,41);
Sum6<=
add_temp_5 (39 DOWNTO 0);
add_temp_6<=resize(sum6 ,41)
+resize(product10,41);
Sum7<= add_temp_6 (39 DOWNTO
0);
add_temp_7<=resize(sum7
,41) +resize(product12,41);
17