8bit 16 step Averageing filter by
Andrew Warren
; Written by Andrew Warren [fastfwd at ix.netcom.com].
;
; (NEW - AVE) + 16*AVE
; AVE = --------------------
; 16
NEW EQU [ANY FILE REGISTER] ;HOLDS NEW SAMPLE [0-255].
AVE EQU [ANY FILE REGISTER[ ;HOLDS THE AVERAGE [0-255].
AVFRAC EQU [ANY FILE REGISTER] ;HOLDS THE FRACTIONAL PART
;OF THE AVERAGE [0-15].
TEMP EQU [ANY FILE REGISTER] ;TEMPORARY STORAGE.
FILTER:
MOVLW 00001111B ;MASK OFF ALL BUT THE FRACTIONAL
ANDWF AVFRAC ;PART OF THE OLD AVERAGE
;(AVFRAC'S HI-NIBBLE CAN
;CONTAIN GARBAGE).
MOVF AVE,W ;NEW = NEW - AVE.
SUBWF NEW ;CARRY = 0 IF THE DIFFERENCE IS
;NEGATIVE, CARRY = 1 IF POSITIVE.
SWAPF AVE,W ;HI-NIBBLE OF W = MIDDLE NIBBLE
;OF 16*AVE.
MOVWF TEMP ;LO-NIBBLE OF TEMP = HI-NIBBLE
;OF 16*AVE (LO-NIBBLE OF 16*AVE
;IS ALWAYS 0000).
; NEW CONTAINS (NEW - AVE) AND [TEMP:W] HOLDS 16*AVE.
; ADD THEM TOGETHER.
SKPC ;IF (NEW - AVE) WAS NEGATIVE,
DECF TEMP ;ADJUST THE HI-NIBBLE OF 16*AVE.
ANDLW 11110000B ;W = LO-BYTE OF 16*AVE.
IORWF AVFRAC,W ;(INCLUDE AVE'S FRACTIONAL
;PART).
ADDWF NEW,W ;W = LO-BYTE OF
;((NEW-AVE) + 16*AVE).
;CARRY = 1 IF SUM > 255,
;CARRY = 0 OTHERWISE.
MOVWF AVFRAC ;LO-NIBBLE OF AVFRAC =
;FRACTIONAL PART OF FINAL
;RESULT. HI-NIBBLE = GARBAGE.
ANDLW 11110000B ;W = (LO-NIBBLE OF
;((15*AVE+NEW)/16)) * 16.
MOVWF AVE ;AVE = (LO-NIBBLE OF
;((15*AVE+NEW)/16)) * 16.
SWAPF AVE ;AVE = LO-NIBBLE OF
;((15*AVE+NEW)/16).
; AVE'S LO-NIBBLE CONTAINS THE LO-NIBBLE OF THE FINAL RESULT.
; AVE'S HI-NIBBLE = 0000.
SKPNC ;LO-NIBBLE OF TEMP =
INCF TEMP ;HI-NIBBLE OF ((15*AVE+NEW)/16).
SWAPF TEMP,W ;HI-NIBBLE OF W = HI-NIBBLE OF
ANDLW 11110000B ;((15*AVE+NEW)/16).
;LO-NIBBLE OF W = 0000.
; W'S HI-NIBBLE CONTAINS THE HI-NIBBLE OF THE FINAL RESULT.
; LO-NIBBLE = 0000.
IORWF AVE ;COMBINE THE HI- AND LO-NIBBLES
;AND STORE THE FINAL RESULT IN
;AVE.
; AVE CONTAINS THE NEW AVERAGE.
See? That wasn't too hard; just 20 words of program space and
20 instruction cycles... And not a single floating-point
operation anywhere in there.