;**** 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