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

📄 eeprom.asm

📁 K0S模拟EEPROM多字节数据分组方法例程
💻 ASM
📖 第 1 页 / 共 2 页
字号:
       ; 
 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 + -