>I was puzzling about this all day, but I think I finally figured out what = the problem is. I even wrote a high-level simulation of the arithmetic (a P= erl >script) to help me visualize the details. > >When you add an offset of 128 to temp, the 24-bit average eventually settl= es at the value 0xFFFE81. When you look at the high-order 16 bits of this t= o get your integer result, you can't just ignore the other 8 bits -- you ne= ed to properly round this 24-bit quantity to get the actual 16-bit result b= y adding 0x000080 and >then truncating, which gives you the true value of 0= xFFFF. > >So, I guess by using a temp offset of 255 instead of 128 in the body of th= e filter, you're essentially adding this output-rounding offset into the in= put values going into the filter. I guess there's nothing really wrong with= doing that, as long as you, and users of your code, understand the ramific= ations of doing it. > >-- Dave Tweed Thanks again Dave, for being so thorough in checking my code. The small timing error (I guess that's what it is) is more than good enough= for my applications. Here's another one, using the same rounding principle. Would you care to have a look at this one too ? By the way, doesn't the rounding make this IIR filter effectively an FIR fi= lter ? Cheers, -Andries ;--------------------------------------------------------------------------= ------------------------------------------------------------ ; 1:32 Infinite Impulse Response Filter for 16-bit values - Andries Tip 201= 2 ;--------------------------------------------------------------------------= ------------------------------------------------------------ CBLOCK h'070' ; setpoint0 ; setpoint is the 16-bit input value setpoint1 ; average0 ; average is the filtered output value, aver= age0 as fractional part, average2&average1 as integer part average1 ; average2 ; temp0 ; temporary value used in calculation temp1 ; temp2 ; ENDC ;--------------------------------------------------------------------------= ------------------------------------------------------------ IIR_32_16BIT ; average =3D (31*average + s= etpoint)/32 =3D average + (setpoint - average)/32 movf average0,w ; temp =3D setpoint - average sublw d'0' ; prepare carry andlw b'11100000' ; asssume positive result, ma= ke all upper bits low movwf temp2 ; (after three shifts they wi= ll be upper bits) movf average1,w ; subwfb setpoint0,w ; movwf temp0 ; movf average2,w ; subwfb setpoint1,w ; movwf temp1 ; movlw b'00011111' ; when carry clear (borrow) w= e must set upper bits of temp2 as it is a negative number skpc ; iorwf temp2,f ; ; temp1:temp0:temp2 =3D NMLKJ= IHG FEDCBA98 765SSSSS with S =3D sign bit =20 rlf temp1,w ; temp =3D temp / 32 rlf temp2,f ; shifting left three times i= s faster than shifting right five times rlf temp0,f ; please mind the byte order rlf temp1,f ; rlf temp1,w ; rlf temp2,f ; rlf temp0,f ; rlf temp1,f ; rlf temp1,w ; rlf temp2,f ; rlf temp0,f ; rlf temp1,f ; ; temp1:temp0:temp2 =3D KJIHG= FED CBA98765 SSSSSNML ; temp2:temp1:temp0 =3D SSSSS= NML KJIHGFED CBA98765=20 movf average0,w ; prepare carry for rounding = (when average0<4..0> <> 0 then set carry) iorlw b'11100000' ; to adjust for rounding erro= rs, otherwise we will never reach 65535 addlw b'00011111' ; movf temp0,w ; addwfc average0,f ; movf temp1,w ; addwfc average1,f ; movf temp2,w ; addwfc average2,f ; ;--------------------------------------------------------------------------= ------------------------------------------------------------ --=20 http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist .