list p=16f877a
include "p16f877a.inc"
errorlevel -302
__config _LVP_OFF & _XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF & _BODEN_OFF & _DEBUG_OFF
cblock 0x020 ;start of general purpose registers
CCP1aH
CCP1aL
CCP1bH
CCP1bL
CCP2H
CCP2L
topH
endc
cblock 0x070
topL
btmH
btmL
qH
qL
count
index
endc
; Start at the reset vector
org 0x000
goto Start
Start org 0x010
clrf PORTB
clrf PORTD
clrf PORTC
clrf CCP1aH
clrf CCP1aL
clrf CCP1bH
clrf CCP1bL
clrf CCP2H
clrf CCP2L
clrf TMR1H
clrf TMR1L
clrf count
clrf topH
clrf topL
clrf btmH
clrf btmL
; clrf CCP1CON
clrf CCPR1H
clrf CCPR1L
clrf CCPR2H
clrf CCPR2L
bsf STATUS,RP0 ;bank 1
bcf STATUS,RP1
movlw b'00000110'
movwf TRISC
movlw b'00000000'
movwf TRISB ;portb [7-0] outputs
movlw b'00000000'
movwf TRISD ;portd output
; all inputs DIGITAL
bcf STATUS,RP0 ;bank0
; bcf PIR1,CCP1IF
;**********************************************
Main:
movlw b'00000000' ;timer 1 using to capture, prescaler 1:1
movwf T1CON
bsf T1CON,TMR1ON
movlw b'00000101'
movwf CCP1CON ;start with rising CAPTURE
movlw b'00000101'
movwf CCP2CON ;start CCP2 with rising CAPTURE
bcf PIR1,CCP1IF
bcf PIR2,CCP2IF
Wait:
btfss PIR1,CCP1IF
goto Wait
movf CCPR1H,W ;save the value in H2 and L2 {lower value}
movwf CCP1aH
movf CCPR1L,W
movwf CCP1aL
bcf PIR1,CCP1IF
;
Wait1:
btfss PIR1,CCP1IF
goto Wait1
movf CCPR1H,W ;save now the value in H1,L1
movwf CCP1bH
movf CCPR1L,W
movwf CCP1bL
bcf PIR1,CCP1IF ;clr flag CCP1
Wait2
btfss PIR2,CCP2IF
goto Wait2
movf CCPR2H,W ;save now the value in H1,L1
movwf CCP2H
movf CCPR2L,W
movwf CCP2L
bcf PIR2,CCP2IF ;clr flag CCP1
;*********CCP1b-CCP1a*******************
SUB1:
movf CCP1aL,W
subwf CCP1bL,W
movwf btmL
;movwf PORTB
btfss STATUS, C
goto BORROW1
goto SUB_1
BORROW1:
decf CCP1bH, F
SUB_1:
movf CCP1aH,W
subwf CCP1bH,W
movwf btmH
;movwf PORTD
;*******CCP2-CCP1b****************
SUB2:
movf CCP1bL,W
subwf CCP2L,W
movwf topL
;movwf PORTB
btfss STATUS, C
goto BORROW2
goto SUB_2
BORROW2:
decf CCP2H, F
SUB_2:
movf CCP1bH,W
subwf CCP2H,W
movwf topH
; movwf PORTD
;***********DIVISION***********************
Div:
call Divide
movf qL,w ;@@@@@ RESULTS @@@@@@
movwf PORTB
movf qH,w ; on LEDs connected to rb and rc.
movwf PORTD
goto Main ;-------LOOP BACK TO START----
Divide:
movf btmH,w ; Check for division by 0.
iorwf btmL,w
btfsc STATUS,Z
bsf PORTB,0 ; //**Error code If btm is Zero:PORTB PIN 0 Light LED//**
movlw d'1' ; Otherwise, initialize variables
movwf count
clrf index ; for the division.
clrf qH
clrf qL
Divide_sh_loop:
btfsc btmH,7 ; Shift divisor left
goto Divide_d1
bcf STATUS,C ; until msb is in
rlf btmL,1 ; btmH.7.
rlf btmH,1 ; count = no. of shifts+1.
incf count,1
goto Divide_sh_loop
Divide_d1:
bcf STATUS,C
rlf qL,1 ; Shift quotient left.
rlf qH,1
movf btmL,w ; top = top - btm.
subwf topL,1
btfsc STATUS,C ; If top - btm < 0 then
goto Divide_d2
movlw d'1' ; top = top + btm
subwf topH,1
btfsc STATUS,C ; The idea is to do the
goto Divide_d2
incf topH,1 ; the subtraction and comparison
movf btmL,w ; (top > btm?) in one step.
addwf topL,1
goto Divide_reentr ; Then, if btm > top, undo
Divide_d2:
movf btmH,w ; the subtraction by adding
subwf topH,1
btfss STATUS,C ; top and btm back together
goto Divide_less ;
bsf qL,0
Divide_reentr
bcf STATUS,C
rrf btmH,1
rrf btmL,1
decfsz count,1
goto Divide_d1
retlw 0h ; Return w/ remainder in top
; and result in q.&nsp;
Divide_less
movf btmL,w ; btm > top, so
addwf topL,1
btfsc STATUS,C ; undo the subtraction by
incf topH,1 ; adding them back together.
movf btmH,w
addwf topH,1
goto Divide_reentr ;
end