📄 f6.asm
字号:
list st=off ; suppress list file symbol table
list n=0 ; suppress list file page breaks
;************************************************************
; Author: Zhiping Huang
; Revision: V1.0
; Date: 11-04-2002
; Assembled using MPLAB 6.00.200
; MCU using pic16f73
;************************************************************
; #define PIC16F73
#ifdef PIC16F73
list p=16f73
#include <p16F73.inc>
__CONFIG _BODEN_OFF&_CP_ON&_PWRTE_OFF&_WDT_ON&_XT_OSC
#else
list p=16f877a ; list directive to define processor
#include <p16f877a.inc> ; processor specific variable definitions
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_OFF & _XT_OSC & _WRT_OFF & _LVP_OFF & _DEBUG_ON & _CPD_OFF
#endif
errorlevel -302 ; suppress assembler warning message "Operand not in bank 0"
errorlevel -306 ; suppress assembler warning message "Crossing page boundary"
#include <F6.inc>
;------------------------------------------------------------------------
;
; Reset address. Determine type of RESET
;
org RESET_V ; Reset vector
RESET:
ifdef PIC16F73
BSF STATUS, RP0 ; Bank 1
btfss PCON,NOT_POR ; Power-up reset?(低有效)
else
nop
endif
goto Start ; YES
GOTO MCLR_RESET ; NO, a WDT or MCLR reset
page
org ISR_V ; Interrupt vector location
movwf W_TEMP ; save context before executing
swapf STATUS,W ; ISR (Interrupt Service Routine)
bsf STATUS,RP0 ; SFR bank 1
movwf STATUS_TEMP
movf FSR,W
movwf FSR_TEMP
movf PCLATH,W
movwf PCLATH_TEMP
bcf STATUS,RP0 ; SFR bank 0
bcf PCLATH,3 ; Prog page 0
; Find out which flag caused the interrupt, then branch to apropriate subroutine
; btfsc INTCON,INTF ; RB0/INT flag
; goto RB0ISR ; waveform sample available
btfss PIR1, TMR1IF ; TMR1 Overflow Interrupt occured?
goto ISR2
bsf PCLATH,3
goto T1OVFL ; YES, Service the TMR1 Interrupt
ISR2:
btfss PIR1, RCIF
goto END_ISR
bsf PCLATH,3
goto RCINT
;***************************************************************************
; Restore the values that were in the W, STATUS, PCLATH, and FSR
; registers just after the interrupt was called.
;
; These values were saved in the routine at the beginning of the
; program at "org 4 ; Interrupt vector"
END_ISR:
bsf STATUS,RP0
movf PCLATH_TEMP,W
movwf PCLATH
movf FSR_TEMP,W
movwf FSR
swapf STATUS_TEMP,W
movwf STATUS
swapf W_TEMP,F
swapf W_TEMP,W
retfie ; return from interrupt
;**********************************************************************************************************
;宏定义
I2C_WR_SUB MACRO _BYTES_, _SourcePointer_, _Sub_Address_
movlw _BYTES_
movwf BYTES
movlw _SourcePointer_
movwf SourcePointer
movlw _Sub_Address_
movwf SubAddress
call W24C02
ENDM
I2C_READ_SUB MACRO _BYTES_, _DestPointer_, _SubAddress_
movlw _BYTES_
movwf BYTES
movlw _DestPointer_
movwf DestPointer
movlw _SubAddress_
movwf SubAddress
call R24C02
ENDM
;************************************************************************
; Program start
;************************************************************************
Start:
bsf PCON,NOT_POR ; must be set in software after a Power-on Reset occurs
MCLR_RESET:
bcf STATUS,RP0 ; Bank 0
clrwdt
clrf PCLATH ; Prog page 0
bsf STATUS,RP0 ; bank 1
bcf RST7756_TRIS ; MOT re_set to output
bcf STATUS,RP0 ; bank 0
bcf RST7756
call PowerOnDelay ; all delay 180ms
bsf PCLATH,3
call InitPeriph ; initialize controller peripherals and some variables
bcf PCLATH,3
call InitValues ; get default values from the EEPROM,
; place them in variables and write to CS5460,
bsf PCLATH,3
call ConfigInt ; initialize interrupts
bcf PCLATH,3
goto MainLoop
;***************************************************************************
InitValues: ; Read EEPROM default values
movf PWRUP55,W ; get byte from RAM
sublw 0x55 ; compare with expected value
btfss STATUS,Z ; was there a match?
goto START3 ; no, was cold start.
movf PWRUPAA,W ; yes, might be a warm start.
sublw 0xAA ; if PWRUPAA <> 0xAA and PWRUP55
btfss STATUS,Z ; <> 0x55 then this was a cold start
goto START3 ; no, was cold start.
; 热复位:恢复灯
btfss Charging
goto IV3
bsf RedLed ; on
bcf CH
goto START6
IV3:
btfss disCharging
goto IV4
bsf GreenLed ; on
bcf DISCH
goto START6
IV4:
btfss BattOn
goto START6
bsf RedLed ;有电池亮桔灯
bsf GreenLed
goto START6
START3:
bsf PCLATH,3
call ClearRAM
bcf PCLATH,3
clrwdt
movlw 0xAA ; Write 0xAA to PWRUPAA
movwf PWRUPAA
movlw 0x55 ; Write 0x55 to PWRUP55
movwf PWRUP55
START6:
; 预设参数上电读出
I2C_READ_SUB 0x03, BFIIC, AT_Current
movlw BFIIC
movwf I
movlw Current_LOW
movwf J
movlw D'3'
movwf tempCount
call S0_S1
; -------------------------------------------------------------
I2C_READ_SUB 0x03, BFIIC, AT_ConstantV
movlw BFIIC
movwf I
movlw ConstantV_LOW
movwf J
movlw D'3'
movwf tempCount
call S0_S1
; -------------------------------------------------------------
I2C_READ_SUB 0x03, BFIIC, AT_ChargeTermI
movlw BFIIC
movwf I
movlw ChargeTermI_LOW
movwf J
movlw D'3'
movwf tempCount
call S0_S1
; -------------------------------------------------------------
I2C_READ_SUB 0x02, BFIIC, AT_TerminalT
movlw BFIIC
movwf I
movlw TerminalT_LOW
movwf J
movlw D'2'
movwf tempCount
call S0_S1
; -------------------------------------------------------------
I2C_READ_SUB 0x03, BFIIC, AT_DisCHTermV
movlw BFIIC
movwf I
movlw DisCHTermV_LOW
movwf J
movlw D'3'
movwf tempCount
call S0_S1
I2C_READ_SUB 0x01, BFIIC, AT_HandleTime
movf BFIIC,W
bsf STATUS,RP0
movwf StandBy
bcf STATUS,RP0
IV_OUT:
CALL KWH ; recall calibration values from eeprom and write to ADE7756 registers
return
;**********************************************************************************************************
;
; Main program
;
;**********************************************************************************************************
MainLoop:
;;;
bsf PCLATH,3 ; Prog page 1
call FXM3216S
bcf PCLATH,3 ; Prog page 0
;;;
clrwdt
;保证总中断开放
ifdef PIC16F73
bsf INTCON,GIE ; 保证总中断开放
endif
;再次定义重要端口
bsf STATUS,RP0 ; bank 1
bsf BUTTON_TRIS ; MOT re_set to output
bcf STATUS,RP0 ; bank 0
bsf BUTTON
btfss CMD_DisCharge
goto ML2
bsf PCLATH,3 ; Prog page 1
call P_DisChar
bcf PCLATH,3 ; Prog page 0
ML2:
btfss CMD_Charge
goto ML0
bsf PCLATH,3 ; Prog page 1
call P_Charge
bcf PCLATH,3 ; Prog page 0
ML0:
btfss TimerArrived
goto ML4
bsf PCLATH,3 ; Prog page 1
call P_TIMER
bcf PCLATH,3 ; Prog page 0
ML4:
btfsc SEC1
call P_SEC
btfsc MIN1
call P_MIN
; 主程序中不能读SPI,CMD子程序中在没电池的情况下可以读SPI,回送巡采命令的数据时,
; 是从内存中取;万一要读,可先关闭定时器中断。
btfsc aFRAME
call CMD ; 帧处理
call DETECT
BTFSS RCSTA,OERR
goto MainLoop
BCF RCSTA,CREN
BCF RCSTA,OERR ;清错误标志
BSF RCSTA,CREN
goto MainLoop
;----------------------------------------------------------------------------------------------
DETECT:
btfss BattOn
goto DE2
movf WorkFlag,W
btfss _Z
return
bsf PCLATH,3 ; Prog page 1
call ClosePWM ; 没有流程,暂关PWM
bcf PCLATH,3 ; Prog page 0
return
DE2:
btfsc DetectBatt
return
bsf DetectBatt
bsf T1CON,TMR1ON
bcf CH
movlw CCPR1L_INIT ; 8 bits of DC
movwf CCPR1L ; Duty Cycle is 50% of PWM Period
movlw CCP1CON_INIT ; PWM mode, 2 LSbs of Duty cycle = 00
movwf CCP1CON ; Duty Cycle is 00% of PWM Period
BCF PIR1, TMR2IF ; Clear the TRM2 = PR2 flag
movlw T2CON_INIT
movwf T2CON ; 1:1 prescale, 1:1 postscale
bsf T2CON,TMR2ON ; TMR2 on
return
;----------------------------------------------------------------------------------------------
PowerOnDelay:
; 5.0688MHz crystal,延时200ms
movlw D'233'
goto DL0
DELAY10ms:
; 5.0688MHz crystal,延时10ms,周期数 T=D'17' tc=13108,delay=10.34ms
movlw D'17'
DL0:
movwf J
movlw 0xFF
movwf I
DL1:
decfsz I,F ;1/2tc
goto DL1
clrwdt
decfsz J,F
goto DL1
nop
return
;----------------------------------------------------------
; 秒处理
P_SEC:
btfsc disCharging
goto PD0
btfss Charging
goto PS3
PD0:
movlw D'15' ; 30秒
subwf SecsPassed,W
btfss _C
incf SecsPassed,F
PS3:
bsf STATUS,RP0 ; select page 1
bcf PIE1,TMR1IE ; disable Timer1中断
bcf STATUS,RP0 ; select page 1
bsf PCLATH,3 ; Prog page 1
call Average ; host 1.28ms
bcf PCLATH,3 ; Prog page 0
;计算完后清除旧数据
clrf VI_CSamp
movlw Iaddend1
movwf FSR
movlw D'8'
movwf J
PS3A:
bsf STATUS,RP0
clrf INDF
bcf STATUS,RP0
incf FSR,F
decfsz J,F
goto PS3A
bsf STATUS,RP0 ; select page 1
bsf PIE1,TMR1IE ; 允许Timer1中断
bcf STATUS,RP0 ; select page 1
incf C_MIN,F
movlw D'60'
subwf C_MIN,W
btfss STATUS,C
goto PS3B
bsf MIN1 ;>=60,1 min
clrf C_MIN
PS3B:
btfsc BattOn
goto PS4
bcf RedLed
bcf GreenLed
goto PM9
;是静置?...
; btfsc Standing
; goto PS4
; movf WorkFlag,W
; btfss _Z
; goto PM9
PS4:
bsf STATUS,RP0
movf I_Waveform3,W
bcf STATUS,RP0
btfss _Z
goto PM9
movlw high I_Code
bsf STATUS,RP0
; movf ChargeTermI_MID,W
subwf I_Waveform2,W
bcf STATUS,RP0
btfsc _C
goto PM9
;<high I_Code
bsf STATUS,RP0
movf V_Waveform3,W
bcf STATUS,RP0
btfss _Z
goto PM9
; movlw high I_Code
movlw high V_Code
bsf STATUS,RP0
; movf ChargeTermI_MID,W
subwf V_Waveform2,W
bcf STATUS,RP0
btfsc _C
goto PM9
;电流电压双低:电池已被拿走
bcf BattOn
clrf LoadOn
;换电池后必须发新的流程
clrf WorkFlag
clrf LoadOn
bsf PCLATH,3 ; Prog page 1
call ClosePWM ; 没有流程,暂关PWM
bcf PCLATH,3 ; Prog page 0
bsf CH ; close 充电控制
bcf RedLed
bsf DISCH ;close 放电控制
bcf GreenLed
;清除三点电压
movlw V_Start_LOW
movwf FSR
movlw D'9'
movwf J
PM8:
bsf STATUS,RP0
clrf INDF
bcf STATUS,RP0
incf FSR,F
decfsz J,F
goto PM8
PM9:
bsf Pass_1s
bcf SEC1
return
;---------------------------------------------------------
P_MIN:
btfsc Standing ;是静置?...
goto PM3
btfsc disCharging
goto PM2
btfss Charging
goto PM_OUT
PM2:
movlw D'1'
addwf C_TermT_LOW,F
btfss _C
goto PM2A
movlw D'1'
addwf C_TermT_HI,F
PM2A:
movf C_TermT_HI,W
bsf _BANK1
xorwf TerminalT_HI,W
bcf _BANK1
btfss _Z
goto PM_OUT
movf C_TermT_LOW,W
bsf _BANK1
subwf TerminalT_LOW,W
bcf _BANK1
btfsc _C
goto PM_OUT
clrf C_TermT_LOW
clrf C_TermT_HI
bsf OverTermTime
clrf WorkFlag
clrf LoadOn
;超时,强制关闭
bsf PCLATH,3 ; Prog page 1
call ClosePWM
bcf PCLATH,3 ; Prog page 0
bsf CH
bsf DISCH
bsf RedLed ;有电池亮桔灯
bsf GreenLed
goto PM_OUT
PM3:
incf Minutes,F
bsf STATUS,RP0
movf StandBy,W
bcf STATUS,RP0 ; select page 1
subwf Minutes,W
btfss _C ;到静置时间?
goto PM_OUT
;yes
bcf Standing
clrf Minutes
bsf RedLed ;有电池亮桔灯
bsf GreenLed
PM_OUT:
bcf MIN1
return
; ---------------------------------------------------------------------------------------------
; 读取波形寄存器值
ReadWafeForm:
clrwdt
call ReadDelay
movlw B'00000001' ; 波形寄存器地址
movwf spi ; output to spi read active energy and reset
movlw b'00000100' ; number of bytes to download B'000(5)(4)(3)(2)(1)'
movwf wordlen ; wordlen is 24 bits. reg is actually 24 bits
CALL SPIRX ; CALL SPI read 24 bit word data will be in
; insd1,2,3. 3 being msb 1 being lsb
return
ReadDelay:
; 5.0688MHz crystal,延时71us,周期数 T=D'3' tc=2320,delay=1.83ms
movlw D'30'
movwf J
RD1:
decfsz J,F
goto RD1
return
; ---------------------------------------------------------------------------------------------
; 数据传递子程序,入口时S = 0,出口时S = 0
; Input: I ->S0 source
; J ->S1 destination
; tempCount:bytes
; Use: TEMP,FSR,W,I,J
S0_S1:
movf I,W
movwf FSR
movf INDF,W
movwf TEMP
movf J,W
movwf FSR
movf TEMP,W
bsf STATUS,RP0
movwf INDF
bcf STATUS,RP0
incf I,F
incf J,F
decfsz tempCount,F
goto S0_S1
return
; ---------------------------------------------------------------------------------------------
; 数据传递子程序,入口时S = 0,出口时S = 0
; Input: I ->S1 source
; J ->S0 destination
; tempCount:bytes
; Use: TEMP,FSR,W,I,J
S1_S0:
movf I,W
movwf FSR
bsf STATUS,RP0
movf INDF,W
bcf STATUS,RP0
movwf TEMP
movf J,W
movwf FSR
movf TEMP,W
movwf INDF
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -