微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 电源设计 > 电表在不同供电模式下的安全过渡

电表在不同供电模式下的安全过渡

时间:05-14 来源:互联网 点击:

; Switch to M6520 when chip is available.

; Standard SFR Symbols
ACC DATA 0E0H
B DATA 0F0H
SP DATA 81H
DPL DATA 82H
DPH DATA 83H
USER1 DATA 90H
DIR1 DATA 91H
FCTRL DATA 0B2H
IPH DATA 0B9H
IPL DATA 0A9H
IRCON DATA 0C0H
IEN0 DATA 0A8H
IEN1 DATA 0B8H

NAME ?C_STARTUP

?C_C51STARTUP SEGMENT CODE
?STACK SEGMENT IDATA

RSEG ?STACK
DS 1

EXTRN CODE (?C_START)
PUBLIC ?C_STARTUP
PUBLIC _?TRIM_TEST

CSEG AT 0
?C_STARTUP: LJMP STARTUP1
RSEG ?C_C51STARTUP
STARTUP1:
CLR IEN0^7 ; Disable interrupts
; To enable secure mode, remove the semicolon of the next line
; ORL FCTRL,#40H ; set secure bit
MOV 0E8h,#0FFh ; Refresh nonmaskable watchdog.

; Set system interrupt priorities; more frequent are higher priority.
MOV IPH,#01DH ; From code in options_gbl.h, main.c
MOV IPL,#00AH ; From code in options_gbl.h
; Clear PLL_OK interrupt (bit3), and others
MOV IRCON,#0
; Enable PLL_OK interrupt
MOV DPTR,#2007H ; Set EX_PLL
MOV A,#20H
MOVX @DPTR,A
; Enable interrupts
MOV IEN1,#08H ; Enable INT4, the PLL_OK interrupt
MOV IEN0,#80H ; Enable all interrupts

ACALL _?TRIM_TEST ; Test 6521's trims

IF IDATALEN > 0
MOV R0,#IDATALEN - 1
CLR A
IDATALOOP: MOV @R0,A
DJNZ R0,IDATALOOP
ENDIF

IF XDATALEN > 0
MOV DPTR,#XDATASTART
MOV R7,#LOW (XDATALEN)
IF (LOW (XDATALEN)) > 0
MOV R6,#(HIGH (XDATALEN)) +1
ELSE
MOV R6,#HIGH (XDATALEN)
ENDIF
CLR A
XDATALOOP: MOVX @DPTR,A
INC DPTR
DJNZ R7,XDATALOOP
DJNZ R6,XDATALOOP
ENDIF

IF PPAGEENABLE > 0
MOV PPAGE_SFR,#PPAGE
ENDIF

IF PDATALEN > 0
MOV R0,#LOW (PDATASTART)
MOV R7,#LOW (PDATALEN)
CLR A
PDATALOOP: MOVX @R0,A
INC R0
DJNZ R7,PDATALOOP
ENDIF

IF IBPSTACK > 0
EXTRN DATA (?C_IBP)
MOV ?C_IBP,#LOW IBPSTACKTOP
ENDIF

IF XBPSTACK > 0
EXTRN DATA (?C_XBP)
MOV ?C_XBP,#HIGH XBPSTACKTOP
MOV ?C_XBP+1,#LOW XBPSTACKTOP
ENDIF

IF PBPSTACK > 0
EXTRN DATA (?C_PBP)
MOV ?C_PBP,#LOW PBPSTACKTOP
ENDIF

MOV SP,#?STACK-1
LJMP ?C_START

; Read a trim whose index is in A. Return the trim in A.
CSEG AT 100H
FUSE_TABLE:
DB 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff

; Trim test. Prefix _? tells Keil C it's reentrant.
_?TRIM_TEST:
PUSH IEN0
PUSH PSW ; Save registers, so it's reentrant.
MOV PSW,00H ; Select registers before saving them
PUSH DPL
PUSH DPH
PUSH ACC
MOV A,R7 ; Save R7 from the current register set.
PUSH ACC
MOV A,R6 ; Save R6 from the current register set.
PUSH ACC

CLR IEN0.7

; Wait for all fuses to be read once before checking fuses
; Complete fuse read takes 45 xtal clock cycles (1 fuse per xtal clock)
MOV R7,#21 ; Wait 21x4 = 48 cycles
loop_inner: DJNZ R7,loop_inner ; 4 cycles (in brownout, 1 cycle/clk)

mov DPH, #HIGH(FUSE_TABLE)

fuse_test_frst: ; check if values previously stored
mov DPL,#LOW(FUSE_TABLE)
clr a
movc a,@a+dptr ; read fuse table
xrl a,#55H
jnz fuse_save

MOV DPTR,#2003H ; Check if in brownout mode
MOVX A,@DPTR
JB ACC.6,PASS ; Mission mode, so don't check.
fuse_test:
mov r7,#8 ; byte counter
fuse_test_lp1:
mov DPTR,#FUSE_TABLE ; load pointer to fuse table
mov a,r7
movc a,@a+dptr ; read fuse table
mov r6,a

mov a,r7

MOV DPTR,#20FDH ; TRIMSEL address
MOVX @DPTR,A ; load reg to read trim
MOV DPL,#0FFH ; TRIM value address

MOVX A,@DPTR ; Get trim value

cjne a,06H,FAIL ; test if flash read and trim ==
djnz r7,fuse_test_lp1

JMP PASS
fuse_save:
MOV DPTR,#2003H ; Check if in brownout mode
MOVX A,@DPTR
; If brownout mode, don't save them and enter sleep.
JNB ACC.6,FAIL

; mov 84H,#LOW(FUSE_TABLE)
mov r7,#8 ; byte counter
fuse_save_lp1:
mov a,r7

MOV DPTR,#20FDH ; TRIMSEL address
MOVX @DPTR,A ; load reg to read trim
MOV DPL,#0FFH ; TRIM value address

MOVX A,@DPTR ; Get trim value
mov r6,a

mov a,r7
mov dptr,#FUSE_TABLE
add a,DPL
mov DPL,a
mov a,r6

orl 0B2H,#01H ; set to flash write
movx @dptr,a ; write fuse table byte
djnz r7,fuse_save_lp1

mov a,#55H ; contr

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top