; 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.
See also:
Questions:
What is the SKPC mnemonic? I did not see it listed in either of the PIC 12/14/16/17 instruction sets. Is it simply just checking the Carry Flag? Thanks, PJGYes. It is a built in macro in MPASM for skip if carry set.