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

📄 pmeter.asm

📁 Simple watt meter using pic16f
💻 ASM
📖 第 1 页 / 共 3 页
字号:
LIST  P=16C71, F=INHX8M, R=HEX, C=132, N=804, T=OFF
TITLE "AC Power Meter - Rick May"
;******************************************************************************
;*                         D E C L A R A T I O N S                            *
;******************************************************************************
	include         "16cXX.h"

;       Register Assignments for MATH routines
;       --------------------------------------        
count   equ     0X13
temp    equ     0X14

ACCaLO  equ     0X15
ACCaHI  equ     0x16
ACCbLO  equ     0x17
ACCbHI  equ     0x18
ACCcLO  equ     0x19
ACCcHI  equ     0x1A
ACCdLO  equ     0x1B
ACCdHI  equ     0x1C

;       Register Assignments 
;	--------------------
AY_DP	EQU  0X1D	; Decimal point Array used by AYDISP1, AYDISP2
AY_TEMP EQU  0X1E	; temp reg used by AYDIGIT
AY_CNT	EQU  0X1F	; shift count used by AYDIGIT

TIC     EQU  0x20	; Number of 10ms intervals/sec 0-99.
SEC     EQU  0x21	; Number of seconds 0-59.
MIN     EQU  0x22       ; Number of minutes.   

SAV_W   EQU  0x23       ; PLACE TO SAVE W DURING INT
SAV_ST  EQU  0x24       ; PLACE TO SAVE STAT DURING INT  

CNTR1	EQU  0X25	; DELAY COUNT used by DELAY
CNTR2	EQU  0X26	; DELAY COUNT used by DELAY

sHI     EQU  0X27       ; 1 second energy accumulator, updated in ISR
sLO     EQU  0X28

eHI     EQU  0X29       ; Master energy accumulator, e, updated in bkgrnd
eMED    EQU  0X2A
eLO     EQU  0X2B   

PWR     EQU  0X2C
ADcnt   EQU  0X2D       ; Count used in A/D converter operations, used by ISR
MODE    EQU  0X2F   

;

;       Bit Definitions
;	---------------
#define mode_sw _portb,0        ; SWITCH DEFINITIONS
#define res_sw  _portb,1

#define ad_cs   _portb,2        ; NATIONAL ADC0831 A/D Converter DEFINITIONS
#define ad_clk  _portb,3
#define ad_dat  _portb,4

#define ay_dat  _portb,5        ; MICROCHIP AY0438 LCD Driver DEFINITIONS
#define ay_clk  _portb,6
#define ay_ld   _portb,7

#define ay_arr_out      _porta,2        ; Direct PIC Drive of LCD backplane
#define ay_bp           _porta,3        ; and LCD Arrow segment
;
; BIT DEFINITONS OF decimal point control reg used by AYDISP1, AYDISP2
;
;          +--7--+--6--+--5--+--4--+--3--+--2--+--1--+--0--+
; AY_DP    | arr | l   | arr | arr |  l  | dp2 | dp3 | dp4 |
;          |     | slow| fast| slow|     |     |     |     |
;          +-----+-----+-----+-----+-----+-----+-----+-----+
#define ay_dp4                  AY_DP,0
#define ay_dp3                  AY_DP,1
#define ay_dp2                  AY_DP,2
#define ay_l                    AY_DP,3
#define ay_arr_flash_slow       AY_DP,4
#define ay_arr_flash_fast       AY_DP,5
#define ay_l_flash_slow         AY_DP,6
#define ay_arr                  AY_DP,7

;
; BIT DEFINITONS OF mode reg
;
;          +--7--+--6--+--5--+--4--+--3--+--2--+--1--+--0--+
; MODE     |no_d1|no_d2| 1s_ |500ms|1s   |  X  |   MODE    |
;          |     |     | flag|_flag|flag2|     |           |
;          +-----+-----+-----+-----+-----+-----+-----+-----+

#define no_d1           MODE,7    
#define no_d2           MODE,6
#define 1s_flag         MODE,5          
#define 500ms_flag      MODE,4
#define 1s_flag2        MODE,3          

;******************************************************************************
;*           R E S E T   A N D   I N T E R R U P T   V E C T O R S            *
;******************************************************************************
	ORG 0x00	        ; RESET VECTOR
	GOTO MAIN_INIT

	ORG 0x04	        ; INTERRUPT VECTOR
	GOTO INT_SERVICE

;******************************************************************************
;*      I N C L U D E    M A T H   L I B R A R Y   R O U T I N E S            *
;******************************************************************************
        include "pm_math.asm"

MAIN_INIT
;******************************************************************************
;*	          P O R T _ I N I T I A L I Z A T I O N                *
;******************************************************************************
        bcf     _gie	        ; DISABLE GLOBAL INTERRUPTS

	bsf     _rp0            ; SET PAGE 1 for _trisa, TRISB, OPTION
	movlw   b'10'	        ; PORTA RA0-1 ANALOG, RA2-3 DIG INPUTS
        movwf   _adcon1

	movlw 	b'00011'	; RA4-RA2 = OUT  RA1,RA0 = IN
	movwf   _trisa

	movlw   b'00010011'     ; RB7-5=OUT,RB4=IN,RB3-2=OUT,RB1-RB0=IN
	movwf   _trisb

	movlw   b'00000111'     ; PortB pullups = on; RTCC=int; Prescale=256
	movwf   _option         
	bcf     _rp0            ; Reset Back to Page 0

	movlw   b'10000101'	; OSC/32 CLK, CH=0, GO,NOINT,AD=ON
        movwf   _adcon0

        clrf    AY_DP           ; Initialize AY LCD stuff to defaults
        bsf     ay_clk
        bsf     ay_dat
        bcf     ay_ld
        bcf     ay_arr
        bcf     ad_clk
        bsf     ad_cs
	movlw	.32		; Clear all segments
	movwf	AY_CNT		; STORE
