《第7章应用程序设计.ppt》由会员分享,可在线阅读,更多相关《第7章应用程序设计.ppt(86页珍藏版)》请在三一文库上搜索。
1、第7章 应用程序设计,本章内容提要:,定标与溢出处理 基础算术运算 FIR滤波器 IIR滤波器 快速傅里叶变换(FFT),7.1 定标与溢出处理,数的定标 溢出的处理方法 常用信号处理算法中的定标方法,7.1.1 数的定标,小数定标的概念 设定一个16位数的小数点处于该数中的哪一位 可以表示不同大小和不同精度的小数 Q表示法 表7-1列出了一个16位数的16种Q表示及它们所能表示的十进制数值范围,表7-1 Q表示及数值范围,不同的Q所表示的数不仅范围不同,而且精度也不相同 Q越大,数值范围越小,但精度越高 Q越小,数值范围越大,但精度就越低 例如, Q0的数值范围是-32768到+32767,
2、其精度为1; Q15的数值范围为-1到0.9999695,精度为 1/32768 = 0.00003051,对定点数而言,数值范围与精度是一对矛盾。一个变量要想能够表示比较大的数值范围,必须以牺牲精度为代价;而想提高精度,则数的表示范围就相应地减小。在实际的定点算法中,应该根据具体问题进行折衷处理, 以达到最佳效果。,在C55x中,16位整数采用补码形式表示。每个采用Qi定标的16位数用1个符号位、i个小数位和15-i个整数位来表示。,表7-2 同样的数在不同定标方式下所表示的具体数值,同样一个16位数,若小数点设定的位置不同,它所表示的数也就不同。,7.1.2 溢出的处理方法,如果算术运算结
3、果超出寄存器所能表示的最大数就会出现溢出 因为16位定点DSP的动态范围有限,所以在使用时必须注意动态范围以防溢出 溢出还与输入信号的特性和运算法则有关,1. 溢出,C55x有以下几种硬件特性可以处理溢出: 保护位 C55x的每个累加器都有8个保护位(3932位),允许连续256次乘加操作而累加器不溢出 溢出标志位 C55x的每个累加器都有相关的溢出标志位,当累加器操作结果出现溢出时,这个标志位就会置位,2. C55x的溢出处理机制,饱和方式位SATD和SATA SATD控制D单元的操作,SATA控制A单元的操作。 如果SATD=1,当D单元发生溢出时,对D单元的结果进行饱和处理。不管饱和方式
4、位的值是什么,当累加器发生溢出时,相应的溢出标志位都会被置位 A单元没有溢出标志位,但如果SATA=1,发生溢出时,结果也会进行饱和处理, 饱和处理是用最近的边界值代替溢出结果。 例如,16位寄存器的范围是8000h(最小负数)7FFFh(最大正数),饱和处理就是用7FFFh代替比7FFFh大的结果;用8000h代替比8000h小的结果。,饱和。饱和是一种处理溢出的方法,但是饱和会剪掉部分输出信号,可能会引起信号失真和引起系统非线性。 输入定标。分析所要使用的系统,假定最坏的情况,然后对输入信号定标,以防止溢出。但是这种方法会极大地降低输出信号的精确度。 固定定标。假定最坏的情况,对中间结果定
5、标。这种方法可以防止溢出,同时增加了系统的信噪比。 动态定标。可以监测中间结果的范围,只在需要的时候对中间结果定标。这种方法可以防止溢出但会增加计算量。,3. 溢出的处理方法,7.1.3 常用信号处理 算法中的定标方法,FIR滤波器的定标方法 在FIR滤波器中处理溢出的最好方法是设计时使滤波器的增益小于1,这样就不需要对输入信号定标。这种方法和累加器的保护位结合起来,可以有效地防止溢出。 由于对信号处理的负面影响,在FIR滤波器中不使用固定定标和输入定标。如果不考虑计算量,在FIR滤波器中可以使用动态定标。对一些类型的音频信号,饱和处理也是一种常用的方法。,IIR滤波器的定标方法 IIR滤波器
6、的定点实现推荐使用多个二阶基本节级联组成,这样可以减小高阶滤波器频率响应灵敏度。由于滤波器系数的量化引入误差,因此避免溢出对IIR滤波器非常重要。 可以通过把中间结果保存在处理器累加器来避免节间数据溢出。为防止在第k阶内部发生数据溢出,需要用增益系数对滤波器的单位脉冲响应(前馈通道)定标。 动态标定方法。在每个阶段滤波器内部状态都被减半,以提高指令周期换取为代价提高了结果的精度。,FFT的定标方法,在FFT操作里,每次蝶形运算后数据平均增加一位。输入定标需要移位 (FFT长度为N),这会导致在计算FFT之前就衰减 6 dB。 在固定定标中,每级蝶形运算输出除以2,这是最常用的FFT定标方法,因
7、为它简单而且有比较好的信噪比。但是,对于大的FFT,这种定标可能会使信息丢失。 另一种方法是动态定标,即在输出溢出时再除以2。在这种情况下,会在这个过程中指定一个变量,每定标一次变量的值加1,计算结束后根据变量的值把结果乘以一个系数。动态定标的信噪比最好,但会增加FFT循环次数。,7.2 基础算术运算,加减运算 乘法运算 除法运算 小数乘法,7.2.1 加减运算,在数字信号处理中,加减运算是常见的算术运算。一般使用16位或32位加减运算,数值分析、浮点运算和其它操作可能需要32位以上的运算。 C55x有直接完成16位或32位加减运算的指令,但没有能直接完成多字加减运算的指令。要进行多字加减运算
8、,需要通过编程方法实现。,以下指令可在单周期内完成32位加法运算: MOV40 dbl(Lmem),ACx ADD dbl(Lmem),ACx 64位的高32位加法要考虑低32位加法产生的进位,使用以下指令: ADD uns(Smem), CARRY, ACx 以下指令可在单周期内完成32位减法运算: MOV40 dbl(Lmem),ACx SUB dbl(Lmem),ACx 64位的高32位减法要考虑低32位减法产生的借位,使用以下指令: SUB uns(Smem),BORROW,ACx,例7-1,64位加法运算。文件名为:add64.asm。,.mmregs .model call=c55
9、_std .model mem=large ;* ; 64位加法 指针分配 ; ; X3 X2 X1 X0 AR1 - X3 (偶地址) ; + Y3 Y2 Y1 Y0 X2 ; - X1 ; W3 W2 W1 W0 X0 ; AR2 - Y3 (偶地址) ; Y2 ; Y1 ; Y0 ; AR3 - W3 (偶地址) ; W2 ; W1 ; W0 ;*,.sect “.text“ .align 4 .global start .sym start,start, 36, 2, 0 start: MOV #0100h,AR1 MOV #0104h,AR2 MOV #0108h,AR3 L1: M
10、OV40 dbl(*AR1(#2), AC0 ; AC0 = X1 X0 ADD dbl(*AR2(#2), AC0 ; AC0 = X1 X0 + Y1 Y0 MOV AC0,dbl(*AR3(#2) ; 保存W1 W0. MOV40 dbl(*AR1), AC0 ; AC0 = X3 X2 ADD uns(*AR2(#1),CARRY,AC0 ; AC0 = X3 X2 + 00 Y2 + CARRY ADD *AR2 #16, AC0 ; AC0 = X3 X2 + Y3 Y2 + CARRY MOV AC0, dbl(*AR3) ; 保存 W3 W2. B L1,例7-2,64位减法运
11、算程序。文件名为:sub64.asm。,.mmregs .model call=c55_std .model mem=large ;* ; 64位减法 指针分配 ; ; X3 X2 X1 X0 AR1 - X3 (偶地址) ; Y3 Y2 Y1 Y0 X2 ; - X1 ; W3 W2 W1 W0 X0 ; AR2 - Y3 (偶地址) ; Y2 ; Y1 ; Y0 ; AR3 - W3 (偶地址) ; W2 ; W1 ; W0 ;*,.sect “.text“ .align 4 .global start .sym start,start,36,2,0 start: MOV #0100h,A
12、R1 MOV #0104h,AR2 MOV #0108h,AR3 L1: MOV40 dbl(*AR1(#2),AC0 ;AC0=X1X0 SUB dbl(*AR2(#2),AC0 ;AC0=X1X0-Y1Y0 MOV AC0,dbl(*AR3(#2) ;保存W1W0. MOV40 dbl(*AR1),AC0 ;AC0=X3X2 SUB uns(*AR2(#1),BORROW,AC0 ;AC0=X3X2-00Y2-BORROW SUB *AR2#16,AC0 ;AC0=X3X2-Y3Y2-BORROW MOV AC0,dbl(*AR3) ;保存 W3W2. B L1,7.2.2 乘法运算,C5
13、5x提供了硬件乘法器,16位乘法可在一个指令周期内完成。 高于16位的乘法运算可以采用下述方法实现(以32位乘法为例)。,例7-3,32位整数乘法运算。文件名:mpy32.asm,.mmregs .model call=c55_std .model mem=large ;* ; 本子程序是两个32位整数乘法,得到一个64位结果。操作数取自数 ; 据存储器,运算结果送回数据存储器。 ; ; 数据存储: 指针分配: ; X1 X0 32位操作数 AR0 - X1 ; Y1 Y0 32位操作数 X0 ; W3 W2 W1 W0 64位结果 AR1 - Y1 ; Y0 ; 入口条件: AR2 - W0
14、 ; SXMD = 1 (允许符号扩展) W1 ; SATD = 0 (不做饱和处理) W2 ; FRCT = 0 (关小数模式) W3 ; ;限制条件:延迟链和输入序列必须指定为长字类型。 ;*,.sect “.text“ .align 4 .global start .sym start,start,36,2,0 start: MOV #0100h,AR0 MOV #0102h,AR1 MOV #0104h,AR2 BSET SXMD BCLR SATD BCLR FRCT L1: AMAR *AR0+ ;AR0指向X0 |AMAR *AR1+ ;AR1指向Y0 MPYM uns(*AR0
15、-),uns(*AR1),AC0 ;ACO=X0*Y0 MOV AC0,*AR2+ ;保存W0 MACM *AR0+,uns(*AR1-),AC0#16,AC0 ;AC0=X0*Y016+X1*Y0 MACM uns(*AR0-),*AR1,AC0 ;AC0=X0*Y016+X1*Y0+X0*Y1 MOV AC0,*AR2+ ;保存W1 MACM *AR0,*AR1,AC0#16,AC0 ;AC0=AC016+X1*Y1 MOV AC0,*AR2+ ;保存W2 MOV HI(AC0),*AR2 ;保存W3 B L1,7.2.3 除法运算,C55x没有提供硬件除法器,也没有提供专门的除法指令,要
16、实现除法运算需借助于条件减法指令SUBC和重复指令RPT。 根据被除数绝对值与除数绝对值的大小关系,除法的实现过程略有不同: 当|被除数|除数|时,商为小数。 当|被除数|除数|时,商为整数。 需要注意的是:SUBC指令要求被除数和除数都必须为正。下面举例说明如何在C55x DSP中实现除法运算。,例7-4,无符号16位除16位整数除法。 文件名为:udiv16o16.asm。,.mmregs .model call=c55_std .model mem=large ;* ; 指针分配 ; AR0-被除数 ; AR1-除数 ; AR2-商 ; AR3-余数 ; ; 注: ; 无符号除法,被除数
17、、除数均为16位 ; 关闭符号扩展,被除数、除数均为正数 ; 运算完成后AC0(15-0)为商,AC0(31-16)为余数 ;*,.sect “.text“ .align 4 .global start .sym start,start,36,2,0 start: MOV #0100h,AR0 MOV #0101h,AR1 MOV #0102h,AR2 MOV #0103h,AR3 L1: BCLR SXMD ; 清零SXMD (关闭符号扩展) MOV *AR0,AC0 ; 把被除数放入AC0 RPT #(16-1) ; 执行subc 16次 SUBC *AR1,AC0,AC0 ; AR1指向
18、除数 MOV AC0,*AR2 ; 保存商 MOV HI(AC0),*AR3 ; 保存余数 B L1,例7-5,无符号32位除16位整数除法。 文件名为:udiv32o16.asm。,.mmregs .model call=c55_std .model mem=large ;* ; 指针分配 ; AR0-被除数高位 ; 被除数低位 ; AR1-除数 ; AR2-商高位 ; 商低位 ; AR3-余数 ; ;注: ;无符号除法,被除数为32位,除数为16位 ;关闭符号扩展,被除数、除数均为正数 ;第一次除法之前,把被除数高位存入AC0 ;第一次除法之后,把商的高位存入AC0(15-0) ;第二次除
19、法之前,把被除数低位存入AC0 ; 第二次除法之后,AC0(15-0)为商的低位,AC0(31-16)为余数 ;*,.sect “.text“ .align 4 .global start .sym start,start,36,2,0 start: MOV #0100h,AR0 MOV #0102h,AR1 MOV #0104h,AR2 MOV #0106h,AR3 L1: BCLR SXMD ; 清零SXMD (关闭符号扩展) MOV *AR0+,AC0 ; 把被除数高位存入AC0 | RPT #(15-1) ; 执行subc 15次 SUBC *AR1,AC0,AC0 ; AR1指向除数
20、 SUBC *AR1,AC0,AC0 ; 执行subc最后一次 | MOV #8,AR4 ; 把AC0_L 存储地址装入AR4 MOV AC0,*AR2+ ; 保存商的高位 MOV *AR0+,*AR4 ; 把被除数低位装入AC0_L RPT #(16-1) ; 执行subc 16次 SUBC *AR1,AC0,AC0 MOV AC0,*AR2+ ; 保存商的低位 MOV HI(AC0),*AR3 ; 保存余数 BSET SXMD ; 置位SXMD (打开符号扩展) B L1,例7-6,带符号16位除16位整数除法。 文件名为:sdiv16o16.asm。,.mmregs .model cal
21、l=c55_std .model mem=large ;* ; 指针分配 ; AR0- 被除数 ; AR1- 除数 ; AR2- 商 ; AR3- 余数 ; ; 注: ; 带符号除法,被除数为16位,除数为16位 ;打开符号扩展,被除数、除数可为负数 ;除法运算之前,商的符号存入AC0 ;除法运算之后,商存入AC1(15-0),余数存入AC1(31-16) ;*,.sect “.text“ .align 4 .global start .sym start,start,36,2,0 start: MOV #0100h,AR0 MOV #0101h,AR1 MOV #0102h,AR2 MOV
22、#0103h,AR3 L1: BSET SXMD ; 置位SXMD (打开符号扩展) MPYM *AR0,*AR1,AC0 ; 计算期望得到的商的符号 MOV *AR1,AC1 ; 把除数存入AC1 ABS AC1,AC1 ; 求绝对值,|除数| MOV AC1,*AR2 ; 暂时保存 |除数| MOV *AR0,AC1 ; 把被除数存入 AC1 ABS AC1,AC1 ; 求绝对值,|被除数| RPT #(16-1) ; 执行subc 16次,SUBC *AR2,AC1,AC1 ;AR2 - |除数| MOV HI(AC1),*AR3 ; 保存余数 MOV AC1,*AR2 ; 保存商 SF
23、TS AC1,#16 ; 对商移位: 把符号位放在最高位 NEG AC1,AC1 ; 对商求反 XCCPART label,AC0#0 ; 如果商的符号位为负, MOV HI(AC1),*AR2 ; 用商的负值替换原来的商 label: B L1,例7-7,带符号32位除16位整数除法。 文件名为:sdiv32o16.asm,.mmregs .model call=c55_std .model mem=large ;* ; 指针分配:(被除数和商都被指定为长字) ; AR0- 被除数高半部分(NumH)(偶地址) ; 被除数高半部分(NumL) ; AR1- 除数(Den) ; AR2- 商的
24、高半部分(QuotH)(偶地址) ; 商的低半部分(QuotL) ; AR3- 余数(Rem) ; 注: ; 带符号除法,被除数为32位,除数为16位 ;打开符号扩展,被除数、除数可为负数 ;除法运算之前,期望的商的符号存入AC0 ;第一次除法运算之前,把被除数的高半部分存入AC1 ;第一次除法运算之后,把商的高半部分存入AC1(15-0) ;第二次除法运算之前,把被除数的低半部分存入AC1 ;第二次除法运算之后,把商的低半部分存入AC1(15-0),余数存入AC1(31-16) ;*,.sect “.text“ .align 4 .global start .sym start,start,
25、36,2,0 start: MOV #0100h,AR0 MOV #0102h,AR1 MOV #0104h,AR2 MOV #0106h,AR3 MOV #0108h,AR4 L1: BSET SXMD ; 置位SXMD (打开符号扩展) MPYM *AR0,*AR1,AC0 ; 除法结果的符号位( NumH x Den ) MOV *AR1,AC1 ; AC1 = Den ABS AC1,AC1 ; AC1 = abs(Den) MOV AC1,*AR3 ; Rem = abs(Den) MOV40 dbl(*AR0),AC1 ; AC1 = NumH NumL ABS AC1,AC1 ;
26、 AC1 = abs(Num) MOV AC1,dbl(*AR2) ; QuotH = abs(NumH) ; QuotL = abs(NumL),MOV *AR2,AC1 ; AC1 = QuotH RPT #(15-1) ; 执行subc 15次 SUBC *AR3,AC1,AC1 SUBC *AR3,AC1,AC1 ; 最后一次执行subc | MOV #11,AR4 ; 把AC1_L存储地址装入AR4 MOV AC1,*AR2+ ; 保存 QuotH MOV *AR2,*AR4 ; AC1_L = QuotH RPT #(16-1) ; 执行subc 16次 SUBC *AR3,AC1
27、,AC1 MOV AC1,*AR2- ; 保存 QuotL MOV HI(AC1),*AR3 ; 保存 Rem BCC skip,AC0= #0 ; 如果实际结果应该为正数,跳到skip. MOV40 dbl(*AR2),AC1 ; 否则,对商取反. NEG AC1,AC1 MOV AC1,dbl(*AR2) skip: B L1,7.2.4 小数乘法,在定点DSP的某些应用中,整数运算很难满足要求。这是因为它自身存在缺陷: 两个16位整数相乘,乘积总是“向左增长”(即小数点左侧的位数增加),这意味着多次相乘后,乘积将很快超出定点器件的数据范围。 保存32位乘积到存储器,要占用2个CPU周期和
28、2个字的存储器空间。 由于乘法器都是16位相乘,因此将32位乘积再作为乘法器的输入时就显得较繁琐,不能胜任递归运算。,为了克服这些缺陷,在实际应用中更多采用的是小数运算。小数运算具有如下优点: 乘积总是“向右增长”。这就意味着超出定点器件数据范围的将是不太感兴趣的部分。 既可以存储32位乘积,也可以近存储高16位乘积,这就允许用较少的资源保存结果。 可以用于递归运算。,例7-8,两个Q31格式有符号小数相乘,得到一个Q31格式结果。文件名为:mpyQ31.asm。,需要注意的是: 两个带符号小数相乘,所得乘积带有2个符号位。 为了解决冗余符号位的问题,需要在程序中设定状态寄存器ST1中的FRC
29、T(小数方式)为1,这样当乘法器将结果传送至累加器时就会自动左移1位。,.mmregs .model call=c55_std .model mem=large ;* ;操作数取自数据存储器,运算结果送回数据存储器。 ; ; 数据存储: 指针分配: ; X1 X0 Q31操作数 AR0 - X1 ; Y1 Y0 Q31操作数 X0 ; W1 W0 Q31结果 AR1 - Y1 ; Y0 ; 入口条件: AR2 - W0(偶地址) ; SXMD = 1 (允许符号扩展) W1 ; SATD = 0 (不做饱和处理) ; FRCT = 1 (运算结果左移一位) ; ;限制条件:W1被指定为偶地址
30、; ;*,.sect “.text“ .align 4 .global start .sym start,start,36,2,0 start: MOV #0100h,AR0 MOV #0102h,AR1 MOV #0104h,AR2 BSET SXMD BCLR SATD BSET FRCT L1: AMAR *AR0+ ; AR0指向X0 MPYM uns(*AR0-),*AR1+,AC0 ; AC0=X0*Y1 MACM *AR0,uns(*AR1-),AC0 ; AC0=X0*Y1+X1*Y0 MACM *AR0,*AR1,AC0#16,AC0; AC0=AC016+X1*Y1 MOV
31、 AC0,dbl(*AR2) ; 保存W1W0 B L1,7.3 FIR滤波器,数字滤波器是DSP的基本应用,有2种基本类型: 有限冲激响应滤波器FIR 无限冲激滤波器IIR 一般来说,如果需要线性相位则选择用FIR滤波器,对于相位要求不敏感的场合可以选用IIR滤波器。 本节主要讨论FIR滤波器的DSP实现方法,有关IIR滤波器的实现将在下一节中介绍。,7.3.1 FIR滤波器的基本结构,一个FIR滤波器的输出序列和输入序列之间的关系,满足差分方程: 传递函数为,FIR滤波器的结构: FIR滤波器的单位冲激响应是一个有限长序列。若为实数,且满足偶对称或奇对称的条件,则FIR滤波器具有线性相位特
32、性。 偶对称线性相位FIR滤波器的差分方程为:,7.3.2 FIR滤波器的C语言编程实现,例7-9,直接型FIR滤波器的C语言编程实现。,/* * fir.c 该程序用于实现FIR滤波器 * L滤波器的阶数 * bi滤波器的系数,i=0,1,L-1 * xi输入信号向量,i=0,1,L-1;x0对应于当前值,x1对应于上一采样值 * x_in 输入信号的当前值 * y_out 输出信号的当前值 */,float fir(float x_in, float *x,float *b,int L) float y_out; int i; /* - */ /* 把上一个采样时间的输入信号向量延迟一个单
33、元,得到当前 采样时间的输入信号向量 */ for(i=L-1;i0;i-) xi = xi-1; x0=x_in; /* - */ /*完成FIR滤波 */ y_out = 0.0; for(i=0;iL;i+) y_out = y_out + bi*xi; return y_out; ,直接型FIR滤波器的实现涉及到两个基本操作,一个是输入信号向量与滤波器系数向量的内积计算,另一个是输入信号向量的更新处理。 在每个采样周期信号缓冲器都要更新一次,最老的采样被抛弃,而其他的信号则向缓冲器的右方移动一个单元,一个新的采样被插入存储单元,并被标记。 如果这个操作过程不用DSP硬件完成,那么它需要
34、很多的时间。,7.3.3 FIR滤波器的汇编语言编程实现,处理信号缓冲器的最有效方法,是把信号采样加载到循环缓冲器中。 在循环缓冲器中,采取数据保持固定、反时针方向移动地址的方式,代替保持缓冲器地址固定且正方向移动数据。 信号采样的起点由指针x(n) 指定,其它诸采样则沿着顺时针方向,从起点开始依次顺序加载。,图7-4 FIR滤波器的循环缓冲区,(a)信号循环缓冲区 (b)系数循环缓冲区,例7-10,FIR滤波器的C55x汇编语言实现。,(1) 主程序 fir_test.c /* fir_test.c */ #include“math.h“ #define L 64 /* Number of
35、FIR filter coefficients */ #define Fs 8000 /* 8000 Hz sampling frequency */ #define T 1/Fs #define f1 800 /* 800 Hz frequency */ #define f2 1800 /* 1800 Hz frequency */ #define f3 3300 /* 3300 Hz frequency */ #define PI 3.1415926 #define w1 (2*PI*f1*T) /* 2*pi*f1/Fs */ #define w2 (2*PI*f2*T) /* 2*pi
36、*f2/Fs */ #define w3 (2*PI*f3*T) /* 2*pi*f3/Fs */ #define a1 0.333 /* Magnitude for wave 1 */ #define a2 0.333 /* Magnitude for wave 2 */ #define a3 0.333 /* Magnitude for wave 3 */,extern int fir(int *,int *,unsigned int,int ); /* Low-pass FIR filter coefficients */ int coeffL= -26,-13,14,36,31,-8,
37、-58,-71,-15,83,139,76,-90,-231,-194,50,331,383,78,-405, -654,-347,403,1024,863,-228,-1577,-1972,-453,2910,6836,9470,9470,6836, 2910,-453,-1972,-1577,-228,863, 1024,403,-347,-654,-405,78,383,331,50,-194,-231,-90,76,139,83,-15,-71, -58,-8,31,36,14,-13,-26; int inL; /* input buffer */ int outL; /* Outp
38、ut buffer */,main() unsigned int i; float signal; unsigned int n=0; int index=0; for(i=0;iL;i+) ini=0; outi=0; while(1) signal = a1*cos(float)w1*n); signal += a2*cos(float)w2*n); signal += a3*cos(float)w3*n); n+; inindex = (int)(0x7fff*signal)+0.5); outindex = fir(in,coeff,L,index); index-; if(index
39、=-1) index=L-1; ,(2) 汇编语言整数fir滤波器函数:fir.asm,; fir.asm 该程序用于实现FIR滤波器,可被C语言程序调用 ; int fir(int *,int *, unsigned int,int) ; 参数0: AR0 输入信号缓冲区指针 ; 参数1: AR1 - FIR滤波器系数向量指针 ; 参数2: T0 - FIR 滤波器的阶数L ; 参数3: T1 - 输入信号当前值在循环缓冲区的序数 ; 返回值: T0 - 输出信号当前值 .def _fir _fir pshm ST1_55 ;现场ST1,ST2和ST3入栈 pshm ST2_55 pshm
40、ST3_55 or #0x340,mmap(ST1_55) ;设置FRCT,SXMD,SATD bset SMUL ;置位SMUL,mov mmap(AR0),BSA01 ;AR0=输入信号循环缓冲区的起始地址 mov mmap(AR1),BSA23 ;AR1=滤波器系数循环缓冲区的起始地址 mov mmap(T0),BK03 ;设置循环缓冲区大小 or #0x5,mmap(ST2_55) ;AR0和AR2为循环缓冲区指针 mov T1,AR0 ; AR0从index偏移量开始 mov #0,AR2 ; AR2从0偏移量开始 sub #2,T0 ;T0=L-2 mov T0,CSR ;设置外部
41、循环次数为L-1 mpym *AR0+,*AR2+,AC0 ;执行第一次运算 | rpt CSR ;启动循环 macm *AR0+,*AR2+,AC0 mov hi(AC0),T0 ; 用Q15格式存放结果 popm ST3_55 ; 恢复ST1, ST2和 ST3 popm ST2_55 popm ST1_55 ret .end,7.4 IIR滤波器,IIR滤波器的优点:结构简单,运算量小,可以用较少的阶数获得很高的选择性。 IIR滤波器的缺点:具有相位特性差,存在稳定性问题。 高阶IIR滤波器经常以串联或并联二阶环节的形式予以实现。,7.4.1 二阶IIR滤波器的结构,二阶IIR滤波器,又称为二阶基本节,分为直接型、标准型和变换型。 二阶IIR滤波器传递函数为:,图7-5 二阶IIR滤波器的直接型的实现,图7-6 的信号流图,图7-7 二阶IIR滤波器的直接型的实现,由于直接型对于给定的传递函数具有最小可能的延迟数、加法器数和乘法器数,所以被称为标准型。,7.4.2 高阶IIR滤波器的结构,高阶IIR滤波器的差分方程和系统函数分别为:,图7-8 高阶IIR滤波器的直接型实现(L=M+1),图7-9 高阶IIR滤波器的串联型结构,图7-10 第k个二阶节,对于 ,有,其中,,注意:,7.4.3 IIR滤波器的C语
链接地址:https://www.31doc.com/p-2094481.html