Full Version : Arc-Tangent Routine for 16C84 (PIC ASM)
avr >>PIC 8051 ZILOG ARM TI H8 ETC >>Arc-Tangent Routine for 16C84 (PIC ASM)


Admin3- 04-18-2006
CODE

      list    p=16C84,t=ON,c=132,n=80,st=off


       include "P16C84.INC"

 cblock   0x0C
   temp
   x,y,a
   x1,y1,cnt
   result
 endc


       ORG     0              ;Reset Vector

       GOTO    Main

       ORG     4              ;Interrupt Vector


Main


       CLRF    x
clrf x1
movlw 0x30
movwf y1
movwf x1
l1
movf y1,w
movwf y

movlw 3
addwf   x1,w
movwf x1
movwf x


       CALL    FRAC_DIV

movf a,w
movwf x
CALL arctan

       goto    l1

FRAC_DIV:
;-------------------
;Fractional division
;
; Given x,y this routine finds:
;  a = 256 * y / x
;

   movlw  8   ;number of bits in the result
   movwf  cnt
   clrf   a   ; the result
   movf   x,w

L1:

   clrc
   rlf    y,f  ;if msb of y is set we know x<y
   rlf    a,f  ;and that the lsb of 'a' should be set
   subwf  y,f  ;But we still need to subtract the
               ;divisor from the dividend just in
               ;case y is less than 256.
   skpnc       ;If y>x, but y<256
    bsf   a,0  ; we still need to set a:0


   btfss  a,0  ;If y<x then we shouldn't have
    addwf y,f  ;done the subtraction

   decfsz cnt,f
    goto  L1

   return


;----------------------------------------------------------
;
;arctan (as adapted from the similar arcsin function)
;
;  The purpose of this routine is to take the arctan of an
;8-bit number that ranges from 0 < x < 255/256. In other
;words, the input, x, is an unsigned fraction whose implicit
;divisor is 256.
;  The output is in a conveniently awkward format of binary
;radians (brads?). The output corresponds to the range of zero
;to pi/4 for the normal arctan function. Specifically, this
;algorithm computes:
;
; arctan(x) = real_arctan(x/256) * 256 / (pi/4)
;  for 0 <= x <= 255
;  
;  where, real_arctan returns the real arctan of its argument
;in radians.
;
;  The algorithm is a table look-up algorithm plus first order
;linear interpolation. The psuedo code is:
;
;unsigned char arctan(unsigned char x)
;{
;  unsigned char i;
;
;  i = x >> 4;
;  return(arctan[i] + ((arctan[i+1] - arctan[i]) * (x & 0xf))/16);
;}
;
;


arctan

       SWAPF   x,W
       ANDLW   0xf
       ADDLW   1
       MOVWF   temp                   ;Temporarily store the index
       CALL    arc_tan_table          ;Get a2=atan( (x>>4) + 1)
       MOVWF   result                 ;Store temporarily in result

       DECF    temp,W                 ;Get the saved index
       CALL    arc_tan_table          ;Get a1=atan( (x>>4) )

       SUBWF   result,W               ;W=a2-a1, This is always positive.
       SUBWF   result,F               ;a1 = a1 - (a1-W) = W

       CLRF    temp                   ;Clear the product
       CLRC

       BTFSC   x,0
        ADDWF  temp,F
       RRF     temp,F
       CLRC

       BTFSC   x,1
        ADDWF  temp,F
       RRF     temp,F
       CLRC

       BTFSC   x,2
        ADDWF  temp,F
       RRF     temp,F
       CLRC

       BTFSC   x,3
        ADDWF  temp,F
       RRF     temp,W

       ADDWF   result,F

       RETURN

arc_tan_table
       ADDWF   PCL,F
       RETLW   0
       RETLW   20    ;atan(1/16) = 3.576deg * 256/45
       RETLW   41
       RETLW   60
       RETLW   80
       RETLW   99
       RETLW   117
       RETLW   134
       RETLW   151
       RETLW   167
       RETLW   182
       RETLW   196
       RETLW   210
       RETLW   222
       RETLW   234
       RETLW   245
       RETLW   0;atan(32/32) = 45deg * 256/45

       END





Forumer™ is Voted #1 Free Forum Hosting provider
Build your own community today with the largest message board hosting company.