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

📄 eeprom.asm

📁 K0S模拟EEPROM多字节数据分组方法例程
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;/*********************** (C) COPYRIGHT 2008 GETSOON************************
;* File Name					: EEPROM_EMULATE.asm
;* Author							:
;* Date First Issued	: 12/03/2008          
;* Description				: eeprom_emulate_78k0s
;**************************************************************************/
PUBLIC _EEPROMWrite 
PUBLIC _EEPROMRead 

;--------------------------------------------------------------------- 
;--------------------------------------------------------------------- 
;OPTBYTE CSEG  AT  0081H 
; 
; DB 11111111B  ; 保护字节: Bit(6-2) = 11111B 
;      ; 保护区域: None 
;      ; 非保护区域: Blocks 0~ 15 
;      ; 确定要释放block的保护  
;      ; 设定为EEPROM仿真 
;--------------------------------------------------------------------- 
;  用于EEPROM的Block号                           用户设定  
;--------------------------------------------------------------------- 
EP_TBL CSEG 
tEEPROM_BLOCK:	;例) 当使用block 14 和 15 
  DB  12      	;    (设定的block必须是连续的。 
  DB  13      	;    设定的block不要与程序区重叠。) 
 
tEEPROM_BLOCK_END: 
;--------------------------------------------------------------------- 
;  用于EEPROM的Block的地址                     用户设定 
;--------------------------------------------------------------------- 
tEEPROM_BLK_ADR: 
  DW 00C00H   ;例) block 14的起始地址 
  DW  00D00H      ;    block 15的起始地址 
  DW  00DFFH+1    ;    block 15 + 1的结束地址 
 
;--------------------------------------------------------------------- 
;  将要被写入的数据block号                      用户设定 
;--------------------------------------------------------------------- 
DATA_NO_MAX EQU  3    ;例) 当使用8个数据block 编号为 0 到 7 
 
 
;--------------------------------------------------------------------- 
;  其它 EQU 设定 
;--------------------------------------------------------------------- 
CMD_INTERNAL_VERIFY EQU  (00000001B)  ;内部校验 (比较MRG01和MRG11) 
CMD_INTERNAL_VERIFY2 EQU  (00000010B)  ;内部校验2 (比较MRG01和MRG12) 
CMD_BLOCK_ERASE EQU (00000011B) ;Block擦除 
CMD_BLANK_CHECK EQU (00000100B) ;Blank检验 
CMD_BYTE_WRITE   EQU  (00000101B)  ;1字节写入 
 
NO_ERR     EQU  (00000000B)  ;未发现错误 
ERR_FPRERR   EQU (00000001B) ;PFCMD写入错误 
ERR_VCERR   EQU (00000010B) ;擦除/写入/内部校验错误 
ERR_WEPRERR   EQU  (00000100B) ;保护错误 
 
FALSE   EQU (0FFH)  ;异常 
TRUE   EQU (00H)  ;正常 
 
DATATOP     EQU (2)   ;数据写入起始地址 
LENG     EQU (4)   ;数据长度 
 
EEPROM_BLOCK_NO  EQU  (tEEPROM_BLOCK_END - tEEPROM_BLOCK)  ;需要用到的block编号 
 
WRITE_RETRY  EQU (10)  ;为写入进行的重新计数 
ERASE_RETRY  EQU (20)  ;为擦除进行的重新计数 
 
;--------------------------------------------------------------------- 
 
 
;--------------------------------------------------------------------- 
; RAM设定 
;--------------------------------------------------------------------- 
EP_RAM1 DSEG  saddr 
 b8DataBuf:  DS 8 ;内部应用的缓存RAM 
 
 d2Address:  DS 2 ;用于存储EEPROM 读取/写入地址的RAM 
 dBlockTBLNo:  DS 1 ;在EEPROM 过程中用于存储正在被使用block的RAM  
       ;读取/写入处理 
 
  ci:   DS 1 ;通用目的循环计数器 
 
 d2SrcAdr:  DS 2 ;在EEPROM数据查询过程中用于存储地址RAM 
 d2EndAdr:  DS 2 ;在EEPROM数据查询过程中用于存储block的结束地址的RAM 
       ; 
 d2DataAdr:  DS 2 ;在EEPROM数据查询过程中用于保护最新数据地址的RAM 
       ; 
 
 d2SetAdr:  DS 2 ;在模块转换过程中用于存储数据传送目的地址的RAM 
       ; 
 d2GetAdr:  DS 2 ;在模块转换过程中用于存储数据传送源地址的RAM 
       ; 
 d2ReadGet:  DS 2 ;用于存储数据传送源地址的RAM 
 d2ReadSet:  DS 2 ;用于存储数据传送目的地址的RAM 
 dNextBlockTBLNo: DS 1 ;用于存储转换目的的RAM 
 
  cj:   DS 1 ; 通用目的循环计数器 
 
 d2MaskStatus:  DS 2 ;用于存储掩模数据的RAM 
 
