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

📄 lc2.asm

📁 another LC meter using a p16f628 single chip,it work well for measure LC.
💻 ASM
📖 第 1 页 / 共 2 页
字号:
D200us	MOVLW	0x42		; DELAY  200us
	MOVWF	COUNT1	
NXT5	DECFSZ	COUNT1,F
	GOTO	NXT5	
	RETLW	0

;******************************************************************
;
;	Convert 24-bit binary number at <AARGB0,1,2> into a bcd number
;	at <bcd>. Uses Mike Keitz's procedure for handling bcd 
;	adjust; Modified Microchip AN526 for 24-bits.
;

B2_BCD

b2bcd   movlw   .24		; 24-bits
        movwf   COUNT		; make cycle counter

        clrf    bcd+0		; clear result area
        clrf    bcd+1
        clrf    bcd+2
        clrf    bcd+3
        
b2bcd2  movlw   bcd 		; make pointer
        movwf   FSR
        movlw   .4
        movwf   cnt

; Mike's routine:

b2bcd3  movlw   0x33            
        addwf   INDF,f          ; add to both nybbles
        btfsc   INDF,3          ; test if low result > 7
        andlw   0xf0            ; low result >7 so take the 3 out
        btfsc   INDF,7          ; test if high result > 7
        andlw   0x0f            ; high result > 7 so ok
        subwf   INDF,f          ; any results <= 7, subtract back
        incf    FSR,f           ; point to next
        decfsz  cnt,f
        goto    b2bcd3
        
        rlf     AARGB2,f	; get another bit
        rlf     AARGB1,f
        rlf     AARGB0,f

        rlf     bcd+3,f         ; put it into bcd
        rlf     bcd+2,f
        rlf     bcd+1,f
        rlf     bcd+0,f

        decfsz  COUNT,f         ; all done?
        goto    b2bcd2          ; no, loop
        return                  ; yes


;*********** INITIALISE LCD MODULE 4 BIT MODE ***********************

LCDINIT CALL	MS100		; WAIT FOR LCD MODULE HARDWARE RESET
	BCF	RS		; REGISTER SELECT LOW
	BCF	ENA		; ENABLE LINE LOW
	
	MOVLW	0x03		; 1
	call	PB_dly
	CALL	MS100		; WAIT FOR DISPLAY TO CATCH UP

	MOVLW	0x03		; 2
	call	PB_dly

	MOVLW	0x03		; 3
	call	PB_dly

	MOVLW	0x02		; Fn set 4 bits
	call	PB_dly
	
	MOVLW	0x0C		; 0x0C DISPLAY ON
	CALL	ST200us

	MOVLW	0x28		; DISPLAY 2 Line , 5x7 Dot's
	CALL	ST200us		; New in LC628/LC006 version
	
	MOVLW	0x06		; 0x06 ENTRY MODE SET
	CALL	ST200us		; Fall into CLEAR

;************ CLEAR DISPLAY ***************************

CLEAR	MOVLW	0x01		; CLEAR DISPLAY
	goto	Home2		; LONGER DELAY NEEDED WHEN CLEARING DISPLAY


;*********** MOVE TO HOME *****************************

HOME	movlw	0x09		; Count characters
	movwf	TabStop		; before tickling display.

	MOVLW	0x02		; HOME DISPLAY
Home2	CALL	STROBE
	goto	MS2


;**********************************************************
;
;	SENDS DATA TO LCD DISPLAY MODULE (4 BIT MODE)	
;

STROBE	BCF	RS		; SELECT COMMAND REGISTER
	GOTO	CM


;************ MOVE TO START OF LINE 2 *****************

LINE2	MOVLW	0xC0		; ADDRESS FOR SECOND LINE OF DISPLAY

ST200us	CALL	STROBE
	goto	D200us


;********************************************************************
;       Initialise Input & Output devices
;********************************************************************

InitIO	movlw	b'00000110'
	movwf	CMCON 	   	; Select Comp mode

	bank1

	movlw	b'00000000'
	movwf	VRCON 	   	; Set Volt ref mode to OFF

	movlw	0x37		; Option register
	movwf	OPTION_REG	; Port B weak pull-up enabled
				; INTDEG Don't care
				; Count RA4/T0CKI
				; Count on falling edge
				; Prescale Timer/counter
				; divide Timer/counter by 256

				; PORTA:-
	movlw	b'11110111'	; initialise data direction
				; 1 = input
				; 0 = output
								;
	movwf	TRISA		; PORTA<0>   = comp1 "-" in
				; PORTA<1>   = comp2 "-" in
				; PORTA<2>   = comp1&2 "+" in
				; PORTA<3>   = comp1 out
				; PORTA<4>   = comp2 out, T0CKI in
				; PORTA<5:7> = unused
				;
				;
				; PORTB:-
	movlw	b'01000000'	; initialise data direction
				; 1 = input
				; 0 = output
				;
	movwf	TRISB		; PORTB<0>   = LCD out "DB4"
				; PORTB<1>   =         "DB5"
				; PORTB<2>   =         "DB6"
				; PORTB<3>   =         "DB7"
				; PORTB<4>   = E  out to LCD
				; PORTB<5>   = RS out to LCD
				; PORTB<6>   = function in
				; PORTB<7>   = Ccal switch out

	bank0

	return	

