;============================================================================
; ************************* Fiel =
AT93CXX.ASM ******************************
; 模块包含: READ(读), WRITE(写), WRAL(片写), ERASE(擦除), ERAL(片擦除),
; EWEN(擦写允许), EWDS(擦写禁止).
; 此模块适用于:
AT93C46/56/57/66 EEPROM 芯片, 8位(ORG=0)或16位(ORG=1)的读、写、
; 擦除等操作。
; 8位或16操作,只需置标志位SIZE为"0"或为"1"和设置NADDR的位即可,非常方便实用。
; 此程序模块已通过硬件仿真调试。
;============================================================================
;
; 93C46 93C56 93C57 93C66
;----------------------------------------------------------------------------
; Data bits: 8 16 8 16 8 16 8 16
; Address bits: 7 6 9 8 8 7 9 8
;----------------------------------------------------------------------------
NADDR EQU 7 ; 8-bit data,地址为7位
;NADDR EQU 6 ; 16-bit data,地址为6位
SIZE EQU F0 ; 0 = 8-bit data, 1 = 16-bit data 标志位
DATA_LO EQU 2AH ; 数据低字节
DATA_HI EQU 2BH ; 数据高字节
ADDR_LO EQU 2CH ; 地址低字节
ADDR_HI EQU 2DH ; 地址高字节
DATA01 EQU 30H ;数据缓存区首址
CS BIT P1.0 ;
AT93Cxx 片选端
SK BIT P1.1 ; 时钟信号输入端
DI BIT P1.2 ; 串行数据输入端
DO BIT P1.3 ; 串行数据输出端
DSEG
AT 20H
ORG 60H ; stack origin
STACK: DS 20H ; stack depth
CSEG
ORG 0000H ;
JMP ON_RESET
ORG 0003H
reti
ORG 000BH
reti
ORG 0013H
reti
ORG 001BH
reti
ORG 0023H
reti
ORG 0080H
USING 0 ;选择工作寄存器0
ON_RESET:
MOV SP, #(STACK-1)
CLR CS ; LOW
CLR SK ; LOW
SETB DI ; HIGH
SETB DO ; HIGH
CLR SIZE ; SPECIFY 8-BIT DATA
; SETB SIZE ; SPECIFY 16-BIT DATA
JB SIZE,DATA16 ;SIZE=1时,为16-bit操作
AJMP DATA8
;==========================================================
; 8-bit Byte (SIZE/ORG=0) 程序操作演示
DATA8:
CALL Byte_read ;读出数据,以便观察
CALL EWEN ;擦写允许
MOV ADDR_LO, #0 ; 地址
MOV DATA_LO, #33H ; 数据
CALL WRITE ; 指定地址写
CALL Byte_read
CALL ERAL ;片擦除 (全部单元置"1")
CALL Byte_read
; 8-bit 片写,将芯存储器全部写入55H的数据
; CALL EWDS ; 擦写禁止
MOV DATA_LO, #55H ; 片写数据(片写之前最好片擦除)
CALL WRAL ; 片写
AJMP DATA8
;==========================================================
;==========================================================
; 16-bit Word (SIZE/ORG=1) 程序操作演示
DATA16:
CALL Word_read ;读8个单元数据,观察
CALL EWEN ;擦写允许
CALL ERAL ;片擦除 (全部单元置"1")
CALL Word_read
MOV ADDR_LO, #0 ; 向指定地址写数据
MOV DATA_LO, #55H ; DATA,数据低字节
MOV DATA_HI, #0AAH ; DATA,数据高字节
CALL WRITE ; 指定地址写
CALL Word_read
; 将芯片存储器全部写入0AAH(高)和55H(低)的数据
MOV DATA_LO, #55H ; DATA
MOV DATA_HI, #0AAH ; DATA
CALL WRAL ;
CALL Word_read
; CALL EWDS ; 擦写禁止
; 将指定单元的内容擦除(置为"1")
MOV ADDR_LO, #0 ;
CALL ERASE ; 将指定单元(00H 01H)擦为"1"
AJMP DATA16
;==========================================================
;读 Read (byte if SIZE/ORG=0, word if SIZE/ORG=1).
Byte_read:
MOV R0,#DATA01 ;缓存区首址
MOV ADDR_HI,#0
MOV ADDR_LO,#0 ;指向
AT93CXX首址
MOV R7,#8 ;字节数
READ01:
CALL READ
MOV A,DATA_LO
MOV @R0,A
INC R0
INC ADDR_LO
DJNZ R7,READ01
RET
;==========================================================
;读 Read ( word if SIZE/ORG=1).低地址为低字节单元,高地址为高字节单元
Word_read:
MOV R0,#DATA01 ;缓存区首址
MOV ADDR_LO,#0
MOV R7,#8 ;字节数
WORD01:
CALL READ ;读数据
MOV A,DATA_LO ;低字节内容
MOV @R0,A
INC R0
MOV A,DATA_HI ;高字节内容
MOV @R0,A
INC R0
INC ADDR_LO
DJNZ R7,WORD01
RET
;----------------------------------------------------------
;==========================================================
;名称: 读指令(READ指令)
;功能: 从指定的地址单元中把数据读出
;----------------------------------------------------------
READ:
SETB CS ;片选置1
MOV DPL, #110B ;起始位和操作码"110"
MOV B, #3
CALL OUTDATA
MOV DPL,ADDR_LO ;低字节地址
MOV DPH,ADDR_HI ;高字节地址
MOV B,#NADDR ;地址位数(8-bit data,NADDR=7)
CALL OUTDATA ;输出读/写单元地址
CALL INDATA
CLR CS
RET
;==========================================================
;名称: 写指令(WRITE 指令)
;功能: 将数据写入到指定的地址单元中
;----------------------------------------------------------
WRITE:
SETB CS ;
MOV DPL, #101B ;起始位和操作码"101B"
MOV B, #3 ;位数
CALL OUTDATA ;输出数据
MOV DPL, ADDR_LO
MOV DPH, ADDR_HI
MOV B, #NADDR
CALL OUTDATA
MOV DPL, DATA_LO
JB SIZE, EE61 ;SIZE=0时,8bit; SIZE=1时,16bit;
MOV B, #8
JMP EE62
EE61:
MOV DPH, DATA_HI
MOV B, #16
EE62:
CALL OUTDATA
CLR CS
CALL STATUS ; 延时10ms
RET
;==========================================================
;名称: 片写指令(WRAL 指令)
;功能: 将命令中指定的数据写入整个存贮器阵列
;----------------------------------------------------------
WRAL:
SETB CS ;片选置1,选中芯片
MOV DPTR, #(10001B SHL (NADDR-2))
MOV B, #(NADDR+3)
CALL OUTDATA
MOV DPL, DATA_LO
JB SIZE, EE71 ; SIZE=0时,8bit; SIZE=1时,16bit;
MOV B, #8
JMP EE72
EE71:
MOV DPH, DATA_HI
MOV B, #16
EE72:
CALL OUTDATA
CLR CS
CALL STATUS ; 延时10ms
RET
;==========================================================
;名称: 地址擦指令(ERASE 指令)
;功能: 将指定地址中所有数据位都为置为"1"
;----------------------------------------------------------
ERASE:
SETB CS
MOV DPTR, #111B ;擦除指令操作码"111B"
MOV B, #3
CALL OUTDATA
MOV DPL, ADDR_LO ;地址低位
MOV DPH, ADDR_HI ;地址高位
MOV B, #NADDR ;
CALL OUTDATA
CLR CS
CALL STATUS ; 延时10ms
RET
;==========================================================
;名称: 片擦指令(ERAL 指令) ,
;功能: 将整个存储器阵列置为"1"
;----------------------------------------------------------
ERAL:
SETB CS
MOV DPTR, #(10010B SHL (NADDR-2)) ;左移
; ERAL指令 操作码和地址为: 10010B
MOV B, #(NADDR+3)
CALL OUTDATA
CLR CS
CALL STATUS ; 延时子程序
RET
;==========================================================
;名称: 擦/写允许(EWEN 指令)
;功能:
AT93CXX在上电复位后,芯片处于擦/写不允许状态,
; EWEN 指令将芯片置为可编程状态,即可擦/写
;----------------------------------------------------------
EWEN:
SETB CS
MOV DPTR, #(10011B SHL (NADDR-2)) ;将10011B向左移((NADDR-2)位
; EWEN 指令: 操作码的地址为: 10011B
MOV B, #(NADDR+3)
CALL OUTDATA
CLR CS
RET
;==========================================================
;名称: 擦/写禁止(EWDS 指令)
;功能: 使用该指令可对写入的数据进行保护,操作步骤与擦/写允许指令相同.
;----------------------------------------------------------
EWDS:
SETB CS
MOV DPTR, #(10000B SHL (NADDR-2))
MOV B, #(NADDR+3)
CALL OUTDATA
CLR CS
RET
;==========================================================
;延时子程序
;----------------------------------------------------------
STATUS:
PUSH B
SETB DO ; FLOAT PIN
SETB CS
MOV B, #220 ; 220 * 50 us = 11 ms
EE40:
PUSH B ; 2 us
MOV B, #22 ; 2 us
DJNZ B, $ ; 2 us * 22
POP B ; 2 us
JB DO, EE41
DJNZ B, EE40
SETB C
JMP EE42
EE41:
CLR C
EE42:
CLR CS
POP B
RET
;==========================================================
INDATA:
SETB DO
CALL SHIN
JNB SIZE, EE21 ; SIZE=0时,8bit; SIZE=1时,16bit
MOV DATA_HI, A ; SAVE HIGH BYTE
; SIZE=1时,16bit
CALL SHIN
EE21: ; SIZE=0时,8bit
MOV DATA_LO, A ; SAVE LOW BYTE
RET
;==========================================================
;读一个字节子程序, 读回的数据在A中
;----------------------------------------------------------
SHIN:
PUSH B
CLR SK
MOV B,#8
EE30:
SETB SK
NOP
MOV C,DO
RLC A
CLR SK
DJNZ B,EE30
POP B
RET
;==========================================================
;向
AT93CXX 写入地址
;----------------------------------------------------------
OUTDATA:
PUSH B
MOV A,B
CLR C
SUBB A,#8
JC EE6
JZ EE5
MOV B,A
CLR C
SUBB A,#8
JC EE2
JNZ EE9
MOV A,DPH
JMP EE4
EE2:
PUSH B
MOV A,DPH
EE3:
RR A
DJNZ B,EE3
POP B
EE4:
CALL SHOUT
MOV B,#8
EE5:
MOV A, DPL
JMP EE8
EE6:
PUSH B
MOV A,DPL
EE7:
RR A
DJNZ B,EE7
POP B
EE8:
CALL SHOUT
EE9:
SETB DO
POP B
RET
;==========================================================
; 写一个字节子程序
; 入口: 写入数据须事先存入A中.
;----------------------------------------------------------
SHOUT:
EE50:
CLR SK
RLC A
MOV DI,C
NOP ; DELAY MIN 400 ns
SETB SK
DJNZ B,EE50
CLR SK
RET
;==========================================================
;==========================================================
END