EEPROM_PROG CSEG 
;------------------------------------------------------------------- 
; 函数名称: _EEPROMRead (用户访问功能) 
; 输入:   X = 读取数据号 
; DE = 读取数据存储地址 
; 输出:   C = 正常完成(正确:00H)或是异常终止(错误:FFH) 
; 摘要:   将指定的数据从EEPROM中读取到存储地址。 
; 1. 寻找用做EEPROM的block。 
; 2. 在合法的blocks中寻找最新的数据地址。 
; 3. 在寻找到的地址中读取最新的数据。 
;------------------------------------------------------------------- 
_EEPROMRead: 

 PUSH HL 
 PUSH DE 
 PUSH AX 
 MOVW AX,SP 
 MOVW HL,AX 
 
 CALL !EEPROMUseBlockSearch  ;寻找当前正在用于EEPROM的block  
 MOV A,C 
 MOV dBlockTBLNo,A 
 CMP A,#FALSE 
  BZ $EP_READ_FL   ;异常终止 
 
 MOV E,A 
 MOV A,[HL] 
 MOV X,A 
  CALL !EEPROMDataSearch  ;获取制定数据编号的最新数据地址  
       ; 
 MOVW AX,BC 
  CMPW AX,#0000H   ;异常终止 
 BZ $EP_READ_FL 
 
  INCW AX    ;设定数据编号被忽略的数据地址  
       ; 
 MOVW DE,AX 
 MOVW d2Address,AX 
 MOV A,[DE] 
 MOV C,A 
 MOV A,[HL+2] 
 XCH A,X 
 MOV A,[HL+3] 
 MOVW DE,AX 
 INCW AX 
 MOV [HL+3],A 
 XCH A,X 
 MOV [HL+2],A 
 MOV A,C 
  MOV [DE],A    ;读取最新数据地址+1的数据1 
   MOVW AX,d2Address 
 INCW AX 
 MOVW DE,AX 
 MOV A,[DE] 
 MOV C,A 
 MOV A,[HL+2] 
 XCH A,X 
 MOV A,[HL+3] 
 MOVW DE,AX 
 MOV A,C 
  MOV [DE],A    ;读取最新数据地址+3的数据2 
 
 MOV C,#TRUE     ;返回值=正常完成(正确) 
 BR EP_READ_E 
 
EP_READ_FL: 
  MOV C,#FALSE   ;返回值=异常终止(错误) 
 
EP_READ_E: 
 POP AX 
 POP DE 
 POP HL 
 RET 
 
;------------------------------------------------------------------- 
; 函数名称: _EEPROMWrite (用户访问功能) 
; 输入: X = 写入数据编号 
; DE = 写入数据存储地址 
; 输出: C = 正常完成(正确:00H)或是异常完成(错误:FFH) 
; 摘要:  把制定编号的数据从存储地址写入EEPROM。 
; 1. 寻找用做EEPROM的block。 
; 2. 如果没有有效地blocks,则把第一个指定的block设定为有效。 
; 3. 寻找用于允许写入到有效block的地址。 
; 4. 如果有效的block已满或者不能被写入,操作将转移到下一个block。 
; 5. 创建写入数据。 
; 6. 写入到有效的blocks。 
;------------------------------------------------------------------- 
_EEPROMWrite: 
 PUSH HL 
 PUSH DE 
 PUSH AX 
 MOVW AX,SP 
 MOVW HL,AX 
 
 CALL !SelfFlashModeOn  ;设定flash模式 
 
 CALL !EEPROMUseBlockSearch  ;寻找被用作EEPROM的block 
 MOV A,C 
  MOV dBlockTBLNo,A   ;设定使用的block号 
  CMP A,#FALSE   ;检验block号 
  BNZ $EP_WRITE_3   ;正常完成 
 
 CALL !EEPROMBlockInit  ;如果当前没有应用的blocks,被指定为EEPROM的最小编号的block 
       ;被设定为有效的block 
       ; 
 MOV A,C 
  MOV dBlockTBLNo,A   ;设定使用的block号 
  CMP A,#FALSE   ;检验block号 
  BNZ $EP_WRITE_2   ;正常完成 
 
  BR EP_WRITE_FL   ;异常终止 
 
