📄 lcfmet737.asm
字号:
bsf RSLINE,4 ; set RS for data send
call BIN2DEC
call CHECKNANO
call SHOWITALL
movlw 'u'
movf LARGE,F
btfss STATUS,Z
goto CAP2
movlw 'n'
movf NANO,F
btfsc STATUS,Z
movlw 'p'
CAP2: call LCDOUT
movlw 'F'
call LCDOUT
movlw ' '
call LCDOUT
movlw ' '
call LCDOUT
movlw ' '
call LCDOUT
movlw ' '
goto MAIN
; **************
LARGEVALUE:
clrf TIMEOUT
incf LARGE,F
movlw %00000000 ; stop timer 1
movwf T1CON
clrf TMR1L ; reset timer 1
clrf TMR1H
bcf PIR1,0 ; clear timer rollover flag
movf PORTB,W ; get current status of RB6
andlw %01000000
movwf STORE ; store it
clrf SLOWIT
bsf T1CON,0 ; start timer 1
WAITB1:
movf PORTA,W
andlw %00010000
xorwf SWITCH,W
btfss STATUS,Z
return
WAITB2: movf PORTB,W ; get current status of RB6
andlw %01000000
movwf STORE2 ; temp store it
xorwf STORE,W ; compare with prev val of RB6
btfsc STATUS,Z ; is it equal?
goto WAITB1 ; yes
movf STORE2,W ; no, different, so store val
movwf STORE
call OSCILLATE ; get timing between two changes of RB6 (1 full cycle)
btfsc TIMEOUT,0
return
call COPY_TIME_REGA
movlw 122
call MULTIPLYSMALL ; REGA * 122 -> REGA multiply freq x 122 to get time re 3.2768MHz xtal (1000000/819200 =1.22)
movlw 100 ; divide by 100
call DIVIDESMALL ; REGA / 100 -> REGA
call COPY_REGA_REGB ; copy answer into REGB
call DIVIDEBILLION ; 1,000,000,000 / REGB -> REGA
movf REGA0,W ; copy answer back into TIMER
movwf TMR1L
movf REGA1,W
movwf TMR1H
movf REGA2,W
movwf TIMEMSB
movlw 4
movwf POINT
return
; ***********
CHECKNANO: clrf NANO
movf DIGIT1,W
iorwf DIGIT2,W
iorwf DIGIT3,W
iorwf DIGIT4,W
iorwf DIGIT5,W
iorwf DIGIT6,W
andlw %00001111
btfsc STATUS,Z
return
bsf NANO,0
movlw 4
movwf POINT
return
; ***********
CHECKMILLI: clrf NANO
movf DIGIT1,W
iorwf DIGIT2,W
iorwf DIGIT3,W
iorwf DIGIT4,W
iorwf DIGIT5,W
andlw %00001111
btfsc STATUS,Z
return
bsf NANO,0
movlw 7
movwf POINT
return
; *************
CALIBCAP: movf REGA0,W
movwf CAPREF0
movf REGA1,W
movwf CAPREF1
movf REGA2,W
movwf CAPREF2
movf REGA3,W
movwf CAPREF3
call SHOWCALIB
return
CALIBIND: movf REGA0,W
movwf INDREF0
movf REGA1,W
movwf INDREF1
movf REGA2,W
movwf INDREF2
movf REGA3,W
movwf INDREF3
call SHOWCALIB
return
; **************
SHOWCALIB: call LCD1
bsf RSLINE,4
clrf LOOP
CALIB2: movf LOOP,W
call CALIB
call LCDOUT
incf LOOP,F
btfss LOOP,4
goto CALIB2
call PAUSIT
return
; **************
SUBTRACTCAPREF: ; subtract ref from current val
; REGA - REGB -> REGA ;Return carry set if overflow
movf CAPREF3,W
movwf REGB3
movf CAPREF2,W
movwf REGB2
movf CAPREF1,W
movwf REGB1
movf CAPREF0,W
movwf REGB0
call SUBTRACT
movf STATUS,W
andlw 1
movwf OVERFLOW
return
SUBTRACTINDREF: ; subtract ref from current val
; REGA - REGB -> REGA ;Return carry set if overflow
movf INDREF3,W
movwf REGB3
movf INDREF2,W
movwf REGB2
movf INDREF1,W
movwf REGB1
movf INDREF0,W
movwf REGB0
call SUBTRACT
movf STATUS,W
andlw 1
movwf OVERFLOW
return
; **************
INDTIMER: movlw %00000110 ; T1 ext osc sync off (bit 2) timer1 off
movwf T1CON ; uses T1 ext clock input via RB6 and measures
; number of clock pulses during 25 cycles of TMR0
BANK1
movlw %10000110 ; timer 1:128, pullups off
movwf OPTION_REG
BANK0
clrf TMR1L ; reset timer 1
clrf TMR1H
clrf TIMEMSB
bcf PIR1,0 ; clr timer rollover flag
movlw %00000111 ; T1 ext osc sync off (bit 2) timer1 on
movwf T1CON
movlw 25
movwf SLOWIT
clrf TMR0
bcf INTCON,2
TIMEIT: btfss PIR1,0 ; has timer 1 overflowed?
goto TIMIT2
bcf PIR1,0
incf TIMEMSB,F
TIMIT2: btfss INTCON,2 ; has timer 0 overflowed?
goto TIMEIT
bcf INTCON,2
decfsz SLOWIT,F
goto TIMEIT
movlw %00000000
movwf T1CON
return
; ****************
OSCILLATE: clrf ZERO
clrf T1CON
clrf TMR1H
clrf TMR1L
bcf PIR1,0
bsf T1CON,0 ; start timer 1
clrf TIMEMSB
bsf T1CON,0 ; start timer 1
OSCA1:
movf PORTA,W
andlw %00010000
xorwf SWITCH,W
btfss STATUS,Z
return
btfsc PIR1,0 ; has timer 1 overflowed?
call INCMSB ; yes
OSCA1A: movf PORTB,W ; is RB6 same as before?
andlw %01000000
movwf STORE2
xorwf STORE,W
btfsc STATUS,Z
goto OSCA1 ; yes
movf STORE2,W ; no, so continue for next cycle
movwf STORE
OSCA2:
movf PORTA,W
andlw %00010000
xorwf SWITCH,W
btfss STATUS,Z
return
btfsc PIR1,0 ; has timer 1 overflowed?
call INCMSB ; yes
OSCA2A: movf PORTB,W ; is RB6 same as before?
andlw %01000000
movwf STORE2
xorwf STORE,W
btfsc STATUS,Z
goto OSCA2 ; yes
movlw %00000000 ; no, stop timer 1
movwf T1CON
return
INCMSB: incf TIMEMSB,F
decf SLOWIT,F
bcf PIR1,0
clrf TMR1H
clrf TMR1L
movf SLOWIT,F
btfsc STATUS,Z
bsf ZERO,0
return
;******** LCD ROUTINES **********
LCD1: movlw %10000000
goto LCDLIN
LCD5: movlw %10000101
goto LCDLIN
LCD6: movlw %10000110
goto LCDLIN
LCD8: movlw %10001000
goto LCDLIN
LCD9: movlw %10001001
goto LCDLIN
LCD13: movlw %10001101
goto LCDLIN
LCD15: movlw %10001111
goto LCDLIN
LCD21: movlw %11000000
goto LCDLIN
LCD25: movlw %11000101
goto LCDLIN
LCD26: movlw %11000110
goto LCDLIN
LCD28: movlw %11001000
LCDLIN: BCF RSLINE,4
LCDOUT: movwf STORE
movlw 50
movwf LOOPA
DELAYIT: decfsz LOOPA,F
goto DELAYIT
call SENDIT
SENDIT: swapf STORE,F
movf STORE,W
andlw 15
iorwf RSLINE,W
movwf PORTB
BSF PORTB,5
nop
nop
BCF PORTB,5
RETURN
; *************
PAUSIT: movlw 25
movwf SLOWIT
bcf INTCON,2
PAUSE: btfss INTCON,2
goto PAUSE
bcf INTCON,2
decfsz SLOWIT,F
goto PAUSE
return
PAUSIT2: clrf TMR0
movlw 10
movwf SLOWIT
bcf INTCON,2
PAUSE2: btfss INTCON,2
goto PAUSE2
bcf INTCON,2
decfsz SLOWIT,F
goto PAUSE2
return
;..............
LCDSET: clrf LOOP ;clr LCD set-up loop
clrf RSLINE ;clear RS line for instruction send
LCDST2: movf LOOP,W ;get table address
call TABLCD ;get set-up instruction
call LCDOUT ;perform it
incf LOOP,F ;inc loop
btfss LOOP,3 ;has last LCD set-up instruction now been done?
goto LCDST2 ;no
return
CLRLINE1: call LCD1 ;set address for line 1 cell 1
bsf RSLINE,4 ;set RS for data send
clrf LOOP ;
CLRL1: movlw ' ' ;clear cell
call LCDOUT ;
incf LOOP,F ;inc loop
btfss LOOP,4 ;has last LCD letter been sent?
goto CLRL1 ;no
return
CLRLINE2: call LCD21
bsf RSLINE,4
movlw 16
movwf LOOP
CL2: movlw ' '
call LCDOUT
decfsz LOOP,F
goto CL2
return
; ***********
SHOWITALL: movlw DIGIT1
movwf FSR
movlw 10
movwf LOOP
SHOW2: movf INDF,W
call LCDOUT
movf LOOP,W
xorwf POINT,W
btfss STATUS,Z
goto SHOW3
movlw '.'
call LCDOUT
SHOW3: incf FSR,F
decfsz LOOP,F
goto SHOW2
return
; ***********
COPY_TIME_REGA:
movf TIMEMSB,W
movwf REGA2
movf TMR1H,W
movwf REGA1
movf TMR1L,W
movwf REGA0
clrf REGA3
return
; *********
MULTIPLYSMALL:
movwf REGB0
clrf REGB1
clrf REGB2
clrf REGB3
call MULTIPLY
movf STATUS,W
andlw 1
movwf OVERFLOW
return
; *************
DIVIDESMALL:
movwf REGB0
clrf REGB1
clrf REGB2
clrf REGB3
call DIVIDE
movf STATUS,W
andlw 1
movwf OVERFLOW
return
; ***********
DIVIDEBILLION:
movlw $3B ; divide 1,000,000,000 ($3B9ACA00) by the answer
movwf REGA3
movlw $9A
movwf REGA2
movlw $CA
movwf REGA1
movlw $00
movwf REGA0
call DIVIDE
movf STATUS,W
andlw 1
movwf OVERFLOW
return
; ***********
COPY_REGA_REGB:
movf REGA0,W
movwf REGB0
movf REGA1,W
movwf REGB1
movf REGA2,W
movwf REGB2
movf REGA3,W
movwf REGB3
return
; *********** PETER HEMSLEY'S 32-BIT MATHS ROUTINES *******
;*** SIGNED MULTIPLY ***
;REGA * REGB -> REGA
;Return carry set if overflow
multiply
clrf MTEMP ;Reset sign flag
call chksgna ;Make REGA positive
skpc
call chksgnb ;Make REGB positive
skpnc
return ;Overflow
call movac ;Move REGA to REGC
call clra ;Clear product
movlw D'31' ;Loop counter
movwf MCOUNT
muloop call slac ;Shift left product and multiplicand
rlf REGC3,w ;Test MSB of multiplicand
skpnc ;If multiplicand bit is a 1 then
call addba ;add multiplier to product
skpc ;Check for overflow
rlf REGA3,w
skpnc
return
decfsz MCOUNT,f ;Next
goto muloop
btfsc MTEMP,0 ;Check result sign
call negatea ;Negative
return
; *************
;*** SIGNED DIVIDE ***
;REGA / REGB -> REGA
;Remainder in REGC
;Return carry set if overflow or division by zero
divide clrf MTEMP ;Reset sign flag
movf REGB0,w ;Trap division by zero
iorwf REGB1,w
iorwf REGB2,w
iorwf REGB3,w
sublw 0
skpc
call chksgna ;Make dividend (REGA) positive
skpc
call chksgnb ;Make divisor (REGB) positive
skpnc
return ;Overflow
clrf REGC0 ;Clear remainder
clrf REGC1
clrf REGC2
clrf REGC3
movlw D'32' ;Loop counter
movwf MCOUNT
dvloop call slac ;Shift dividend (REGA) msb into remainder (REGC)
movf REGB3,w ;Test if remainder (REGC) >= divisor (REGB)
subwf REGC3,w
skpz
goto dtstgt
movf REGB2,w
subwf REGC2,w
skpz
goto dtstgt
movf REGB1,w
subwf REGC1,w
skpz
goto dtstgt
movf REGB0,w
subwf REGC0,w
dtstgt skpc ;Carry set if remainder >= divisor
goto dremlt
movf REGB0,w ;Subtract divisor (REGB) from remainder (REGC)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -