⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pm_math.asm

📁 Simple watt meter using pic16f
💻 ASM
字号:
;********************************************************************
;  mpy_S
;       8x8 multiply routine
;       ON ENTRY: ACCaHI=multiplicand, ACCaLO=multiplier
;       RETURNS:  result in ACCbHI & ACCbLO
;       REGS DESTROYED: ACCbHI,ACCbLO,ACCaHI,ACCaLO,count
;********************************************************************
Same    equ     1

mpy_S   clrf    ACCbHI          ; SUBPROGRAM ENTRY
        clrf    ACCbLO
	movlw   8
	movwf   count
	movf    ACCaHI,w        ; 8-bit multiplicand
	bcf     _carry          ; Clear the carry bit in the status Reg.
loop    rrf     ACCaLO          ; 8-bit multiplier
	btfsc   _carry
	addwf   ACCbHI,Same
	rrf     ACCbHI,Same
	rrf     ACCbLO,Same
	decfsz  count
	goto    loop
	retlw   0



;********************************************************************
;  B2_BCD
;       ON ENTRY: 16bit value in ACCbHI & ACCbLO
;       RETURNS:  BCD bytes (msb) ACCdLO, ACCaHI, ACCaLO (lsb)
;       REGS DESTROYED: ACCdLO, ACCa,count,temp
;********************************************************************
B2_BCD  bcf     _carry          ; SUBPROGRAM ENTRY
                                ; clear the carry bit
	movlw   .16
	movwf   count
	clrf    ACCdLO
	clrf    ACCaHI
	clrf    ACCaLO
loop16  rlf     ACCbLO
	rlf     ACCbHI
	rlf     ACCaLO
	rlf     ACCaHI
	rlf     ACCdLO
;
	decfsz  count
	goto    adjDEC
	RETLW   0
;
adjDEC  movlw   ACCaLO
	movwf   _fsr
	call    adjBCD
;
	movlw   ACCaHI
	movwf   _fsr
	call    adjBCD
;
	movlw   ACCdLO
	movwf   _fsr
	call    adjBCD
;
	goto    loop16
;
adjBCD  movlw   3
	addwf   0,W
	movwf   temp
	btfsc   temp,3          ; test if result > 7
	movwf   0
	movlw   30
	addwf   0,W
	movwf   temp
	btfsc   temp,7          ; test if result > 7
	movwf   0               ; save as MSD
	RETLW   0