AYINIT	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	AYINIT
	bsf	ay_ld	        ; Done. Raise ay_ld to latch data to AY
        nop
        bcf     ay_ld

        clrf    TIC
        clrf    SEC
        clrf    MIN
        clrf    sHI 
        clrf    sLO 
        clrf    eHI 
        clrf    eMED
        clrf    eLO 
        clrf    PWR 
        clrf    MODE


        movlw   .217            ; 256-39=217 = 10ms timeout
        movwf   _rtcc           ; preload timer.
        bsf     _rtie           ; enable timer interrupts
        bsf     _gie            ; global interrupt enable

        goto    main_loop
        org     0x100
;******************************************************************************
;*                      M A I N   P R O G R A M  L O O P                      *
;******************************************************************************
main_loop
;------------------------------------------------------
;       Scan Switches
;------------------------------------------------------
        btfsc   res_sw          ; Using internal pullups 0=down
        goto    reset_sw_done
        movlw   .65             ; Wait 50ms
        call    DELAY
        btfsc   res_sw          ; Using internal pullups 0=down
        goto    reset_sw_done
        clrf    TIC
        clrf    SEC
        clrf    MIN
        clrf    eLO
        clrf    eMED
        clrf    eHI
        bcf     no_d1
        bcf     no_d2
reset_sw_done   
        
        btfsc   mode_sw         ; Using internal pullups 0=down
        goto    mode_sw_done
        movlw   .65             ; Wait 50ms
        call    DELAY
        btfsc   mode_sw         ; Using internal pullups 0=down
        goto    mode_sw_done

        movf    MODE,w          ; put mode in W reg
        addlw   .1              ; Increment to next mode (2bit cntr)
        andlw   0x03            ; mask off any carry that may have happened
;
;       Now, new MODE is in W reg
;
        rrf    MODE             ; this shifting wipes out existing 2bit
        bcf    _carry           ; counter.
        rrf    MODE
        bcf    _carry        
        rlf    MODE
        rlf    MODE            
;
;        Now restore other bits in MODE, recall new counter is in W        
;       
        iorwf   MODE            ; 'or-in' other bits in MODE reg.
        movwf  MODE

        movlw   .130            ; wait 100ms since we changed modes
        call    DELAY           ; don't want to slide through a mode
mode_sw_done   

;
;       Check for 1s if expired, Update Accumulator e
;
        btfss   1s_flag2         ; if 1s up, then do block below          
        goto    not_1s_exp 
        bcf     1s_flag2        ; background clears, isr sets.
        movf    sLO,W           ; ACCb is numerator
        movwf   ACCbLO
        movf    sHI,W
        movwf   ACCbHI 
        clrf    sLO             ; these accumulators can be reset now
        clrf    sHI
        CLRF    ACCaHI          ; ACCa is denominator
        movlw   .36
        movwf   ACCaLO
        call    D_divS          ; result in ACCb e=s/36
;
;        ;do triple precision accumulate of e, energy
;
        movf    ACCbLO,w        ; Addition ( ACCb + e -> e )
	addwf   eLO             ; add lsb
	btfsc   _carry          ; add in carry
        goto    lo_carry        ; yep, we had carry out of Lo byte
        goto    med_add         ; No carry out of lo byte
lo_carry
        incf    eMED            ; adjust for carry
        btfsc   _z
        incf    eHI
med_add
	movf    ACCbHI,w        ; Now do the MED byte
	addwf   eMED            ; add msb
        btfsc   _carry
        incf    eHI
not_1s_exp

;------------------------------------------------------
;       Dispatcher
;------------------------------------------------------
        movlw   HIGH Mode0
        movwf   _pclath

        movf    MODE,w
        andlw   0x03
        addwf   _pcl
        goto    Mode0
        goto    Mode1
        goto    Mode2
        goto    Mode3        

Mode0
;------------------------------------------------------
;       Mode0 = Instantenous Power Measurement
;------------------------------------------------------
        movlw   .13             ; wait 10ms as to not over-display
        call    DELAY

        clrf    AY_DP           ; no flashing colons or arrow

        btfss   500ms_flag      ; if 500ms up, then do block below          
        goto    mode0_done
        bcf     500ms_flag      ; background clears, isr sets.
        btfss   1s_flag
        goto    half_sec_accum
        goto    full_sec_accum

half_sec_accum
        movf    sLO,W           ; ACCb is numerator
        movwf   ACCbLO
        movf    sHI,W
        movwf   ACCbHI 
        clrf    ACCaHI          ; ACCa is denominator
        movlw   .5              ; 50 samples in 500 ms 
        movwf   ACCaLO
        call    D_divS          ; result in ACCb pwr=(s/50)*10  simple avg.
        call    B2_BCD          ; ACCd,ACCa = B2_BCD(ACCb)
        call    AYDISP2         ; display low 4bytes
        goto    mode0_done
        
full_sec_accum
        bcf     1s_flag         ; clear flag that is set by isr
        movf    sLO,W           ; ACCb is numerator
        movwf   ACCbLO
        movf    sHI,W
        movwf   ACCbHI 
        clrf    sLO             ; clear these accumulators used by isr
        clrf    sHI             ; clear these accumulators used by isr
        clrf    ACCaHI          ; ACCa is denominator
        movlw   .10             ; 100 samples in 1 s 

⌨️ 快捷键说明

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