PIC Microcontoller Basic Math

Multiplication and Division by a Constant

The PICList code generator: Multiplication and Division by any Constant through a simple html form 

Binary Multiplication by a Constant

8 bits by any constant by Myke Predko

See Division Methods for divide by 10, etc...

Since rotating any binary value one place left or right will multiply or divide by 2:

;Multiply 8 bit ACC by 2 (double)
	rlf	ACC, f

;Multiply 16 bit ACC by 2 (double)
	clrc
	rlf	ACC0, f
	rlf	ACC1, f

;Divide 8 bit ACC by 2 (half)
	rrf	ACC, f

;Divide 16 bit ACC by 2 (half)
	clrc
	rrf	ACC0, f
	rrf	ACC1, f


; 28/32-bit unsigned Multiply by 16
;  by Martin Sturm 2010
;
; Left shift by 4 with zero fill on right
; NOTE: discards uppermost bits shifted out
;  2 instructions shorter than unrolled RLF
;  1 instruction longer than code generator but can tolerate
;   non-zero bits in the upper nibble of high byte
; Can be easily modified for 24, 16 bit versions
;
; 17 instructions, 17 cycles
MULT_U12_BY16 MACRO x4,x3,x2,x1
                     ; x4   x3   x2   x1   W
                     ; a b  c d  e f  g h
    MOVLW    0x0F    ;                     0x0F

    ANDWF    x4,F    ; 0 b
    SWAPF    x4,F    ; b 0

    SWAPF    x3,F    ;      d c
    ANDWF    x3,W    ;                     0 c
    IORWF    x4,F    ; b c		
    XORWF    x3,F    ;      d 0
  ;stop here for 16bit
    MOVLW    0x0F    ;                     0x0F
    SWAPF    x2,F    ;           f e
    ANDWF    x2,W    ;                     0 e
    IORWF    x3,F    ;      d e
    XORWF    x2,F    ;           f 0
  ;stop here for 24bit
    MOVLW    0x0F    ;                     0x0F
    SWAPF    x1,F    ;                h g
    ANDWF    x1,W    ;                     0 g
    IORWF    x2,F    ;           f g
    XORWF    x2,F    ;                h 0
  ;repeat the 5 inst. pattern above for larger datatypes
    ENDM             ; b c  d e  f g  h 0



; 32-bit unsigned Divide by 16
;  by Martin Sturm 2010
;
; Right shift 4byte value by 4 with zero fill on left.
;  2 instructions shorter than unrolled RLF implementation
;  1 instruction faster than code generator !
; Can be easily modified for 24, 16 bit versions
;
; 17 instructions, 17 cycles
DIV_U32_BY16 MACRO x4,x3,x2,x1
                     ; x4   x3   x2   x1   W
                     ; a b  c d  e f  g h
    MOVLW    0xF0    ;                     0xF0

    ANDWF    x1,F    ;                g 0
    SWAPF    x1,F    ;                0 g

    SWAPF    x2,F    ;           f e
    ANDWF    x2,W    ;                     f 0
    IORWF    x1,F    ;                f g
    XORWF    x2,F    ;           0 e
  ;stop here for 16bit
    MOVLW    0xF0    ;                     0xF0
    SWAPF    x3,F    ;      d c
    ANDWF    x3,W    ;                     d 0
    IORWF    x2,F    ;           d e
    XORWF    x3,F    ;      0 c
  ;stop here for 24bit
    MOVLW    0xF0    ;                     0xF0
    SWAPF    x4,F    ; b a 
    ANDWF    x4,W    ;                     b 0
    IORWF    x3,F    ;      b c
    XORWF    x4,F    ; 0 a
  ;repeat the 5 inst. pattern above for larger datatypes
    ENDM             ; 0 a  b c  d e  f g

;******************************************************************************
;Multiply 32 bit number by 10
; for PIC18F by VegiePete gmail
;Inline code, in place result
;FSR0 points to 32 bit number (low byte in low memory)
;Returns overflow byte in WREG, Z set if no overflow
Times10:
	movf	POSTINC0,w	;grab 1st digit, point to 2nd
	mullw	10
	movf	POSTDEC0,w	;rescue 2nd digit, point to first
	movff	PRODL,POSTINC0	;save result low, point to 2nd
	movff	PRODH,INDF0	;save result high

	mullw	10
	movf	PRODL,w		;grab result low byte
	addwf	POSTINC0,f	;add to highest previous byte, point tp 3rd
	movlw	0
	addwfc	PRODH,f		;propagate the carry
	movf	INDF0,w		;rescue 3rd digit
	movff	PRODH,INDF0	;save result high

	mullw	10
	movf	PRODL,w		;grab result low byte
	addwfc	POSTINC0,f	;add to highest previous byte, plus any carry
	movlw	0
	addwfc	PRODH,f		;propagate the carry
	movf	INDF0,w		;rescue 4th digit
	movff	PRODH,INDF0	;save result high
	
	mullw	10		;don't care about overflow byte
	movf	PRODL,w		;grab result low byte
	addwfc	INDF0,w		;add to highest previous byte, plus any carry

	movlw	0
	addwfc	PRODH,w		;propagate the carry, load overflow
	
	return