;**********************************************************
;
;	Measure Frequency. Stash in "F3 and F3+1"
;

Measure	bcf	INTCON,T0IF	; Declare "Not yet Over-range"
	CLRF	TMR0		; RESET INTERNAL COUNT (INCLUDING PRESCALER)
				; See page 27 Section 6.0

	CLRF	F3		; Ready to receive 16 bit number
	CLRF	F3+1

	bank1
				; OPEN GATE
	
	movlw	b'11100111'	; Enable RA4 output to T0CKI
	movwf	TRISA		; 1 = input
				; 0 = output
	
	CALL	MS100		; 100MS DELAY

				; CLOSE GATE (COUNT COMPLETE)

	movlw	b'11110111'	; Disable RA4 output to T0CKI
	movwf	TRISA		; 1 = input
				; 0 = output
	bank0

	MOVF	TMR0,W		; GET HIGH BYTE		
	MOVWF	F3		; Copy to Big end of 16 bit result

; The comparator is "outputting" a 1 'cos we've forced it high
; so T0CKI=1.

PSC1	bank1
	bsf	OPTION_REG,T0SE	; Clock the prescaler
	nop
	bcf	OPTION_REG,T0SE
	bank0
	
	DECF	F3+1,F		; Decrement the counter
	
	movf	TMR0,W		; Has TMR0 changed?
	xorwf	F3,W		; if unchanged, XOR -> 0

	beq	PSC1

	return			; F3 : F3+1 now holds 16 bit result

;**********************************************************
;
;	Display contents of AARGB0,1,2 on LCD
;	First convert to BCD, Then ASCII (nybble at a time)
;

Display	CALL	B2_BCD		; CONVERT COUNT TO BCD		

	call	Swap0		; GET NEXT DIGIT
	call	Move0		; GET OTHER BCD DIGIT
	call	Swap1
	call	Move1
	call	Swap2
	call	Move2
	call	Swap3
	goto	Move3		; includes return

;**********************************************************
;
;	Formatted display of BCD work area for Capacitor
;

C_disp	movf	R_sign,w	; Sign
	call	DATS

F_C1	MOVF	bcd+0,W
	ANDLW	0x0F
	beq	F_C2

	CALL	PutNyb
	call	Swap1
	call	Move1
	CALL	DoDP		; Print DP
	call	Swap2
	goto	F_C3U

;--------------------------------------------------

F_C2	swapf	bcd+1,W
	ANDLW	0x0F
	beq	F_C3

	CALL	PutNyb
	call	Move1
	CALL	DoDP		; Print DP
	call	Swap2
	call	Move2
	goto	F_C3U		; print nF. includes RETURN

;--------------------------------------------------

F_C3	MOVF	bcd+1,W
	ANDLW	0x0F
	beq	F_C4

	CALL	PutNyb
	CALL	DoDP		; Print DP
	call	Swap2
	call	Move2
	call	Swap3

F_C3U	movlw	Unit1-0x2100	; nF
	goto	pmsg		; includes RETURN

;--------------------------------------------------

F_C4	SWAPF	bcd+2,W		; Digit1 == 0 ?
	ANDLW	0x0F
	bne	NoB1_C

	MOVLW	0x20		; YES PRINT A SPACE
	call	DATS

	MOVF	bcd+2,W		; Digit2 == 0 ?
	ANDLW	0x0F
	bne	NoB2_C

	MOVLW	0x20		; YES PRINT A SPACE
	call	DATS
	bra	NoB3_C

NoB1_C	call	Swap2		; 1
NoB2_C	call	Move2		; 2
NoB3_C	call	Swap3		; 3
	CALL	DoDP		; Print DP
	call	Move3		; 4

	movlw	Unit2-0x2100	; pF
	goto	pmsg		; includes RETURN

;**********************************************************
;
;	Formatted display of BCD work area for Inductor
;

L_disp	movf	R_sign,w	; Sign
	call	DATS

