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 xx, but y<256 bsf a,0 ; we still need to set a:0 btfss a,0 ;If y> 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