;;;这是STC15W系列的 汇编语言编写的 停电保存数据,上电恢复数据 部分的程序
;;;在 STC12C系列 上有使用过,
;;; STC8F2K08S2 可以对比一下几个相关寄存器地址是否一致,一致可以直接使用
;;;用C语言的没有
; / *** *** *** *** *** *** / CPU STC15W404AS
; / *** *** *** *** *** *** / 12.000MHz
WDT_CONTR EQU 0C1H ; 看门狗
ISP_DATA EQU 0C2H ; EEPROM 数据寄存器
ISP_ADDRH EQU 0C3H ; 地址寄存器H
ISP_ADDRL EQU 0C4H ; 地址寄存器L
ISP_CMD EQU 0C5H ; 命令寄存器
ISP_TRIG EQU 0C6H ; 触发寄存器
ISP_CONTR EQU 0C7H ; ( 等待时间 < 6M 4 )
ISPRH EQU 78H ; ( 等待时间 < 12M 3 )
ISPRL EQU 79H ; ( 等待时间 < 20M 2 )
ISPWH EQU 7AH ; ( 等待时间 < 12M 3 )
ISPWL EQU 7BH ; ( 等待时间 < 20M 2 )
; / *** *** *** *** *** *** / 通用数据存储器 RAM 256 字节
; / *** *** *** *** *** *** / 定义内部RAM L EEPROM 5K
RIV_R0 EQU 1CH
RIV_R1 EQU 1DH
PTJSA0 EQU 50H ; 停电保存数据
PTJSA1 EQU 51H ; 可以根据需要字节
; -------------------------------
; / *** *** *** *** *** *** /
; ISP - 78H 79H 7AH 7BH
PJSQS0 EQU 7EH
PJSQS1 EQU 7FH
; / *** *** *** *** *** *** / 通用 标志位
; / *** *** *** *** *** *** / 20H --- 2FH
PLVD_BZ BIT 26H ; 停电处理标志
PLVD_B2 BIT 27H
; / *** *** *** *** *** *** / 程序入口
; / *** *** *** *** *** *** /
ORG 0000H
L0000: LJMP MIN000 ; 初始化 主程序 START
ORG 0033H
L0033: LJMP LVD000 ; LVD 低电压 ( LVDF )
; RETI
; / *** *** *** *** *** *** / ELVDI (低电压) 中断
; / *** *** *** *** *** *** /
; 5V-3.7V 5.50V - 3.30V 4.06V - 1.32V
LVD000: PUSH PSW ; 电流检测
PUSH ACC
SETB RS0 ; 1 区 R1 R3
CLR RS1
ANL PCON, #11011111B ; 清 LVDF 位
MOV A, PCON
JNB ACC.5, LVD008 ; LVDF
CLR EA
CLR TR1
SETB PLVD_BZ
JNB PLVD_B2, LVD008
CLR PLVD_B2
LVD003: MOV A, PJSQS0 ; 数据
MOV B, #08H
MUL AB
MOV ISPWL, A ; 0000H - 01FFH
MOV ISPWH, B
MOV R1, #PTJSA0 ; 断电保存数据写入
MOV R3, #08H
LVD006: MOV A, @R1
LCALL ISP010 ; 字节写
INC ISPWL
INC R1
DJNZ R3, LVD006
INC PJSQS0
LVD007: ANL PCON, #11011111B ; 清 LVDF 位
MOV A, PCON
JB ACC.5, LVD007
LVD008: CLR PLVD_BZ
SETB EA
POP ACC
POP PSW
RETI
; / *** *** *** *** *** *** / 初始化 主程序A
; / *** *** *** *** *** *** /
MIN000: MOV SP, #0B0H ; 初始化 主程序 SP = B0H - FFH
MOV IE, #11000000B ; IE.6 ( EPCA_LVD 中断 )
MIN002: LCALL MIM000 ; 初始化
MIN010: NOP ; 主程序
NOP
MOV WDT_CONTR, #3EH ; 看门狗 初始化 12M ( 1.0485 S )
NOP ; 喂狗 同
NOP
; 主控程序在这里加入
MIN050: JMP MIN010
RET
; / *** *** *** *** *** *** / 读写 STC15W404AS EEPROM
; / *** *** *** *** *** *** / 1 字节读
ISP000: MOV ISP_CONTR, #83H ; 打开 IAP 功能 设置等待时间
MOV ISP_CMD, #01H ; 送字节读命令
MOV ISP_ADDRH, ISPRH ; 送地址高字节
MOV ISP_ADDRL, ISPRL ; 送地址低字节
CLR EA ; 关中断
MOV ISP_TRIG, #5AH ; 起动 ISP/IAP 触发寄存器
MOV ISP_TRIG, #0A5H
NOP
MOV A, ISP_DATA ; 将读出的数据送往Acc
JB PLVD_BZ, $+5
SETB EA
LCALL ISP030 ; 关闭 IAP 功能
RET
; / *** *** *** *** *** *** / 1 字节编程
ISP010: MOV ISP_CONTR, #83H ; 打开 IAP 功能 设置等待时间
MOV ISP_CMD, #02H ; 送字节编程命令
MOV ISP_ADDRH, ISPWH ; 送地址高字节
MOV ISP_ADDRL, ISPWL ; 送地址低字节
MOV ISP_DATA, A ; 数据进ISP_DATA
CLR EA ; 关中断
MOV ISP_TRIG, #5AH ; 起动 ISP/IAP 触发寄存器
MOV ISP_TRIG, #0A5H
NOP
JB PLVD_BZ, $+5
SETB EA
LCALL ISP030 ; 关闭 IAP 功能
RET
; / *** *** *** *** *** *** / 擦除扇区
ISP020: MOV ISP_CONTR, #83H ; 打开 IAP 功能 设置等待时间
MOV ISP_CMD, #03H ; 送擦除扇区命令
MOV ISP_ADDRH, ISPWH ; 送地址高字节
MOV ISP_ADDRL, ISPWL ; 送地址低字节
CLR EA ; 关中断
MOV ISP_TRIG, #5AH ; 起动 ISP/IAP 触发寄存器
MOV ISP_TRIG, #0A5H
NOP
JB PLVD_BZ, $+5
SETB EA
LCALL ISP030 ; 关闭 IAP 功能
RET
; / *** *** *** *** *** *** / 关闭 IAP 功能
ISP030: MOV ISP_CONTR, #00H
MOV ISP_CMD, #00H
MOV ISP_TRIG, #00H
MOV ISP_ADDRH, #0FFH ; 指向非EEPROM区
MOV ISP_ADDRL, #0FFH
RET
RET
; / *** *** *** *** *** *** / 初始化 STC15W404AS
; / *** *** *** *** *** *** / 读回DAT ***
MIM000: MOV R4, #20 ; 50000 uS * 20
MIM001: NOP
NOP
MOV WDT_CONTR, #3CH ; 看门狗 初始化 12M ( 1.0485 S )
NOP
NOP ; 喂狗 同
DJNZ R4, MIM001
CLR PLVD_BZ ;
CLR PLVD_B2
MOV RIV_R1, #50 ; 30 S
LCALL MIM050 ; 机器编号
NOP
MIM010: MOV PJSQS0, #40H ; 读回 编码
MIM013: DEC PJSQS0 ; 0000H - 01FFH
MOV A, PJSQS0
CJNE A, #0FFH, MIM015
RET
MIM015: MOV B, #08H ; 计算地址
MUL AB
MOV ISPRL, A ; 0000H - 01FFH
MOV ISPRH, B
LCALL ISP000 ; 字节读
CJNE A, #0FFH, MIM016
JMP MIM013
MIM016: MOV R0, #PTJSA0
MOV R3, #08H
MIM018: LCALL ISP000 ; 字节读
MOV @R0, A ; 写 RAM
INC ISPRL
INC R0
DJNZ R3, MIM018
INC PJSQS0
MIM050: RET
; / *** *** *** *** *** *** / 结束
END |