HUNAN UNIVERSITY
FIR 滤波器在 DSP
上的仿真实现
学 生 姓 名
学 生 学 号
陶 晶
20070820319
专 业 班 级
通 信 工 程 三 班
指 导 老 师
胡 红 平
2010 年 12 月 20 日
一、设计目的
1.学习数字滤波器的 DSP 实现原理和 C54X 编程技巧;
2.通过 CCS 的图形显示工具观察输入/输出信号波形以及频谱的变化。
二、设计所需仪器
1.PC 一台;
2.Code Composer Studio 1.2 软件;
3.MATLAB 软件;
4.Dev
C++软件。
三、设计要求
1.设计一个 FIR 低通滤波器,通带边界频率为 1200Hz,采样频率为 8000Hz。
2.设计一个采样频率 Fs 为 8000Hz,输入信号频率为 600Hz 和 3000Hz 的合成信号,通过设
计的低通滤波器将 3000Hz 信号滤掉,余下 600Hz 信号。
3.用循环缓冲区和双操作数寻址方法编写实现 FIR 滤波的程序。
四、设计原理
数字信号处理的最主要的应用领域是数字滤波。数字滤波器被认为是数字信号处理的重要基
石。相对于模拟滤波,数字滤波具有以下的优点:
* 可以满足滤波器对幅值和相位特性的严格要求,精度高;
* 没有电压漂移、温度漂移等问题。基本不受环境影响,稳定性好;
* DSP实现的数字滤波器可靠性高,灵活性好。
由于数字滤波器具有上述的优点,使得数字滤波器广泛应用于语音处理、图像处理、模式识
别、通信等领域。
FIR滤波器的特点FIR滤波器有如下特点:
① 可以在幅度特性随意设计的同时,保证精确、严格的线性相位特性。
② FIR滤波器不是递归结构,其单位脉冲响应是有限长的序列,不存在不稳定的问题。
(2) FIR滤波器的设计方法FIR滤波器的设计方法主要有窗函数法和频率采样设计法。窗函数
法是基本的设计方法,采用矩形窗,直接简便,但采用矩形窗存在比较大的Gibbis效应,且
矩形窗的第一旁瓣与主瓣衰减了13 dB。在实际应用中,一般采用其他窗函数,比较常用的
有:三角窗、巴特利特窗、汉明窗、汉宁窗和布莱克曼窗等。
如果FIR 滤波器的冲激响应为h(0),h(1), ...,h(N-1)。X(n)表示滤波器在n 时刻的输入,
则n 时刻的输出为:
y(n) = h(0)x(n) + h(1)x(n-1) + ... + h(N-1)x[n-(N-1)]
使用MAC 或FIRS 指令可以方便地实现上面的计算。
图1 说明了使用循环寻址实现FIR 滤波器的方法。为了能正确使用循环寻址,必须先初始化
BK,块长为N。同时,数据缓冲区和冲激响应(FIR 滤波器的系数)的开始地址必须是大于N
的2 的最小幂的倍数。例如,N=11,大于N 的最小2 的幂为16,那么数据缓冲区的第一个地
址应是16 的倍数,因此循环缓冲区起始地址的最低4 位必须是0。
在图中,滤波系数指针初始化时指向 h(N-1),经过一次 FIR 滤波计算后,在循环寻址的作
用下,仍然指向 h(N-1)。而数据缓冲区指针指向的是需要更新的数据,如 x(n)。在写入新
数据并完成 FIR 运算后,该指针指向 x(n-(N-1))。所以,使用循环寻址可以方便地完成滤
波窗口数据的自动更新。
五、设计内容及步骤
1.FIR 滤波器的设计
FIR 滤波器的设计可以用 MATLAB 软件的窗函数法进行,这里选择 Hamming 窗,滤波器的阶
数位 10 阶,低通滤波器的截止频率为 1200Hz,程序为:
b=fir1(9,1200/8000*2)
得到 FIR 数字滤波器系数 b 为:
b0
b4
0.0435
=-0.0053
=
0.2951
0.0435
=
-0.0028
0.1695
0.1695
0.2951
=
b6
b7
b2
b3
b1
b5
=
=
=
=
=
b9
-0.0053
= -0.0028
b8
在 DSP 汇编语言中,不能直接输入十进制小数,在 MATLAB 中进行如下转换:
h=round(b*2^15)
将系数转换为 Q15 的定点小数形式,为:
h0
h5
=1426
=
=
=9670
5554
=-92
= -92
=
h8
h2
h7
1426
-174
5554
h9
h3
h4
h1
h6
=
=
9670
=-174
2.产生滤波器输入信号文件
利用 C 语言产生输入信号,信号是频率为 600Hz 和 3000Hz 的正弦波合成的波形,文件名为
firinput.c ,具体程序如下:
#include
#include
void main()
{
int i;
double f[256];
FILE *fp;
if((fp=fopen("firin.inc","wt"))==NULL)
{
printf("can't open file! \n");
return;
}
for(i=0;i<256;i++)
{
f[i]=sin(2*3.14159*i*600/8000)+sin(2*3.14159*i*3000/8000);
fprintf(fp," .word
%ld\n",(long)(f[i]*32768/2));
}
fclose(fp);
}
该程序产生名为 firin.inc 的输入信号程序。Firin.inc 文件的部分内容如下:
.word
0
.word
19023
.word
-3129
.word
27767
.word
15582
:
:
.word
21445
.word
4
在 DSP 汇编语言程序中通过.copy 汇编命令将生成的数据文件 firin.inc 复制到汇编程序
中,作为 FIR 滤波器的输入数据。
3.编写 FIR 数字滤波器的汇编源程序
FIR 数字滤波器汇编程序 fir.asm 如下:
.title
"fir.asm"
.mmregs
.global
start
.def
.def
.set
.set
start
_c_int00
1
256
K0
K
;输入样本数据个数
table
.sect
"table"
;FIR 滤波器系数
N
.set
10
;FIR 滤波器阶数
.word
-174,-92,1426,5554,9670,9670,5554,1426,-92,-174
.data
input
.copy
"firin.inc"
;模拟输入在数据存储区 0x2400
output
.space
1024
;输出数据在数据区 0x2500
an
缓冲区
.usect
"an",N
;自定义数据空间,作为输入数据 x(n)循环
xn
.usect
"xn",N
;自定义数据空间,存储 FIR 滤波器的系数
.text
_c_int00
b
start
nop
nop
start:
SSBx
FRCT
;小数乘法编程时,设置 FRCT(小数方式)位
STM
STM
#xn,AR4
#K0,AR0
;AR4 指向输入数据 x(n)循环缓冲区
RPTZ
A,#N-1
;A=0,重复下一条指令 N 次
STL
STM
STM
RPT
A,*AR4+
;数据循环缓冲区清零
#(xn+N-1),AR4
;数据循环缓冲区指针指向 x(n-N+1)
#an,AR5
#N-1
;AR5 指向 FIR 系数表指针
;重复下一条指令 N 次
MVPD
#table,*AR5+
;将 FIR 系数从程序存储器移到数据存储器
#input,AR6
;AR6 指向模拟输入数据存储空间地址
#output,AR7
;AR7 指向 FIR 滤波器输出数据存储空间地址
STM
STM
STM
#K-1,BRC
RPTBD
LOOP-1
;BRC=k-1
;块重复
STM
LD
STL
#N,BK
*AR6+,A
;FIR 循环缓冲区大小,BK=N
;装载输入数据至累加器 A 中
A,*AR4+%
;用最新的样本值替代最旧的样本值
RPTZ
A,N-1
;重复下一条指令 N 次
MAC
STH
*AR4+0%,*AR5+0%,A
A,*AR7+
LOOP:
EEND
B
EEND
.end
4.编写 FIR 滤波器链接命令文件
对应以上汇编程序的链接命令文件 fir.cmd 如下:
fir.obj
-m
fir.map
-o
fir.out
MEMORY
{
PAGE 0: ROM1(RIX)
:ORIGIN=0080H,LENGTH=100H
PAGE 1: INTRAM1(RW) :ORIGIN=2400H,LENGTH=0200H
INTRAM2(RW) :ORIGIN=2600H,LENGTH=0100H
INTRAM3(RW) :ORIGIN=2700H,LENGTH=0100H
B2B(RW)
:ORIGIN=0070H,LENGTH=10H
}
SECTIONS
{
.text
.data
an
xn
.stack
:
:
:
:
:
{}>ROM1
PAGE 0
{}>INTRAM1
PAGE 1
{}>INTRAM2
PAGE 1
{}>INTRAM3
PAGE 1
{}>B2B
PAGE 1
}
5.在 Code Composer Studio 1.2 软件中将有关程序运行并调试。
六、结果及分析
1.输入信号
(1)输入信号存储在首地址为 2400H 的存储空间中,如下:
(2)输入信号的波形如下:
(3) 输入信号的频谱如下:
由频谱图可知:输入信号是频率为 600Hz 和 3000Hz 的正弦波合成的波形
2.输出信号
(1)输出信号存储在首地址为 2500H 的存储空间中,如下:
(2)输出信号的波形如下:
(3)输出信号的频谱,如图 5 所示。