文档介绍:
在实际应用中虽然信号处理的方式多种多样,但其算法的基本要素却大多相同,在本节 中介绍几种较为典型的算法实现,希望通过对这些例子(单精度,16bit)的分析,能够让 大家熟悉DSP编程中的一些技巧,在以后的工作中可以借R2+
;A=c5 *x^2+c4*x+c3
poly
*AR2+
;A=c5*xA3+c4*xA2+c3*x+c2
poly
*AR2+
;A=c5 *xA4+c4*xA3+c3 *xA2+c2*x+c 1
mpya
A
sfta
A, 3
;adjust AH to Q15
SinePolyCoeff:
.word Oxlcce
.word 0x08b7
;in Q12 format
; (coef for xA5 = c5)
; (coef for xA4 二 c4)
.word Oxaacc ; - (coef for xA3 = c3)
.word 0x0053 ; (coef for xA2 = c2)
.word 0x3240 ; (coef for xAl = cl)
在编程过程中,使用到了 POLY语句,它能够使多项式的计算简洁快速地完成。该函数的结 果可以通过实验X来验证。
2. FIR滤波器的实现
FIR滤波器由于具有线性相位而且延迟能够确定,因而在信号处理中广泛应用。FIR的 基本模型如下图所不。
图3- FIR模型
N—1
其数学表达式为血]=/z[z]x[n - i],根据该表达式可以给出一种最为直接的实现形 i=0
式。直接形式中采用线性地址来存放数据,如图3・所示。
x[n]
x [ n -1 ]
h [ N-1 ]
h [ N-2 ]
•……
x [ n - ( N - 2)] x [ n - ( N -1)]
h[ 1 ]
h[ 0]
图3-直接形式
程序中可以采用MACD来实现程序如下:
Id *(lnput), A
stl A, *(x_n)
stm #x_n_Nm1, AR2
mpy *AR2-, #h_Nm1, B
rpt #N-2
macd *AR2・,h_Nm2, B
程序首先将新的数据放置在x[n]处,然后对状态缓存由下而上计算,在循环语句中每执 行一次状态变量自动向下移动一级,即自动更新。它的计算量基本为N个时钟周期。
当然,数据存放还可以采用循环缓存。另外,由于F旧的系数存在对称性,其结构如 图3-所示。那么可以利用这个特点,实现更为快速的计算。
为计算方便将状态变量分别存放在两个缓存区间内,一块命名为Buffer_new,存放图3-上 半部分的数据,另一块命名为Buffer_old,存放图3-下半部分的数据。它们都当循环缓存 使用,大小为FIR阶数的一半,即N/2 (常数SIZE)O根据上述原理编写的汇编程序如下:
stm #Buffer_new, AR2
stm #Buffer_old, AR3
stm #SIZE, BK
stm # -1, ARO
fir_loop:
;read input
Id *(Input), A
stl A, *AR2
;filtering
add *AR2+0%, *AR3+O%, A
rptz B, #SIZE-1
firs *AR2+0%, *AR3+O%, FIR_Coeff
sth B, ^(Output) ;store output
mar *+AR2(2)%
mar *AR3+%
mvdd *AR2, *AR3+0% ;update buffer
b fir_loop
为方便理解,在图3-中,将状态变量更新的过程标明,左边的是Buffer_new,右边的是
Buffer_old。开始时,指针 AR2 和 AR3 分别指向 Buffer_new 和 Buffer_old 中的 x[0]与 x[-19], 将最“新”的数据存进Buffer_new (步骤1)。利用FIRS实现FIR,结果放在BH中。计算 结束后,AR2和AR3分别指向x[-l]和x[-18](步骤2)。然后调整AR2,让它指向Buffer_new 中最"老"的数据x[-9](步骤3);调整AR3,让它指向Buffer_old中最"老"的数据x[-19]
(步骤4)。接下来进行数据更新,将Buffer_new中最“老”的数据放进Buffer_old中,成 为最“新”的数据。最后AR2指向x[-9]的位置,这个位置将在下次计算时放置