EP_WRITE_2: 
 MOV A,dBlockTBLNo 
 CALL !BlockAddressGet 
 ADDW AX,#DATATOP 
  MOVW d2Address,AX   ;计算block写入的起始地址(数据起始地址+偏移量(合法/非法标志)) 
       ; 
 BR EP_WRITE_4 

EP_WRITE_3:
 MOV A,dBlockTBLNo 
 MOV X,#00H 
 XCH A,X 
 CALL !_EEPROMWriteTopSearch 
 MOVW AX,BC 
  MOVW d2Address,AX   ;设定当前使用的表的写入地址 
 
EP_WRITE_4: 
 MOV A,dBlockTBLNo 
 INC A 
 CALL !BlockAddressGet  ;重新查找当前使用的block的结束地址 
 XCH A,X 
 SUB A,d2Address 
 XCH A,X 
 SUBC A,d2Address+1 
 CMPW AX,#LENG 
  BNC $EP_WRITE_6   ;比较可写入的字节编号和写入数据的长度(数据编号,分隔符,等)  
       ; 
 
 MOV A,dBlockTBLNo 
 MOV X,#0 
 XCH A,X 
 CALL !EEPROMUseBlockChange  ;当数据不能被写入时改变使用的block 
 MOV A,C 
  MOV dBlockTBLNo,A   ;确定使用的block号 
 
  CMP A,#FALSE   ;检验block号 
  BZ $EP_WRITE_FL   ;异常终止 
 
EP_WRITE_5: 
 MOV A,dBlockTBLNo 
 MOV X,#00H 
 XCH A,X 
 CALL !_EEPROMWriteTopSearch 
 MOVW AX,BC 
  MOVW d2Address,AX   ;设定当前使用的表的写入地址 
 
EP_WRITE_6: 
  MOV A,[HL]    ;给写入数据缓存的EEPROM设定数据编号 
 MOV b8DataBuf,A 
 
 MOV A,[HL+2] 
 XCH A,X 
 MOV A,[HL+3] 
 MOVW DE,AX 
 INCW AX 
 MOV [HL+3],A 
 XCH A,X 
 MOV [HL+2],A 
 MOV A,[DE] 
  MOV b8DataBuf+1,A   ;给写入数据缓存的EEPROM设定数据1 
 
 MOV A,[HL+2] 
 XCH A,X 
 MOV A,[HL+3] 
 MOVW DE,AX 
 MOV A,[DE] 
  MOV b8DataBuf+2,A   ;给写入数据缓存的EEPROM设定数据2 
 
 MOV A,#00H 
  MOV b8DataBuf+3,A   ; 给写入数据缓存的EEPROM设定定界符 
 
 MOVW DE,#b8DataBuf 
 MOV C,#LENG 
 MOVW AX,d2Address 
 CALL !Flash_EEPROMWrite  ;向EEPROM中写入被创建的写入数据 
 BZ $EP_WRITE_TR 
 
EP_WRITE_FL: 
 CALL !SelfFlashModeOff  ;释放flash模式 
  MOV C,#FALSE   ;返回数据 = 异常终止(错误) 
 BR EP_WRITE_E 
 
EP_WRITE_TR: 
 CALL !SelfFlashModeOff  ;释放flash模式 
 MOV C,#TRUE     ;返回数据 = 正常完成(正确) 
 
EP_WRITE_E: 
 POP AX 
 POP DE 
 POP HL 
 RET 
 
 
;------------------------------------------------------------------- 
; 函数名称: EEPROMUseBlockSearch 
; 输入:   无 
; 输出  :  C = Block表编号(00H到FEH),异常终止(错误: FFH) 
; 摘要:   寻找位于EEPROM的flash存储器中当前正在使用的block。 
;------------------------------------------------------------------- 
EEPROMUseBlockSearch: 
 PUSH HL 
 
  MOV L,#0    ;初始化循环计数器L寄存器 
EP_BSRC_T: 
 MOV A,L 
 CMP A,#EEPROM_BLOCK_NO  ;循环号 = EEPROM设定block的编号 
 BNC $EP_BSRC_FL 
 
 CALL !BlockAddressGet 
 MOVW DE,AX 
 MOV A,[DE] 
 MOV b8DataBuf,A 
 INCW DE 
 MOV A,[DE] 
 MOV b8DataBuf+1,A 
 