;*******************************************************************
;                       Double Precision Division
;
;               ( Optimized for Code Size : Looped 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
;
;   Performance :
;               Program Memory  :       037
;               Clock Cycles    :       310
;
;        NOTE :
;               The performance specs are for Unsigned arithmetic ( i.e,
;               with "SIGNED equ  FALSE ").
;
;*******************************************************************;
;
;
;*******************************************************************
SIGNED  equ     FALSE           ; Set This To 'TRUE' if the routines
;                               ; for Multiplication & Division needs
;                               ; to be assembled as Signed Integer
;                               ; Routines. If 'FALSE' the above two
;                               ; routines ( D_mpy & D_div ) use
;                               ; unsigned arithmetic.
;*******************************************************************
;       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.
;
;
D_divS
;
     IF   SIGNED
     CALL    S_SIGN
     ENDIF
;
	call    setup
	clrf    ACCcHI
	clrf    ACCcLO
dloop   bcf     _carry
	rlf     ACCdLO
	rlf     ACCdHI
	rlf     ACCcLO
	rlf     ACCcHI
	movf    ACCaHI,w
	subwf   ACCcHI,w          ;check if a>c
	btfss   _z
	goto    nochk
	movf    ACCaLO,w
	subwf   ACCcLO,w        ;if msb equal then check lsb
nochk   btfss   _carry          ;carry set if c>a
	goto    nogo
	movf    ACCaLO,w        ;c-a into c
	subwf   ACCcLO
	btfss   _carry
	decf    ACCcHI
	movf    ACCaHI,w
	subwf   ACCcHI
	bsf     _carry          ;shift a 1 into b (result)
nogo    rlf     ACCbLO
	rlf     ACCbHI
	decfsz  temp            ;loop untill all bits checked
	goto    dloop
;
    IF    SIGNED
	btfss   sign,MSB        ; check sign if negative
	retlw   0
	goto    neg_B           ; negate ACCa ( -ACCa -> ACCa )
    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
;
;*******************************************************************
;
neg_A   comf    ACCaLO          ; negate ACCa ( -ACCa -> ACCa )
	incf    ACCaLO
	btfsc   _z
	decf    ACCaHI
	comf    ACCaHI
	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   _z
	decf    ACCbHI
	comf    ACCbHI
;
chek_A  btfss   ACCaHI,MSB        ; if MSB set go & negate ACCa
	retlw   0
	goto    neg_A
;
     ENDIF
;
;*******************************************************************
;                       Test Program
;*******************************************************************
;    Load constant values to ACCa & ACCb for testing
;
test1   movlw   1
	movwf   ACCaHI
	movlw   0FF             ; loads ACCa = 01FF
	movwf   ACCaLO
;
	movlw   07F
	movwf   ACCbHI
	movlw   0FF             ; loads ACCb = 7FFF
	movwf   ACCbLO
;
	call    D_divS          ; remainder in ACCc. Here ACCb =0040 & ACCc=003F
;
self1    goto    self1
;


;*******************************************************************
;                    Double Precision Multiplication
;
;               ( Optimized for Code Size : Looped 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 )
;
;   Performance :
;               Program Memory  :       033
;               Clock Cycles    :       333
;
;       Note : The above timing is the worst case timing, when the
;               register ACCb = FFFF. The speed may be improved if
;               the register ACCb contains a number ( out of the two
;               numbers ) with less number of 1s.
;
;               The performance specs are for Unsigned arithmetic ( i.e,
;               with "SIGNED equ  FALSE ").
;
;*******************************************************************;
;   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
;      (t) The result is in location ACCbLO & ACCbHI ( 16 bits )
;
;   Performance :
;               Program Memory  :       07
;               Clock Cycles    :       08
;*******************************************************************;
;   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
;      (t) The result is in location ACCbLO & ACCbHI ( 16 bits )
;
;   Performance :
;               Program Memory  :       14
;               Clock Cycles    :       17
;*******************************************************************;
;         Double Precision Subtraction ( ACCb - ACCa -> ACCb )
;
D_sub   call    neg_A           ; At first negate ACCa; Then add
;
;*******************************************************************
;       Double Precision  Addition ( ACCb + ACCa -> ACCb )
D_add   movf    ACCaLO,w        ; Addition ( ACCb + ACCa -> ACCb )
	addwf   ACCbLO          ;add lsb
	btfsc   _carry          ;add in carry
	incf    ACCbHI
	movf    ACCaHI,w
	addwf   ACCbHI            ;add msb
	retlw   0
;*******************************************************************
;               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_mpyS                           ;results in ACCb(16 msb's) and ACCc(16 lsb's)
;
     IF   SIGNED
     CALL    S_SIGN
     ENDIF
;
	call    setup
mloop   rrf     ACCdHI          ;rotate d right
	rrf     ACCdLO
	btfsc   _carry          ;need to add?
	call    D_add
	rrf     ACCbHI
	rrf     ACCbLO
	rrf     ACCcHI
	rrf     ACCcLO
	decfsz  temp            ;loop until all bits checked
	goto    mloop
;
    IF    SIGNED
	btfss   sign,MSB
	retlw   0
	comf    ACCcLO          ; negate ACCa ( -ACCa -> ACCa )
	incf    ACCcLO
	btfsc   _z
	decf    ACCcHI
	comf    ACCcHI
	btfsc   _z
neg_B   comf    ACCbLO          ; negate ACCb
	incf    ACCbLO
	btfsc   _z
	decf    ACCbHI
	comf    ACCbHI
	retlw   0
    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   _z
	decf    ACCbHI
	comf    ACCbHI
;
chek_A  btfss   ACCaHI,MSB        ; if MSB set go & negate ACCa
	retlw   0
	goto    neg_A
;
     ENDIF
;
;*******************************************************************
;                       Test Program
;*******************************************************************
;    Load constant values to ACCa & ACCb for testing
;
test2   movlw   1
	movwf   ACCaHI
	movlw   0FF             ; loads ACCa = 01FF
	movwf   ACCaLO
;
	movlw   07F
	movwf   ACCbHI
	movlw   0FF             ; loads ACCb = 7FFF
	movwf   ACCbLO
;
	call    D_mpyS          ; Here (ACCb,ACCc) = 00FF 7E01
;
self2    goto    self2

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -