MATHS.INC from PIC Microcontoller Input / Output Methods for Perminant Magnet Motors
;*******************************************************************
; Double Precision Multiplication
;
; ( Optimized for Speed : straight Line Code )
;
;*******************************************************************;
; Multiplication : ACCb(16 bits) * ACCa(16 bits) -> ACCb,ACCc ( 32 bits )
; (a) Load the 1st operand in location ACCaLO & ACCaHI ( 16 bits )
; (b) Load the 2nd operand in location ACCbLO & ACCbHI ( 16 bits )
; (c) CALL D_mpy
; (d) The 32 bit result is in location ( ACCbHI,ACCbLO,ACCcHI,ACCcLO )
;*******************************************************************;
;
; multiplication macro
;
mulMac MACRO
LOCAL NO_ADD
;
rrf ACCdHI, F ;rotate d right
rrf ACCdLO, F
btfss STATUS,C ;need to add?
goto NO_ADD ; no addition necessary
movf ACCaLO,w ; Addition ( ACCb + ACCa -> ACCb )
addwf ACCbLO, F ;add lsb
btfsc STATUS,C ;add in carry
incf ACCbHI, F
movf ACCaHI,w
addwf ACCbHI, F ;add msb
NO_ADD rrf ACCbHI, F
rrf ACCbLO, F
rrf ACCcHI, F
rrf ACCcLO, F
;
ENDM
;
;*******************************************************************;
; Double Precision Multiply ( 16x16 -> 32 )
; ( ACCb*ACCa -> ACCb,ACCc ) : 32 bit output with high word
; in ACCb ( ACCbHI,ACCbLO ) and low word in ACCc ( ACCcHI,ACCcLO ).
;
D_mpyF ;results in ACCb(16 msb's) and ACCc(16 lsb's)
;
IF SIGNED
CALL S_SIGN
ENDIF
;
call setup
;
; use the mulMac macro 16 times
;
mulMac
mulMac
mulMac
mulMac
mulMac
mulMac
mulMac
mulMac
mulMac
mulMac
mulMac
mulMac
mulMac
mulMac
mulMac
mulMac
;
IF SIGNED
btfss sign,MSB
retlw 0
comf ACCcLO ; negate ACCa ( -ACCa -> ACCa )
incf ACCcLO
btfsc STATUS,Z
decf ACCcHI
comf ACCcHI
btfsc STATUS,Z
neg_B comf ACCbLO ; negate ACCb
incf ACCbLO
btfsc STATUS,Z
decf ACCbHI
comf ACCbHI
retlw 0
ELSE
retlw 0
ENDIF
;*******************************************************************
setup movlw .16 ; for 16 shifts
movwf temp
movf ACCbHI,w ;move ACCb to ACCd
movwf ACCdHI
movf ACCbLO,w
movwf ACCdLO
clrf ACCbHI
clrf ACCbLO
retlw 0
;*******************************************************************
; Assemble this section only if Signed Arithmetic Needed
;
IF SIGNED
;
S_SIGN movf ACCaHI,W
xorwf ACCbHI,W
movwf sign
btfss ACCbHI,MSB ; if MSB set go & negate ACCb
goto chek_A
;
comf ACCbLO ; negate ACCb
incf ACCbLO
btfsc STATUS,Z
decf ACCbHI
comf ACCbHI
;
chek_A btfss ACCaHI,MSB ; if MSB set go & negate ACCa
retlw 0
goto neg_A
;
ENDIF
;
;*******************************************************************
; Double Precision Division
;
; ( Optimized for Speed : straight Line Code )
;
;*******************************************************************;
; Division : ACCb(16 bits) / ACCa(16 bits) -> ACCb(16 bits) with
; Remainder in ACCc (16 bits)
; (a) Load the Denominator in location ACCaHI & ACCaLO ( 16 bits )
; (b) Load the Numerator in location ACCbHI & ACCbLO ( 16 bits )
; (c) CALL D_div
; (d) The 16 bit result is in location ACCbHI & ACCbLO
; (e) The 16 bit Remainder is in locations ACCcHI & ACCcLO
;*******************************************************************;
;
divMac MACRO
LOCAL NOCHK
LOCAL NOGO
bcf STATUS,C
rlf ACCdLO, F
rlf ACCdHI, F
rlf ACCcLO, F
rlf ACCcHI, F
movf ACCaHI,w
subwf ACCcHI,w ;check if a>c
btfss STATUS,Z
goto NOCHK
movf ACCaLO,w
subwf ACCcLO,w ;if msb equal then check lsb
NOCHK btfss STATUS,C ;carry set if c>a
goto NOGO
movf ACCaLO,w ;c-a into c
subwf ACCcLO, F
btfss STATUS,C
decf ACCcHI, F
movf ACCaHI,w
subwf ACCcHI, F
bsf STATUS,C ;shift a 1 into b (result)
NOGO rlf ACCbLO, F
rlf ACCbHI, F
ENDM
;*******************************************************************
; Double Precision Divide ( 16/16 -> 16 )
;
; ( ACCb/ACCa -> ACCb with remainder in ACCc ) : 16 bit output
; with Quotiont in ACCb (ACCbHI,ACCbLO) and Remainder in ACCc (ACCcHI,ACCcLO).
;
; NOTE : Before calling this routine, the user should make sure that
; the Numerator(ACCb) is greater than Denominator(ACCa). If
; the case is not true, the user should scale either Numerator
; or Denominator or both such that Numerator is greater than
; the Denominator.
;*******************************************************************
neg_A comf ACCaLO, F ; negate ACCa ( -ACCa -> ACCa )
incf ACCaLO, F
btfsc STATUS,Z
decf ACCaHI, F
comf ACCaHI, F
retlw 0
;*******************************************************************
D_divF
IF SIGNED
CALL S_SIGN
ENDIF
call setup
clrf ACCcHI
clrf ACCcLO
; use the mulMac macro 16 times
divMac
divMac
divMac
divMac
divMac
divMac
divMac
divMac
divMac
divMac
divMac
divMac
divMac
divMac
divMac
divMac
;
IF SIGNED
btfss sign,MSB ; check sign if negative
retlw 0
goto neg_B ; negate ACCa ( -ACCa -> ACCa )
ELSE
retlw 0
ENDIF
;
;*******************************************************************
; Assemble this section only if Signed Arithmetic Needed
;
IF SIGNED
;
S_SIGN movf ACCaHI,W
xorwf ACCbHI,W
movwf sign
btfss ACCbHI,MSB ; if MSB set go & negate ACCb
goto chek_A
;
comf ACCbLO ; negate ACCb
incf ACCbLO
btfsc STATUS,Z
decf ACCbHI
comf ACCbHI
;
chek_A btfss ACCaHI,MSB ; if MSB set go & negate ACCa
retlw 0
goto neg_A
;
ENDIF
;
;*******************************************************************
; Double Precision Addition & Subtraction
;*******************************************************************;
; Addition : ACCb(16 bits) + ACCa(16 bits) -> ACCb(16 bits)
; (a) Load the 1st operand in location ACCaLO & ACCaHI ( 16 bits )
; (b) Load the 2nd operand in location ACCbLO & ACCbHI ( 16 bits )
; (c) CALL D_add
; (d) The result is in location ACCbLO & ACCbHI ( 16 bits )
;*******************************************************************;
; Subtraction : ACCb(16 bits) - ACCa(16 bits) -> ACCb(16 bits)
; (a) Load the 1st operand in location ACCaLO & ACCaHI ( 16 bits )
; (b) Load the 2nd operand in location ACCbLO & ACCbHI ( 16 bits )
; (c) CALL D_sub
; (d) The result is in location ACCbLO & ACCbHI ( 16 bits )
;*******************************************************************;
D_sub call neg_A ; At first negate ACCa; Then add
;*******************************************************************
D_add movf ACCaLO,w
addwf ACCbLO, F ;add lsb
btfsc STATUS,C ;add in carry
incf ACCbHI, F
movf ACCaHI,w
addwf ACCbHI, F ;add msb
retlw 0
file: /Techref/microchip/io/dev/motor/servob/MATHS_INC.htm, 7KB, , updated: 2005/5/13 16:50, local time: 2024/12/26 08:09,
|
| ©2024 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions? <A HREF="http://linistepper.com/techref/microchip/io/dev/motor/servob/MATHS_INC.htm"> MATHS.INC</A> |
Did you find what you needed?
|