F_L1	MOVF	bcd+0,W
	ANDLW	0x0F
	beq	F_L2

	CALL	PutNyb
	call	Swap1
	CALL	DoDP		; Print DP
	call	Move1
	call	Swap2
	goto	F_L2U		; Print mH. includes RETURN

;--------------------------------------------------

F_L2	swapf	bcd+1,W
	ANDLW	0x0F
	beq	F_L3

	CALL	PutNyb
	CALL	DoDP		; Print DP
	call	Move1
	call	Swap2
	call	Move2
	
F_L2U	movlw	Unit3-0x2100	; mH
	goto	pmsg		; includes RETURN

;--------------------------------------------------

F_L3	MOVF	bcd+1,W
	ANDLW	0x0F
	beq	F_L4

	CALL	PutNyb
	call	Swap2
	call	Move2
	CALL	DoDP		; Print DP
	call	Swap3
	goto	F_L4U		; Print uH. includes RETURN

;--------------------------------------------------

F_L4	SWAPF	bcd+2,W		; Digit1 == 0 ?
	ANDLW	0x0F
	bne	NoB1_L

	MOVLW	0x20		; YES PRINT A SPACE
	call	DATS

	goto	NoB2_L

NoB1_L	call	Swap2		; 1
NoB2_L	call	Move2		; 2
	CALL	DoDP		; Print DP
	call	Swap3		; 3
	call	Move3		; 4

F_L4U	movlw	Unit4-0x2100	; uH
	goto	pmsg		; includes RETURN

;--------------------------------------------------
;
;	Common subroutine for formatted output
;

DoDP	MOVLW	'.'		; Print DP
	goto	DATS		; Return from DATS

Swap0	SWAPF	bcd+0,W		; GET NEXT DIGIT
	goto	PutNyb		; DISPLAY IT

Move0	MOVF	bcd+0,W		; GET OTHER BCD DIGIT
	goto	PutNyb

Swap1	SWAPF	bcd+1,W
	goto	PutNyb

Move1	MOVF	bcd+1,W
	goto	PutNyb

Swap2	SWAPF	bcd+2,W
	goto	PutNyb

Move2	MOVF	bcd+2,W
	goto	PutNyb

Swap3	SWAPF	bcd+3,W
	goto	PutNyb

Move3	MOVF	bcd+3,W
	goto	PutNyb

;********************************************************************
;
;	Stack operations
;
;********************************************************************	

;add		call	FPA24
;		goto	S_fix

subtract	call	FPS24
		goto	S_fix

divide		call	FPD24
		goto	S_fix

multiply	call	FPM24
;		goto	S_fix

;
;	Fix stack after add, subtract, divide & multiply
;	AND Collect ALL Floating Point Errors in FPE

S_fix	iorwf	FPE,f			; W may hold Error (0xff)

	copy	CARGB1,BARGB1		; C -> B
	copy	CARGB0,BARGB0
	copy	CEXP,BEXP
	return

;
;	Push stack (duplicates TOS)
;

S_push	copy	BARGB1,CARGB1		; B -> C
	copy	BARGB0,CARGB0
	copy	BEXP,CEXP

	copy	AARGB1,BARGB1		; A -> B
	copy	AARGB0,BARGB0
	copy	AEXP,BEXP
	return

;
;	Swap A and B

S_swap	swap	AARGB1,BARGB1		; A <-> B
	swap	AARGB0,BARGB0
	swap	AEXP,BEXP
	return

;********************************************************************
;
;	Calculate Unknown Capacitance OR inductance
;	
;       Output: 24 bit positive integer (scaled)
;	right justified in AARGB0, AARGB1, AARGB2
;	also as BCD in bcd:bcd+1:bcd+2:bcd+3
;
;********************************************************************	

C_calc	call	divide
	call	Get_Ccal	; Times 10,000 ( = 1000.0pF)
	call	multiply
	goto	PorM		; includes return

;--------------------------------------------------------------------

L_calc	call	multiply
	call	Get_Lscale	; Precomputed Scale_factor/(4*PI*PI)
	call	multiply
	call	Get_Ccal
	call	S_swap
	call	divide

L_divF1	call	Get_F1		; Divide by F1^2
	call	S_push
	call	multiply
	call	S_swap
	call	divide

;
;	Handle Space or Minus in front of FP number
;	

PorM	btfss	AARGB0,7	; test sign
	goto	Pplus
	
Pminus	movlw	0x2d		; minus
	goto	PMdisp

Pplus	movlw	0x20		; plus

PMdisp	movwf	R_sign		; save for later display
	bcf	AARGB0,7	; make plus anyway

;
;	Format as raw BCD string in bcd:bcd+1:bcd+2:bcd+3
;

	call	INT2424		; To INT in AARGB0 etc.
	iorwf	FPE,f		; W may hold Error (0xff)
	goto	B2_BCD		; includes return

;********************************************************************
;
;	Calculate (F1/F3)^2-1, leave result on stack
;
;********************************************************************	

F1_F3	call	Get_F3
	goto	F1_F1

;********************************************************************
;
;	Calculate (F1/F2)^2-1, leave result on stack
;
;********************************************************************	

F1_F2	call	Get_F2
F1_F1	call	Get_F1
	call	divide		; F1/Fx
	call	S_push
	call	multiply	; (F1/Fx)^2
	call	Get_One
	call	S_swap
	goto	subtract	; (F1/Fx)^2-1
				; includes return

;********************************************************************
;	Fetch assorted things used for the calculation
;	of Unknown L and C
;
;********************************************************************	

Get_Lscale	call	S_push		; make room first
		movlw	0xB8		; 2.53303e+17
		movwf	AEXP		; Create FP version of
		movlw	0x60		; Precomputed 1/(4*PI*PI)
		movwf	AARGB0		; times any needed
		movlw	0xFA		; fiddle factor (1/100)
		movwf	AARGB1
		return

Get_One		call	S_push		; make room first
		clrf	AEXP		; Create a binary 1
		clrf	AARGB0
		clrf	AARGB1
		movlw	0x01
		goto	LSB2stak
	

Get_Ccal	movlw	cal_t		; Get integer value
		goto	W2stak		; Includes stack push

Get_F1		movlw	F1		; Includes stack push
		goto	W2stak

Get_F2		movlw	F2		; Includes stack push
		goto	W2stak

Get_F3		movlw	F3		; Includes stack push
;		goto	W2stak

;********************************************************************
;	Copy 16 bit number, pointed to by W, to stack
;	and convert to FP (positive value only)
;	via a 24 bit number in AARGB0,1,2
;********************************************************************	

W2stak		movwf	FSR
		call	S_push		; make room first

		clrf	AEXP
		clrf	AARGB0

		movf	INDF,W		; Big Byte first
		movwf	AARGB1

		incf	FSR,F		; then little byte

		movf	INDF,W
LSB2stak	movwf	AARGB2
		
		CALL	FLO2424		; 24 bit int -> 24 bit FP
		iorwf	FPE,f		; W may hold Error (0xff)
		RETURN

;********************************************************************
;	Read EEPROM into "cal_t"
;********************************************************************	

EE_RD	bank1
	movlw	cal_p-0x2100	; Address to read
	MOVWF	EEADR
	bank0

	CALL	EE_R
	MOVWF	cal_t+0

	CALL	EE_Rinc
	MOVWF	cal_t+1

	RETURN

EE_Rinc	bank1
	INCF	EEADR,F		; bump address

EE_R	bank1
	BSF	EECON1,RD	; EE Read
	MOVF	EEDATA,W	; W = EEDATA
	bank0

	RETURN


;********************************************************************
;	Write EEPROM from "cal_t"
;********************************************************************	

EE_WR	bank1
	movlw	cal_p-0x2100
	MOVWF	EEADR		; Address to write

	MOVF	cal_t+0,W	; Data byte #0
	CALL	EE_W

	MOVF	cal_t+1,W	; Data byte #1
	CALL	EE_Winc

	bank0
	RETURN

	errorlevel	-302	; In Bank 2

EE_Winc	INCF	EEADR,F		; bump address
	
EE_W	MOVWF	EEDATA
	BSF	EECON1,WREN	; Enable Write
	MOVLW	0x55		;
	MOVWF	EECON2		; Write 0x55
	MOVLW	0xAA		;
	MOVWF	EECON2		; Write 0xAA
	BSF	EECON1,WR	; Set WR bit (begin write)

EE_W2	BTFSC	EECON1,WR	; Wait for write to finish
	GOTO	EE_W2

	bank0
	BCF	PIR1,EEIF	; clear interrupts
	bank1
	RETURN	

	errorlevel	+302

;********************************************************************	

	INCLUDE <FP.TXT>

;********************************************************************
;
;	Text Strings (stored in data EEPROM)
;

        ORG 0x2100

ovr	de	"   Over Range   ",0
Unit1	de	" nF",0
Unit2	de	" pF",0
Unit3	de	" mH",0
Unit4	de	" uH",0
Cintro	de	" C = ",0
Lintro	de	" L = ",0
Calibr  de	"   Calibrating  ",0

cal_p	de	0x27,0x10		; Initial value = 10000

 	END

;********************************************************************

⌨️ 快捷键说明

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