Wow, this is very nicely done! I assume you are the author? Thanks much for the great tool! Cheers, -Neil. -----Original Message----- From: Nikolai Golovchenko [mailto:nikolai@synaptics.com] Sent: Monday, May 20, 2002 12:30 PM To: piclist@mitvma.mit.edu Cc: picdude@AVN-TECH.COM Subject: Re:[PIC]: Division by a constant source=Hi Jinx, You just have to use this program: http://www.piclist.com/cgi-bin/constdivmul.exe :) Division by a constant is equivalent to a multiplication by the reciprocal constant, so all you have to do is to specify the multiplication constant and the error. For example, http://www.piclist.com/cgi-bin/constdivmul.exe?Acc=ACC&Bits=16&endian=little &Const=0.00549378103986287&ConstErr=0.05&Temp=TEMP&cpu=pic16 does it in 36 instructions (7.2 us at 20 MHz clock) with the error of 0.01%. Well, the error means the constant approximation error. That is, 1/182.024 = 0.00549378103986287 ~= 1/256+1/1024+1/2048+1/8192 = 0.0054931640625. But there is also the rounding error. For a 9 bit result, an off by one number may mean an error anywhere from 0.2% to infinity :), depending on the value: error = 1/v*100, v=0..511 I would expect the result occasionally be off by one in that case, which may be just fine. For example, if the result should be something like 360.01, but the code produces 359. If this is not fine, try turning on the rounding option in the code generator. The code follows. Unfortunately, it seems to have a bug - the 9th bit of result is lost. To fix it add this at the end: clrf ACC1 rlcf ACC1, f Hope it helps, Nikolai ; ACC = ACC * 0.00549378 ; Temp = TEMP ; ACC size = 16 bits ; Error = 1 % ; Bytes order = little endian ; Round = no ; ALGORITHM: ; Clear accumulator ; Add input / 256 to accumulator ; Add input / 1024 to accumulator ; Add input / 2048 to accumulator ; Add input / 8192 to accumulator ; Move accumulator to result ; ; Approximated constant: 0.00549316, Error: 0.0112305 % ; Input: ACC0 .. ACC1, 16 bits ; Output: ACC0 .. ACC1, 9 bits ; Code size: 36 instructions cblock ACC0 ACC1 TEMP0 TEMP1 endc ;copy accumulator to temporary movf ACC1, w movwf TEMP1 movf ACC0, w movwf TEMP0 ;shift accumulator right 2 times clrc rrf ACC1, f rrf ACC0, f clrc rrf ACC1, f rrf ACC0, f ;add temporary to accumulator addwf ACC0, f movf TEMP1, w skpnc incfsz TEMP1, w addwf ACC1, f ;shift accumulator right 1 times rrf ACC1, f rrf ACC0, f ;add temporary to accumulator movf TEMP0, w addwf ACC0, f movf TEMP1, w skpnc incfsz TEMP1, w addwf ACC1, f ;shift accumulator right 2 times rrf ACC1, f rrf ACC0, f clrc rrf ACC1, f rrf ACC0, f ;add temporary to accumulator movf TEMP0, w addwf ACC0, f movf TEMP1, w skpnc incfsz TEMP1, w addwf ACC1, f ;shift accumulator right 8 times movf ACC1, w movwf ACC0 -- http://www.piclist.com#nomail Going offline? Don't AutoReply us! email listserv@mitvma.mit.edu with SET PICList DIGEST in the body