;**** A P P L I C A T I O N N O T E A V R 2 2 2 ************************
;*
;* Title: 8-Point Moving Average Filter
;* Version: 1.0
;* Last updated: 97.07.04
;* Target: AT90Sxx1x (Devices with SRAM)
;*
;* Support E-mail: avr@atmel.com
;*
;* DESCRIPTION
;* This Application note shows an implementation of an 8-point Moving
;* Average (MAV) filter. The program filters a data array containing SIZE
;* elements starting at T_START. The App. note contains a test
;* program which copies a 60-byte block of data from program memory to
;* SRAM and filters the data. Note that the ends of the data array are not
;* filtered.
;*
;***************************************************************************
.include "8515def.inc"
.equ SIZE=60 ;data array size
.equ TABLE_L=$60 ;Low SRAM address of first data element
.equ TABLE_H=$00 ;High SRAM address of first data element
rjmp RESET ;Reset Handle
;***************************************************************************
;*
;* "mav8"
;*
;* This subroutine filters SIZE bytes with the first element in SRAM
;* location T_START. The filter routine uses an 8-byte ring buffer which
;* occupies working registers r0-r7. As filtering progresses, this ring
;* buffer always contains the 8-byte window to be averaged.
;*
;* Number of words :31 + return
;* Number of cycles :59 + (SIZE-7)*75 + return
;* Low registers used :11 (r0-r7,mav_tmp,AL,AH)
;* High registers used :1 (t_size)
;* Pointers used :X,Y,Z
;*
;***************************************************************************
;***** Subroutine Register Variables
.def mav_tmp=r8 ;temprary storage register
.def AL=r9 ;ring buffer sum, low byte
.def AH=r10 ;ring buffer sum, high byte
.def t_size=r16 ;size of table
;***** Code
mav8:
clr YH
clr YL ;init pointers
clr XH
clr XL
;***** Fill ring buffer with first-8 byte data segment
mav8_1:
ld mav_tmp,Z+ ;get SRAM data
st Y+,mav_tmp ;store in register
cpi YL,8 ;got all?
brne mav8_1 ;if not, loop more
sbiw ZL,5 ;Z points to first value to filter
mav8_2:
;***** Find average
clr AH ;Clear avg High byte
clr AL ;Clear avg Low byte
clr YL ;init Y-pointer
mav8_3:
ld mav_tmp,Y+
add AL,mav_tmp ;add value to AL
adc AH,XH ;add carry to AH (XH is zero)
cpi YL,8 ;added all ?
brne mav8_3 ;if not, loop again
lsr AH ;divide by 8
ror AL
lsr AH
ror AL
lsr AH
ror AL
ldd mav_tmp,Z+5 ;get next value to buffer
st X+,mav_tmp ;store to buffer
andi XL,$07 ;mask away pointer upper bits
st Z+,AL ;store average
dec t_size
cpi t_size,4 ;end of array?
brne mav8_2 ;if not, loop more
ret
;***************************************************************************
;*
;* Test Program
;*
;* This program copies 60 bytes of data from Program memory to SRAM. It
;* then calls "mav8" to get the data filtered.
;*
;***************************************************************************
RESET:
;***** Main program Register variables
.def temp=r16
;***** Code
ldi temp,low(RAMEND)
out SPL,temp
ldi temp,high(RAMEND)
out SPH,temp ;init Stack Pointer
;***** Memory fill
clr ZH
ldi ZL,tableend*2+1 ;Z-pointer <- ROM table end + 1
ldi YL,low(256*TABLE_H+TABLE_L+SIZE)
ldi YH,high(256*TABLE_H+TABLE_L+SIZE)
;Y pointer <- SRAM table end + 1
loop:
lpm ;get ROM constant
st -Y,r0 ;store in SRAM and decrement Y-pointer
sbiw ZL,1 ;decrement Z-pointer
cpi YL,TABLE_L ;if not done
brne
loop ;loop more
cpi YH,TABLE_H
brne loop
;***** Filter data
ldi ZL,TABLE_L
ldi ZH,TABLE_H
ldi T_size,SIZE
rcall mav8
forever:
rjmp forever
;***** 60 ROM Constants
table:
.db 120,196
.db 78,216
.db 78,100
.db 43,39
.db 241,43
.db 62,172
.db 109,69
.db 48,184
.db 215,231
.db 63,133
.db 216,8
.db 121,126
.db 188,98
.db 168,205
.db 157,172
.db 108,233
.db 80,255
.db 252,102
.db 198,0
.db 171,239
.db 107,114
.db 172,170
.db 17,45
.db 42,55
.db 34,174
.db 229,250
.db 12,179
.db 187,243
.db 44,231
tableend:
.db 76,48
No comments:
Post a Comment