关键词: MAXQ2000, DSP, 音频滤波器, 数字信号处理, MAXQ, MAC 関連製品

# 采用MAXQ2000进行音频滤波

By: Kris Ardis

MAXQ2000的MAC能够发挥多大的性能？本应用笔记以一个音频滤波器为例来解释此问题，并定量给出MAXQ2000支持的性能。

## 运行演示

MAXQ2000评估板上的按键用于选择滤波器，并播放经过滤波的音频采样。使用按键SW4选择滤波器，滤波器名称将显示在LCD上(HI为高通、LO为低通、BP为带通，ALL为全通)。使用按键SW5播放通过所选滤波器的音频。可在播放期间切换滤波器。

## 设计一个简单的FIR滤波器

y(n) + ΣbKy(k) = ΣaJx(j)

y(n) = 0.5y(n-1) + x(n) - 0.8x(n-1)

y(n) = ΣaJx(j)
y(n) = x(n) - 0.2x(n - 1) + 0.035x(n - 3)

## 使用乘-累加(MAC)单元实现一个滤波器

```Zeroes:
dc16
dc16 12, 11, 0x1000, 0x26d3, 0x1e42, 0xf9a3, 0xecde, 0xff31, 0xa94,
0x2ae, 0xfd0c, 0xff42, 0xde
Shift amount: 12
```

## 用MAXQ汇编语言实现滤波器

```    move  MCNT, #22h           ; signed, mult-accum, clear regs first

zeroes_filterloop:
move  A[0], DP[0]          ; let's see if we are out of data
cmp   #W:rawaudiodata      ; compare to the start of the audio data
lcall UROM_MOVEDP1INC      ; get next filter coefficient
move  MA, GR               ; multiply filter coefficient...
lcall UROM_MOVEDP0DEC      ; get next filter data
move  MB, GR               ; multiply audio sample...
jump  e, zeroes_outofdata  ; stop if at the start of the audio data
djnz  LC[0], zeroes_filterloop

zeroes_outofdata:
move  A[2], MC2            ; get MAC result HIGH
move  A[1], MC1            ; get MAC result MID
move  A[0], MC0            ; get MAC result LOW
```

## 性能

```zeroes_filterloop:
move  A[0], DP[0]          ; 1, let's see if we are out of data
cmp   #W:rawaudiodata      ; 2, compare to the start of the audio data
move  DP[1], DP[1]         ; 1, select DP[1] as our active pointer
move  GR, @DP[1]++         ; 1, get next filter coefficient
move  MA, GR               ; 1, multiply filter coefficient...
move  BP, BP               ; 1, select BP[Offs] as our active pointer
move  GR, @BP[Offs--]      ; 1, get next filter data
move  MB, GR               ; 1, multiply audio sample...
jump  e, zeroes_outofdata  ; 1, stop if at the start of the audio data
djnz  LC[0], zeroes_filterloop  ; 1
```

```zeroes_filterloop:
move  A[0], DP[0]          ; 1, let's see if we are out of data
cmp   #W:rawaudiodata      ; 2, compare to the start of the audio data
move  DP[1], DP[1]         ; 1, select DP[1] as our active pointer
move  MA, @DP[1]++         ; 1, multiply next filter coefficient
move  BP, BP               ; 1, select BP[Offs] as our active pointer
move  MB, @BP[Offs--]      ; 1, multiply next filter data
jump  e, zeroes_outofdata  ; 1, stop if at the start of the audio data
djnz  LC[0], zeroes_filterloop  ; 1
```

```zeroes_filterloop:
move  DP[1], DP[1]         ; 1, select DP[1] as our active pointer
move  MA, @DP[1]++         ; 1, multiply next filter coefficient
move  BP, BP               ; 1, select BP[Offs] as our active pointer
move  MB, @BP[Offs--]      ; 1, multiply next filter data
djnz  LC[0], zeroes_filterloop  ; 1
```

```    move  A[2], MC2            ; get MAC result HIGH
move  A[1], MC1            ; get MAC result MID
move  A[0], MC0            ; get MAC result LOW
move  APC, #0C2h           ; clear AP, roll modulo 4, auto-dec AP

shift_loop:
;
; Because we use fixed point precision, we need to shift to get a real
; sample value.  This is not as efficient as it could be.  If we had a
; dedicated filter, we might make use of the shift-by-2 and shift-by-4
; instructions available on MAXQ.
;
move  AP, #2               ; select HIGH MAC result
move  c, #0                ; clear carry
rrc                        ; shift HIGH MAC result
rrc                        ; shift MID MAC result
rrc                        ; shift LOW MAC result
djnz  LC[1], shift_loop    ; shift to get result in A[0]
move APC, #0               ; restore accumulator normalcy
move AP, #0                ; use accumulator 0
```

```    ;
; don't care about high word, since we shift left and take the
; middle word.
;
move  A[1], MC1            ; 1, get MAC result MID
move  A[0], MC0            ; 1, get MAC result LOW
move  MCNT, #20h           ; 1, clear the MAC, multiply mode only
move  AP, #0               ; 1, use accumulator 0
and   #0F000h              ; 2, only want the top 4 bits
move  MA, A[0]             ; 1, lower word first
move  MB, #10h             ; 1, multiply by 2^4
move  A[0], MC1R           ; 1, get the high word, only lowest 4 bits significant
move  MA, A[1]             ; 1, now the upper word, we want lowest 12 bits
move  MB, #10h             ; 1, multiply by 2^4
or    MC1R                 ; 1, combine the previous result and this one
;
; result is in A[0]
;
```

 Filter Length (Taps) Max Rate (Hz) 50 68965.51724 100 37037.03704 150 25316.4557 200 19230.76923 250 15503.87597 300 12987.01299 350 11173.18436

```    move  BP, BP               ; select BP[Offs] as our active pointer
zeroes_filtertop:
move  MA, #FILTERCOEFF_0   ; 2, multiply next filter coefficient
move  MB, @BP[Offs--]      ; 1, multiply next filter data
move  MA, #FILTERCOEFF_1   ; 2, multiply next filter coefficient
move  MB, @BP[Offs--]      ; 1, multiply next filter data
move  MA, #FILTERCOEFF_2   ; 2, multiply next filter coefficient
move  MB, @BP[Offs--]      ; 1, multiply next filter data
. . .
move  MA, #FILTERCOEFF_N   ; 2, multiply next filter coefficient
move  MB, @BP[Offs--]      ; 1, multiply next filter data
;
; filter calculation complete
;
```

 Filter Length (Taps) Max Rate (Hz) 50 105263.1579 100 58823.52941 150 40816.32653 200 31250 250 25316.4557 300 31250 350 27027.02703

## 支持IIR滤波器

• 使用一段专用RAM来存储最后的输出采样(环形缓冲中使用该方法最有效，BP[Offs]寄存器的使用方式与前面描述的相似)
• 包括滤波器的反馈(‘y'部分)特征参数
• 加入另一个循环，该循环持续累加滤波器反馈部分的乘积结果

## 结论

MAXQ2000具有的性能和外设可使其成为优秀的通用微控制器，可以广泛应用在需要快速、通用微控制器(特别是需要用户交互)的场合。高效的MAC使MAXQ2000具有一定的数字滤波能力，可成为最通用的通用微控制器。

 相关型号 MAX1407 免费样品 MAXQ2000-KIT 免费样品 MAXQ2000 免费样品
 下一步 EE-Mail 订阅EE-Mail，接收关于您感兴趣的新文档的自动通知。
 © , Maxim Integrated Products, Inc.
The content on this webpage is protected by copyright laws of the United States and of foreign countries. For requests to copy this content, contact us.
 APP 3483: 应用笔记 3483,AN3483, AN 3483, APP3483, Appnote3483, Appnote 3483