📄 eeprom.asm
字号:
;
BZ $EP_BCHG_8
MOVW AX,d2GetAdr
MOVW d2ReadGet,AX ;设定数据获取地址
MOVW AX,#b8DataBuf
MOVW d2ReadSet,AX ;设定数据存储地址
MOV cj,#0
EP_BCHG_4:
MOV A,cj
CMP A,#LENG ;从0到数据长度的循环
BNC $EP_BCHG_5
MOVW AX,d2ReadGet
MOVW DE,AX
INCW AX
MOVW d2ReadGet,AX
MOV A,[DE]
MOV C,A
MOVW AX,d2ReadSet
MOVW DE,AX
INCW AX
MOVW d2ReadSet,AX
MOV A,C
MOV [DE],A ;将数据从获取地址传送到存储地址。
;
INC cj ;循环计数器+1
BR EP_BCHG_4
EP_BCHG_5:
MOVW DE,#b8DataBuf
MOV C,#LENG
MOVW AX,d2SetAdr
CALL !Flash_EEPROMWrite ;将存储的数据写入EEPROM
BNZ $EP_BCHG_FL ;异常完成
EP_BCHG_7:
MOVW AX,d2SetAdr
ADDW AX,#LENG
MOVW d2SetAdr,AX ;为了寻找下一个数据,把寻找地址和数据长度相加
EP_BCHG_8:
INC ci ;循环计数器+1
BR EP_BCHG_T
EP_BCHG_9:
MOV A,#00H
MOV b8DataBuf,A ;为block有效/无效设定准备数据
MOV A,dNextBlockTBLNo
CALL !BlockAddressGet
MOVW DE,#b8DataBuf
MOV C,#1
CALL !Flash_EEPROMWrite
BNZ $EP_BCHG_FL ;异常终止
EP_BCHG_11:
MOV A,L
CALL !BlockAddressGet
ADDW AX,#1
MOVW DE,#b8DataBuf
MOV C,#1
CALL !Flash_EEPROMWrite
BZ $EP_BCHG_TR ;正常完成
EP_BCHG_FL:
MOV C,#FALSE ;返回值 = 异常终止
BR EP_BCHG_E
EP_BCHG_TR:
MOV A,dNextBlockTBLNo
MOV B,#00H
XCH A,C ;返回值 = 下一个block编号
EP_BCHG_E:
POP HL
RET
;-------------------------------------------------------------------
; 函数名称: _EEPROMWriteTopSearch
; 输入: X = 寻找block表编号
; (使用用户自行定义的为EEPROM设定的block编号)
; 输出: BC = 写入地址(0000H到FFFFH)
; 摘要: 寻找指定block的写入地址。
;-------------------------------------------------------------------
_EEPROMWriteTopSearch:
PUSH HL
MOVW HL,AX
MOV A,L
CALL !BlockAddressGet ;从EEPROM block起始结束地址表,
ADDW AX,#DATATOP
MOVW d2SrcAdr,AX ;设定block起始地址
MOV A,L
INC A
CALL !BlockAddressGet ; 从EEPROM block起始结束地址表,
MOVW d2EndAdr,AX ;设定block结束地址
EP_WTSR_T:
MOVW AX,d2SrcAdr
MOVW DE,AX
MOV A,[DE]
CMP A,#0FFH ;是否为数据编号寻找结束代码(FFH)?
BZ $EP_WTSR_2
MOVW AX,d2SrcAdr
ADDW AX,#LENG
MOVW d2SrcAdr,AX ;通过高级寻找指针LENG字节进行下一数据寻找
;
CMP A,d2EndAdr+1
BNZ $EP_WTSR_1
XCH A,X
CMP A,d2EndAdr
EP_WTSR_1:
BC $EP_WTSR_T ;判断寻找指针是否在寻找block范围内
;
MOVW AX,d2EndAdr
MOVW BC,AX ;如果寻找指针超出了block范围,将寻找地址设为block结束
;
BR EP_WTSR_E
EP_WTSR_2:
MOVW AX,d2SrcAdr
MOVW BC,AX ;返回值 = 寻找指针的地址
EP_WTSR_E:
POP HL
RET
;-------------------------------------------------------------------
; 函数名称: EEPROMDataSearch
; 输入: X = 读取数据编号
; E = 当前使用的block表编号
; (使用用户自行定义的为EEPROM设定的block编号)
; 输出: BC = 最新数据的地址 (0001H到FFFFH),异常终止(0000H)
; 摘要: 在指定的编号读取最新数据的存储地址。
;-------------------------------------------------------------------
EEPROMDataSearch:
PUSH HL
MOV A,X
XCH A,X
MOV A,E
MOVW HL,AX
CALL !BlockAddressGet ;从EEPROM block开始结束地址表,
ADDW AX,#DATATOP ;设定block开始地址
MOVW d2SrcAdr,AX
MOVW AX,#0000H
MOVW d2DataAdr,AX ;初始化寻找结果存储地址
MOV A,H
INC A
CALL !BlockAddressGet ;从EEPROM block开始结束地址表,
MOVW d2EndAdr,AX ;设定block结束地址
EP_DASR_T:
MOVW AX,d2SrcAdr
MOVW DE,AX
MOV A,[DE]
MOV b8DataBuf,A ;重新得到寻找地址数据
CMP A,L
BNZ $EP_DASR_1 ;与数据编号相比教
MOVW AX,d2SrcAdr
ADDW AX,#LENG-1
MOVW DE,AX
MOV A,[DE]
MOV b8DataBuf+3,A ;重新得到定界符
CMP A,#00H
BNZ $EP_DASR_2 ;如果定界符为00H,寻找目标数据
MOVW AX,d2SrcAdr
MOVW d2DataAdr,AX ;在寻找结果存储地址中存储寻找地址
;
BR EP_DASR_2
EP_DASR_1:
MOV A,b8DataBuf
CMP A,#0FFH ;判断数据结束(FFH)
BZ $EP_DASR_E
EP_DASR_2:
MOVW AX,d2SrcAdr
ADDW AX,#LENG
MOVW d2SrcAdr,AX ;为下一个数据的高级寻找地址(+LENG字节)
CMP A,d2EndAdr+1
BNZ $EP_DASR_3
XCH A,X
CMP A,d2EndAdr ;判断寻找指针是否位于寻找block范围内
;
EP_DASR_3:
BC $EP_DASR_T
EP_DASR_E:
MOVW AX,d2DataAdr ;返回值 = 存储地址的寻找结果(如果为0000H,异常终止)
;
MOVW BC,AX
POP HL
RET
;-------------------------------------------------------------------
; 函数名称: SelfFlashBlockErase
; 输入: A = 擦除block编号
; 输出: C = 正常完成(正确:00H)或是异常完成(错误:FFH)
; 摘要: 擦除指定的block并且执行blank检测。
; 备注: 下述的blank检测将被执行两次。
; 每一次的目的是不同的。
; 第一次blank用于检测是否存在未被使用的空间。
; 第二次blank检测确定未使用的空间是否已经通过擦除block创建。
;-------------------------------------------------------------------
SelfFlashBlockErase:
PUSH HL
XCH A,X
PUSH AX
MOVW AX,SP
MOVW HL,AX
MOV B,#ERASE_RETRY ;为擦除设定重新计数
MOV A,[HL] ;设定空白检测模块
CALL !FlashBlockBlankCheck ;空白检测处理
BZ $SF_BKER_TR ;如果空白检测发生错误,执行擦除处理
SF_BKER_RE:
MOV A,[HL] ;设定擦除block
CALL !FlashBlockErase ;擦除处理
BNZ $SF_BKER_01 ;异常终止
MOV A,[HL] ;设定空白检测block
CALL !FlashBlockBlankCheck ;空白检测处理
BZ $SF_BKER_TR ;空白检测正常完成
SF_BKER_01:
DBNZ B,$SF_BKER_RE ;检测重新计数
SF_BKER_FL:
MOV A,#FALSE ;返回值 = 异常终止
BR SF_BKER_E
SF_BKER_TR:
MOV A,#TRUE ;返回值 = 正常完成
SF_BKER_E:
MOV C,A
POP AX
POP HL
RET
;-------------------------------------------------------------------
; 函数名称: SelfFlashModeOff
; 输入: 无
; 输出: 无
; 摘要: 释放自编程模式的处理
;-------------------------------------------------------------------
SelfFlashModeOff:
MOV PFS,#NO_ERR
MOV PFCMD,#0A5H ;PFCMD寄存器控制
MOV FLPMC,#00H ;FLPMC寄存器控制(设定值)
MOV FLPMC,#0FFH ;FLPMC寄存器控制(反向设定值)
MOV FLPMC,#00H ;设定正常模式: FLPMC寄存器控制(设定值)
;
MOV A,PFS
CMP A,#NO_ERR
BNZ $SelfFlashModeOff ;检测到特殊寄存器写入的完成
EI
MOVW AX,d2MaskStatus
; MOV MK1,A ;当使用78K0S/KY1+删除这一行
XCH A,X
MOV MK0,A ;恢复中断屏蔽标志
RET
;-------------------------------------------------------------------
; 函数名称: SelfFlashModeOn
; 输入: 无
; 输出: 无
; 摘要: 设定自编程模式的处理
;-------------------------------------------------------------------
SelfFlashModeOn:
MOV A,MK0
XCH A,X
; MOV A,MK1 ;当使用78K0S/KY1+删除这一行
MOVW d2MaskStatus,AX ;保存中断屏蔽标志
MOV MK0,#11111111B
; MOV MK1,#11111110B ;屏蔽除去INTFLC的中断
;当使用78K0S/KY1+删除这一行
DI
SF_MDON_LP:
MOV PFS,#NO_ERR
MOV PFCMD,#0A5H ;PFCMD寄存器控制
MOV FLPMC,#01H ;FLPMC寄存器控制(设定值)
MOV FLPMC,#0FEH ;FLPMC寄存器控制(反向设定值)
MOV FLPMC,#01H ;设定自编程模式: FLPMC寄存器控制(设定值)
;
MOV A,PFS
CMP A,#NO_ERR
BNZ $SF_MDON_LP ;检测到特殊寄存器写入操作的完成
RET
;-------------------------------------------------------------------
; 函数名称: FlashBlockErase
; 输入: A = Block编号
; 输出: Z (零标志位) = 正常完成(1)或者异常完成(0)
; 摘要: 擦除指定的block。
;-------------------------------------------------------------------
FlashBlockErase:
MOV FLCMD,#CMD_BLOCK_ERASE ;设置flash控制命令(block擦除)
MOV FLAPH,A ;设置空白检测block号
MOV FLAPL,#00H
MOV FLAPHC,A
MOV FLAPLC,#00H
CALL !SubFlashSelfPrg
RET
;-------------------------------------------------------------------
; 函数名称: FlashBlockBlankCheck
; 输入: A = Block编号
; 输出: Z(零标志) = 正常完成(1)或异常完成(0)
; 摘要: 执行指定blank的检测。
;-------------------------------------------------------------------
FlashBlockBlankCheck:
MOV FLCMD,#CMD_BLANK_CHECK ;设定flash控制命令(block空白检测)
MOV FLAPH,A ;设定空白检测block编号
MOV FLAPL,#00H
MOV FLAPHC,A
MOV FLAPLC,#0FFH
CALL !SubFlashSelfPrg
RET
;-------------------------------------------------------------------
; 函数名称: Flash_EEPROMWrite
; 输入: DE = 写入开始地址
; C =需要写入的数据blocks编号
; AX = 写入数据存储地址
; 输出: Z(0标志) = 正常完成(1)或异常完成(0)
; 摘要: 执行对EEPROM的写入和内部确认。
;-------------------------------------------------------------------
Flash_EEPROMWrite:
PUSH HL
PUSH AX
PUSH BC
MOVW HL,AX
MOV FLCMD,#CMD_BYTE_WRITE ;设置flash控制命令(字节写入)
FL_WR_W1:
MOV B,#WRITE_RETRY
MOVW AX,HL
MOV FLAPH,A
XCH A,X
MOV FLAPL,A ;设置写入/校验地址
MOV A,[DE]
MOV FLW,A ;设置写入数据
FL_WR_W2:
CALL !SubFlashSelfPrg
BZ $FL_WR_W3
DBNZ B,$FL_WR_W2 ;重新计数判断(共10次)
POP BC
POP HL
BR FL_WR_E
FL_WR_W3:
INCW DE ;读取地址+1
INCW HL ;写入地址+1
DBNZ C,$FL_WR_W1
POP BC
POP HL
MOV FLCMD,#CMD_INTERNAL_VERIFY ;设置闪存控制命令(内部校验)
MOVW AX,HL
MOV FLAPH,A
XCH A,X
MOV FLAPL,A ;设定校验起始地址
DEC C
ADD A,C
XCH A,X
ADDC A,#0
MOV FLAPHC,A
XCH A,X
MOV FLAPLC,A ;设定校验结束地址
CALL !SubFlashSelfPrg
FL_WR_E:
POP HL
RET
;--------------------------------------------------------------------
; 函数名称: BlockAddressGet
; 输入: A: Block编号
; 输出: AX: Block起始地址
; 处理: Block地址表参考处理
;--------------------------------------------------------------------
BlockAddressGet:
CLR1 CY
MOV X,#0
ROLC A,1
XCH A,X
ROLC A,1
ADDW AX,#tEEPROM_BLK_ADR ;从EEPROM block开始/结束地址表
MOVW DE,AX
MOV A,[DE]
XCH A,X
INCW DE
MOV A,[DE]
RET
;--------------------------------------------------------------------
; 函数名称: SubFlashSelfPrg
; 输入: 无
; 输出: Z(零标志) = 正常完成(1)或是异常终止(0)
; 处理: 调用flash存储器自编程功能。
;--------------------------------------------------------------------
SubFlashSelfPrg:
MOV PFS,#NO_ERR ;清除闪存状态寄存器
MOV WDTE,#0ACH ;清除并启动看门狗定时器
HALT ;开始自编程功能
MOV A,PFS
CMP A,#NO_ERR
RET
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -