pmeter.asm

来自「Simple watt meter using pic16f」· 汇编 代码 · 共 926 行 · 第 1/3 页

ASM
926
字号
;------------------------------------------------------
        call    GET_AD          ; A/D value is put into PWR

        movf    PWR,w           ; Get PWR
        addwf   sLO             ; add to sLO accumulator
        btfsc   _carry          ; check carry bit
        incf    sHI
	return                  ; END OF RTCC_SERVICE


;********************************************************************
;  GET_AD
;       Read A/D Converter.  Nat'l AD0831
;       ON ENTRY: None
;       ON EXIT: Data returned in PWR
;       REGS DESTROYED: W, ADcnt, PWR
;********************************************************************
GET_AD
	movlw	.9              ; first bit out is garbage
	movwf	ADcnt
        bcf     ad_cs           ; drop chip select to start conv
AD1
        nop
        nop
        bsf	ad_clk          ; Raise clk
        nop             
        bcf     ad_clk          ; Data is valid after falling edge
        nop
        nop
        nop
        nop
        nop
        btfss   ad_dat          ; Move ad_dat into carry bit
        goto    ad_is_low
        bsf     _carry
        goto    data_in_carry
ad_is_low
        bcf     _carry
data_in_carry
        rlf     PWR             ; Msb is first out of a/d, so rlf
	decfsz	ADcnt
        goto    AD1
        bsf     ad_cs           ; raise chip select to end conv
;
;       Conversion Over, Now scale data
;
        movf    PWR,w
        sublw   0x80            ; W = 0x80 - W
        btfss   _carry          ; _carry set = positive
        goto    neg_result
        movwf   PWR
        goto    get_ad_over
neg_result
        movlw   0x80
        subwf   PWR             ; PWR = PWR - 0x80                        
get_ad_over
        movf    PWR,w           ; Add hysteresis
        sublw   0x02            ; W = 0x02 - W
        btfsc   _carry          ; _carry clear = negative
        clrf    PWR             ; make values 2 or less = zero
	return


;********************************************************************
;  DELAY                               a       b  c
;       ON ENTRY: W = AMT TO  Delay=   5+[(256*3)+5]*W  Tcyc
;       REGS DESTROYED: W, CNTR1, CNTR2, 
;********************************************************************
DELAY	movwf	CNTR2           ; a  (1)   SUBPROGRAM ENTRY
        clrf    CNTR1           ; a  (1)   cntr1 is lsb of counter
LOOP	incfsz	CNTR1,1         ;  bc(2/1) <-- This inner loop
	goto	LOOP            ;  b (2)   <-- executed 256 times
	decfsz	CNTR2,1         ; a c(2/1)  Note:skips take 2cyc
	goto	LOOP            ;   c(2)
	return                  ; a  (2)

;********************************************************************
; AYDISP1
;       Displays 4 most sig digits of BCD num in ACCdLO,ACCaHI,ACCaLO.
;       ON ENTRY: ACCdLO,ACCaHI,ACCaLO= 5digit BCD numb ACCdLO=msb
;       RETURNS: None.
;       OUTPUTS: ay_ld
;       REGS DESTROYED: W, _carry, ACCdLO,ACCaHI,ACCaLO
;********************************************************************
AYDISP1	
	movf	ACCdLO,0        ; get bcd digit5
        btfsc   ay_dp4          ; test dp4 if set, then set _carry
        iorlw   0x80
	call	AYDIGIT         ; Do LCD Digit 4, leftmost on display

	swapf	ACCaHI,0
	andlw	0Fh             ; get bcd digit 4
        btfsc   ay_dp3          ; test dp3 if set, then set _carry
        iorlw   0x80
	call	AYDIGIT         ; Do LCD Digit 3

	movf	ACCaHI,0
	andlw	0Fh             ; get bcd digit 3
        btfsc   ay_dp2          ; test dp2 if set, then set _carry
        iorlw   0x80
	call	AYDIGIT         ; Do LCD Digit 2

	swapf	ACCaLO,0
	andlw	0Fh             ; get bcd digit 2
        btfsc   ay_l            ; test l if set, then set _carry
        iorlw   0x80
	call	AYDIGIT         ; Do LCD Digit 1

	bsf	ay_ld	        ; Done. Raise ay_ld to latch data to AY
        nop
        bcf     ay_ld
	return

;********************************************************************
; AYDISP2
;       Displays 4 least sig digits of BCD num in ACCdLO,ACCaHI,ACCaLO.
;       ON ENTRY: ACCdLO,ACCaHI,ACCaLO= 5digit BCD numb ACCdLO=msb
;       RETURNS: None.
;       OUTPUTS: ay_ld
;       REGS DESTROYED: W, _carry, ACCdLO,ACCaHI,ACCaLO
;********************************************************************
AYDISP2
	swapf	ACCaHI,0
	andlw	0Fh             ; get bcd digit 4
        btfsc   ay_dp4          ; test dp4 if set, then set bit7 of W
        iorlw   0x80
	call	AYDIGIT         ; Do LCD Digit 4, leftmost on display

	movf	ACCaHI,0
	andlw	0Fh             ; get bcd digit 3
        btfsc   ay_dp3          ; test dp3 if set, then set _carry
        iorlw   0x80
        bsf     _carry
	call	AYDIGIT         ; Do LCD Digit 3

	swapf	ACCaLO,0
	andlw	0Fh             ; get bcd digit 2
        btfsc   ay_dp2          ; test dp2 if set, then set _carry
        iorlw   0x80
	call	AYDIGIT         ; Do LCD Digit 2

	movf	ACCaLO,0
	andlw	0Fh             ; get bcd digit 1
        btfsc   ay_l            ; test l if set, then set _carry
        iorlw   0x80
	call	AYDIGIT         ; Do LCD Digit 1

	bsf	ay_ld	        ; Done. Raise ay_ld to latch data to AY
        nop
        bcf     ay_ld
	return


;********************************************************************
; AYTEST
;       Walks segment accross display at 100ms intervals.
;       ON ENTRY: None.
;       RETURNS: None.
;       OUTPUTS: ay_ld, ay_clk, ay_dat
;       REGS DESTROYED: W, AY_CNT,
;********************************************************************
AYTEST	
	movlw	.32		; Clear all segments
	movwf	AY_CNT		; STORE
AY1_LP	bsf	ay_clk	        ; Raise clk
	bcf	ay_dat	        ; Lower data - all zero data
	bcf	ay_clk	        ; Lower clk
	decfsz	AY_CNT		; MOVE TO NEXT BIT
	goto	AY1_LP
	bsf	ay_ld	        ; Done. Raise ay_ld to latch data to AY
        nop
        bcf     ay_ld

	bsf	ay_clk	        ; Raise clk
	bsf	ay_dat	        ; Lonely one
	bcf	ay_clk	        ; Lower clk
	bsf	ay_ld	        ; Done. Raise ay_ld to latch data to AY
        nop
        bcf     ay_ld
        
AY_WAIT1
        btfsc   mode_sw         ; wait for user to press button
        goto    AY_WAIT1
AY_WAIT1R
        btfss   mode_sw         ; wait for user to release button
        goto    AY_WAIT1R
        
	movlw	.31		; # BITS TO SHIFT
	movwf	AY_CNT		; STORE
AY2_LP	bsf	ay_clk	        ; Raise clk
	bcf	ay_dat	        ; Lower data
	bcf	ay_clk	        ; Lower clk
	bsf	ay_ld	        ; Done. Raise ay_ld to latch data to AY
        nop
        bcf     ay_ld
AY_WAIT2
        btfsc   mode_sw
        goto    AY_WAIT2
AY_WAIT2R
        btfss   mode_sw         ; wait for user to release button
        goto    AY_WAIT2R

	decfsz	AY_CNT		; MOVE TO NEXT BIT
	goto	AY2_LP
	return


;********************************************************************
; AYMSG
;       Displays 4 digit Msg from MAPSEG table.
;       ON ENTRY: W=MAPSEG offset
;       RETURNS: None.
;       OUTPUTS: ay_ld
;       REGS DESTROYED: W, _carry, ACCdLO,ACCaHI,ACCaLO
;********************************************************************
AYMSG
	movwf   ACCdLO          ; save offset in temp register
	call	AYDIGIT         ; Do LCD Digit 4, leftmost on display

        incf    ACCdLO          ; Get next byte of msg
        movf    ACCdLO,w        
	call	AYDIGIT         ; Do LCD Digit 3

        incf    ACCdLO          ; Get next byte of msg
        movf    ACCdLO,w        
	call	AYDIGIT         ; Do LCD Digit 2

        incf    ACCdLO          ; Get next byte of msg
        movf    ACCdLO,w        
	call	AYDIGIT         ; Do LCD Digit 1

	bsf	ay_ld	        ; Done. Raise ay_ld to latch data to AY
        nop
        bcf     ay_ld
	return


;********************************************************************
; AYDIGIT
;       Shifts 8bits of data, 1 digit, to AY chip. 
;       ON ENTRY: W=bit6-0=index to seg table, bit7 indicates DP
;       RETURNS:  None.
;       OUTPUTS:  ay_clk, ay_dat
;       REGS DESTROYED: W, AY_TEMP, AY_CNT, SAV_W
;********************************************************************
AYDIGIT	
	movwf	AY_TEMP		; store table offset/ DP bit
        movlw   HIGH MAPSEG     
        movwf   _pclath         ; insure page boundary taken care of
        movf    AY_TEMP,w       ; restore table offset
        andlw   0x7F            ; suppress DP in bit 7
        call	MAPSEG  	; call to table read will wipe out carry
        btfsc   AY_TEMP,7       ; See if we need to adjust for DP
        addlw   1               ; Increment segment pattern
	movwf	AY_TEMP		; STORE SEG PATTERN

	movlw	8		; # BITS TO SHIFT
	movwf	AY_CNT		; STORE
BIT_LP	bsf	ay_clk	        ; Raise clk
	rlf	AY_TEMP,1	; MOVE BIT TO _carry
	btfsc	_carry   	; TEST IT
	goto	RAISE1		; IF HIGH GO TO RAISE
	bcf	ay_dat	        ; Lower data
	goto	LATCH
RAISE1	bsf	ay_dat	        ; Raise data
LATCH	bcf	ay_clk	        ; Lower clk
	decfsz	AY_CNT		; MOVE TO NEXT BIT
	goto	BIT_LP
        bsf     ay_clk          ; Raise clk
	return

;********************************************************************
;  MAPSEG
;       ON ENTRY: W = index into segment table
;       RETURNS:  W = 7 segment display representation
;       REGS DESTROYED: W 
;********************************************************************
MAPSEG
        addwf   _pcl            ; add bcd to pc to create jump table
SEGTBL
; segment map ->  ABCDEFGDP     ; 1=visible for lcd                
	retlw   b'11111100'     ; off=0  7 seg rep of zero  
	retlw   b'01100000'     ; off=1  7 seg rep of one   
	retlw   b'11011010'     ; off=2  7 seg rep of two   
	retlw   b'11110010'     ; off=3  7 seg rep of three 
	retlw   b'01100110'     ; off=4  7 seg rep of four  
	retlw   b'10110110'     ; off=5  7 seg rep of five  
	retlw   b'10111110'     ; off=6  7 seg rep of six   
	retlw   b'11100000'     ; off=7  7 seg rep of seven 
	retlw   b'11111110'     ; off=8  7 seg rep of eight 
	retlw   b'11100110'     ; off=9  7 seg rep of nine  
	retlw   b'11101110'     ; off=A  7 seg rep of A     
	retlw   b'00111110'     ; off=B  7 seg rep of b     
	retlw   b'10011100'     ; off=C  7 seg rep of C     
	retlw   b'01111010'     ; off=D  7 seg rep of d     
	retlw   b'10011110'     ; off=E  7 seg rep of e     
	retlw   b'10001110'     ; off=F  7 seg rep of f     
	retlw   b'00011100'     ; off=10 7 seg rep of 'L'     
	retlw   b'00111010'     ; off=11 7 seg rep of 'o'
	retlw   b'00000000'     ; off=12 7 seg rep of ' '
	retlw   b'00111110'     ; off=13 7 seg rep of 'b'     
	retlw   b'11101110'     ; off=14 7 seg rep of A     
	retlw   b'00000000'     ; off=15 7 seg rep of ' '
	retlw   b'10011110'     ; off=16 7 seg rep of e     
	retlw   b'00000000'     ; off=17 7 seg rep of ' '
;
        END

⌨️ 快捷键说明

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