EP_BSRC_2: 
 MOV A,b8DataBuf 
 CMP A,#00H 
  BNZ $EP_BSRC_3   ;当有效标志 = 00, 
 
 MOV A,b8DataBuf+1 
 CMP A,#0FFH 
  BNZ $EP_BSRC_3   ;当有效标志 = FF, 
 
 MOVW AX,HL 
 MOV A,#00H 
  MOVW BC,AX    ;返回值 = 有效block编号 
 BR EP_BSRC_E 
 
EP_BSRC_3: 
 INC L 
 BR EP_BSRC_T 
 
EP_BSRC_FL: 
  MOV C,#FALSE   ;返回值 = 异常完成(没有有效的block)  
       ; 
 
EP_BSRC_E: 
 POP HL 
 RET 
 
 
;------------------------------------------------------------------- 
; 函数名称: EEPROMBlockInit 
; 输入:   无 
; 输出: C = 正常完成(正确:00H)或是异常完成(错误:FFH) 
; 摘要:   如果用于EEPROM的block都是无效的,则第一个被指定的block被 
;   设定为当前应用的(有效的)。 
;------------------------------------------------------------------- 
EEPROMBlockInit: 
 PUSH HL 

 MOV A,!tEEPROM_BLOCK  ;为EEPROM设定最小的block编号 
 CALL !SelfFlashBlockErase  ;擦除指定的block 
 MOV A,C 
 CMP A,#TRUE 
  BNZ $EP_BINI_FL   ;异常终止 
 
 MOV A,#00H 
  MOV b8DataBuf,A   ;设定block有效数据 
 
 MOVW DE,#b8DataBuf 
 MOV C,#1 
 MOV A,!tEEPROM_BLK_ADR 
 MOV X,A 
 MOV A,!tEEPROM_BLK_ADR+1 
 CALL !Flash_EEPROMWrite  ;调用EEPROM写入处理 
  BNZ $EP_BINI_FL   ;异常完成 
 
EP_BINI_TR: 
  MOV C,#TRUE    ;返回值 = 正常完成(正确) 
 BR EP_BINI_E 
 
EP_BINI_FL: 
  MOV C,#FALSE   ;返回值 = 异常终止(错误) 
 
EP_BINI_E: 
 POP HL 
 RET 
 
;------------------------------------------------------------------- 
; 函数名称: EEPROMUseBlockChange 
; 输入: X = 当前使用的block的表编号  
; (使用用户自行定义的为EEPROM设定的block编号) 
; 输出:  C = Block表编号(00H到FEH),异常终止(FFH) 
; 摘要:  如果当前使用的block已经写满了数据,该函数寻找下一个block用于写入数据。 
 
; 1. 设定下一个被使用的block。 
; 2. 擦除下一个被使用的block。 
; 3. 把最新的数据从有效的block传送到下一个block。 
; 4. 把下一个block设定为有效。 
; 5. 把当前有效的block设定为无效。 
;------------------------------------------------------------------- 
EEPROMUseBlockChange: 
 PUSH HL 
 MOVW HL,AX 
 
  MOV A,L    ;确定下一个将被使用的block 
 INC A 
 CMP A,#EEPROM_BLOCK_NO 
 BC $EP_BCHG_2 
 MOV A,#0 
EP_BCHG_2: 
 MOV dNextBlockTBLNo,A 
 
 MOV C,A 
 MOVW AX,#tEEPROM_BLOCK 
 XCH A,X 
 ADD A,C 
 XCH A,X 
 ADDC A,#0 
 MOVW DE,AX 
 MOV A,[DE] 
 CALL !SelfFlashBlockErase  ;擦除下一个被使用的block 
 MOV A,#FALSE 
 CMP A,C 
  BNZ $EP_BCHG_3   ;如果擦除异常结束, 
 BR EP_BCHG_FL 
 
EP_BCHG_3: 
 MOV A,dNextBlockTBLNo 
 CALL !BlockAddressGet 
 ADDW AX,#DATATOP 
  MOVW d2SetAdr,AX   ;设定下一个block写入的起始地址 
 
  MOV ci,#0    ;设定下一个block写入的起始地址 
EP_BCHG_T: 
 MOV A,ci 
  CMP A,#DATA_NO_MAX   ;从0到DATA_NO_MAX循环 
 BC $EP_BCHG_J 
 BR EP_BCHG_9 
 
EP_BCHG_J: 
 MOV A,L 
 MOV E,A 
 MOV A,ci 
 MOV X,A 
 CALL !EEPROMDataSearch  ;寻找最新的数据编号地址 
 MOVW AX,BC 
 MOVW d2GetAdr,AX 
 
  CMPW AX,#0000H   ;判断地址是否为除去0000H之外的其它地址(数据存在)  

⌨️ 快捷键说明

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