;EXAM13
;93C46 16 BIT READ/WRITE DEMO 00H-3FH
EEPCLK EQU P1.0
EEPDI EQU P1.1
EEPDO EQU P1.2
EEPCS EQU P1.3
MAXBUF EQU 11
ORG 30H
StrBuff: DS 1
REGADR: DS 1
REGDAT1: DS 1
REGDAT2: DS 1
buffer: DS MAXBUF ;Command Buffer
ORG 0000H
; *** Power up delay ***
;Wait for other Device
RES: MOV R2,#40H
RES1: MOV R3,#0
RES2: DJNZ R3,RES2
DJNZ R2,RES1
;EEPROM 93C46 Initial
CLR EEPCLK
CLR EEPCS
MOV REGADR,#00H
MAIN: LCALL InitUART ;Initial UART 9600,n,8,1 no parity
MOV DPTR,#Hello
LCALL SendSROM
LCALL EPENABLE ;ENABLE EEPROM
MOV R2,#00H
LCALL EPREAD
;LCALL EEPTEST
ScanStr:
MOV R0,#buffer ;point to buffer
LCALL GetStr
MOV R0,#buffer ;load buffer Ptr
LCALL GetCmd ;found = 1...n
JZ ScanEx ; 0 = isn't Command
MOV StrBuff,A ;store result in StrBuff
;Check Command No
;Check Command 1
XRL A,#01 ;?Compare A=1
JZ Cmd1 ;switch to x
;Check Command 2
MOV A,StrBuff ;Restore
XRL A,#02 ;?Compare A=2
JZ Cmd2
;Check Command 3
MOV A,StrBuff ;Restore
XRL A,#03 ;?Compare A=3
JZ Cmd3
JMP ScanStr
ScanEx: MOV DPTR,#ErrMsg1
LCALL SendSROM
LCALL LineFeed
JMP ScanStr
;Treat Command
Cmd1: LCALL DoCmd1
LJMP ScanStr
;*** Read EEPROM Command
Cmd2: LCALL DoCmd2
LJMP ScanStr
Cmd3: LCALL EPERALL
MOV DPTR,#EraAll
LCALL SendSROM
LJMP ScanStr
LenErr: MOV DPTR,#ErrMsg3
LCALL SendSROM
RET
; ** Wroking Command1 ***
;* Write EEPROM
DoCmd1:
LCALL LineFeed
MOV R0,#buffer
LCALL Strlen
XRL A,#10
JZ DoCmd1A
LCALL LenErr
RET
DoCmd1A:
LCALL GetArg1
MOV REGADR,A
LCALL SBYTEH
LCALL GetArg2
MOV REGDAT1,A
LCALL SBYTEH
LCALL GetArg3
MOV REGDAT2,A
LCALL SBYTEH
MOV R2,REGADR
LCALL EPERASE ;ERASE
MOV R2,REGADR
MOV R3,REGDAT1
MOV R4,REGDAT2
LCALL EPWRITE ;WRITE
LCALL LineFeed
RET
; ** Wroking Command3 ***
;* Dump EEPROM 64 Byte 00H-3FH *
DoCmd2:
LCALL LineFeed
MOV R0,#buffer
LCALL Strlen
XRL A,#04h
JZ DoCmd2a
LCALL LenErr
LJMP ScanStr
DoCmd2a:
LCALL GetArg1
MOV REGADR,A
;Read EEProm
MOV R2,REGADR
LCALL EPREAD
MOV A,R3
LCALL SBYTEH
MOV A,#' '
LCALL SBYTE
MOV A,R4
LCALL SBYTEH
LCALL LineFeed
RET
;********** ATOH SUB **********
; ASCII TO HEX CONVERT
; IN = R2,R3 30H,41H
; OUT = A 0AH
; REG = A,R2
ATOH: MOV A,R2
LCALL ATOHS
SWAP A
MOV R2,A
MOV A,R3
LCALL ATOHS
ORL A,R2
RET
ATOHS: CJNE A,#'A',$+3
JC ATOHS1
ADD A,#9
ATOHS1: ANL A,#0FH
RET
;* Get Argument 1 *
;IN R2,R3
;OUT A
GetArg1:
MOV A,buffer+2
MOV R2,A
MOV A,buffer+3
MOV R3,A
LCALL ATOH
RET
;* Get Argument 2 *
;IN R2,R3
;OUT A
GetArg2:
MOV A,buffer+5
MOV R2,A
MOV A,buffer+6
MOV R3,A
LCALL ATOH
RET
;* Get Argument 3 *
;IN R2,R3
;OUT A
GetArg3:
MOV A,buffer+8
MOV R2,A
MOV A,buffer+9
MOV R3,A
LCALL ATOH
RET
;*** Get String ***
;IN R0 pointer to String Buffer
;R3 count n of Str
;
GetStr: MOV R3,#0
GetSnx: CLR A
LCALL RBYTE ;READ -> A
MOV StrBuff,A ;Restore char in StrBuff
;check end of str
XRL A,#0Dh ;Carriage Return
JZ ChkStr
MOV A,StrBuff ;Restore char in StrBuff
XRL A,#0Ah ;line feed LF
JZ ChkStr
MOV A,StrBuff ;Restore char in StrBuff
XRL A,#1Bh ;line feed LF
JZ GetESC
MOV A,StrBuff ;Restore char in StrBuff
LCALL SBYTE ;A -> Send ECho
MOV @R0,StrBuff ;store in buffer
INC R0 ;next point
INC R3 ;count str
;Test buffer full
MOV A,R3
XRL A,#MAXBUF ;Compare with MAXBUFFER
JZ Sendfull ;>= MAXBUFFER
SJMP GetSnx
ChkStr: MOV A,R3
JZ GetDis ;if len = 0
MOV @R0,#0 ;end of String
RET
GetDis:
LCALL DumpE
SJMP GetStr
GetESC:
MOV DPTR,#Abortx
LCALL SendSROM
MOV R0,#buffer ;Point to buffer
SJMP GetStr
Sendfull:
MOV DPTR,#ErrMsg2
LCALL SendSROM
MOV R0,#buffer ;Point to buffer
SJMP GetStr
; *** Get Command ***
;R0 point to Str buffer
;DPTR point to command
;R2 save
;R7 result
;return command in A
; found 1...n
; not found 0
;
;REG change = R0,R2,R7
;
GetCmd: MOV R7,#01 ;count
MOV A,R0 ;save R0->R2
MOV R2,A ;Restore Ptr
MOV DPTR,#Command1
LCALL StrCmp
JZ CmdEQU ;A=0 Equ
;If not Equ next Cmp
INC R7 ;inc result
MOV A,R2 ;get ptr
MOV R0,A ;Reload Ptr
MOV DPTR,#Command2
LCALL StrCmp
JZ CmdEQU
INC R7 ;inc result
MOV A,R2 ;get ptr
MOV R0,A ;Reload Ptr
MOV DPTR,#Command3
LCALL StrCmp
JZ CmdEQU
;not found
MOV R7,#0 ;result is NULL
CmdEQU: MOV A,R7 ;result in R7
RET
;StrCmp(@R0,DPTR);
;R0 point to Str buffer
;DPTR point to command
;reg change = R0,DPTR
;result in A 0 = Equ
; FFh = nEqu
StrCmp: CLR A
MOVC A,@A+dptr
JZ StrEq ;end of str
XRL A,@R0 ;Compare A=@R0 ?
JNZ StrNEq
INC R0 ;next char in buffer
INC dptr ;next command
JMP StrCmp
StrNEq: MOV A,#0FFh ;not equal
RET
StrEq: CLR A ;equal ret 0
RET
;* EEPTEST
EEPTEST:
MOV R2,#00H ;Address
LCALL EPERASE ;ERASE
MOV R2,#00H ;Address
MOV R3,#91H ;Data
MOV R4,#92H ;Data
LCALL EPWRITE ;WRITE
RET
;*** EEPROM READ SUB ***
;93C46 READ WORD SUBROUTINE
;IN = R2 ADDRESS (0-63)
;OUT DATA = R3,R4
;REG = A,R2,R3
EPREAD: MOV A,R2
ANL A,#00111111B ;MAKE SURE DATA=6 BIT
ORL A,#10000000B ;OPCODE
SETB EEPCS ;CS=1
SETB EEPDI ;START BIT
LCALL CLOCK
MOV R2,#8 ;OPCODE,ADDRESS
EPRD2: RLC A
MOV EEPDI,C
LCALL CLOCK
DJNZ R2,EPRD2
;Read 8 bit
MOV R2,#8 ;READ DATA (8 BIT FIRST)
EPRD4: LCALL CLOCK
MOV C,EEPDO
RLC A
DJNZ R2,EPRD4
MOV R3,A ;Save to R3
MOV R2,#8 ;READ DATA (8 BIT LAST)
EPRD5: LCALL CLOCK
MOV C,EEPDO
RLC A
DJNZ R2,EPRD5
MOV R4,A
CLR EEPCS ;CS=0
RET
CLOCK: SETB EEPCLK ;SYNC CLOCK
NOP
NOP
CLR EEPCLK
NOP
NOP
RET
;*** EPWRITE SUB ***
; 93C46 WRITE WORD SUBROUTINE
; IN = R2 ADDRESS (0-63)
; = R3,R4 DATA
; REG = A,R2
EPWRITE:
MOV A,R2
ANL A,#00111111B ;MAKE SURE DATA=6 BIT
ORL A,#01000000B ;OPCODE
SETB EEPCS ;CS=1
SETB EEPDI ;START BIT
LCALL CLOCK
;Address
MOV R2,#8 ;OPCODE,ADDRESS
EPWR2: RLC A
MOV EEPDI,C
LCALL CLOCK
DJNZ R2,EPWR2
;Data 8
MOV R2,#8 ;WRITE DATA (8 BIT FIRST)
MOV A,R3
EPWR4: RLC A
MOV EEPDI,C
LCALL CLOCK
DJNZ R2,EPWR4
MOV R2,#8 ;WRITE DATA (8 BIT LAST)
MOV A,R4 ;R4
EPWR5: RLC A
MOV EEPDI,C
LCALL CLOCK
DJNZ R2,EPWR5
CLR EEPCS ;CS=0
NOP
NOP
SETB EEPCS ;CS=1 (CHECK STATUS)
NOP
NOP
JNB EEPDO,$ ;WAIT FOR BUSY
NOP
NOP
CLR EEPCS ;CS=0
RET
;*** EPERASE SUB ***
; 93C46 ERASE WORD SUBROUTINE
; IN = R2 ADDRESS (0-63)
; REG = A,R2
EPERASE:MOV A,R2
ANL A,#00111111B ;MAKE SURE DATA=6 BIT
ORL A,#11000000B ;OPCODE
SETB EEPCS ;CS=1
SETB EEPDI ;START BIT
LCALL CLOCK
MOV R2,#8 ;OPCODE,ADDRESS
EPERA2: RLC A
MOV EEPDI,C
LCALL CLOCK
DJNZ R2,EPERA2
CLR EEPCS ;CS=0
NOP
NOP
SETB EEPCS ;CS=1 (CHECK STATUS)
NOP
NOP
JNB EEPDO,$ ;WAIT FOR BUSY
NOP
NOP
CLR EEPCS ;CS=0
RET
;*** EPERASE ALL ***
; 93C46 ERASE WORD SUBROUTINE
; IN = R2 ADDRESS (0-63)
; REG = A,R2
EPERALL:
MOV R6,#64
MOV R2,#00
MOV REGADR,#00
EPERALX:
MOV R2,REGADR
MOV R3,#0FFH
MOV R4,#0FFH
LCALL EPWRITE ;WRITE
INC REGADR
DJNZ R6,EPERALX
RET
;*** EPENABLE SUB ***
;93C46 ENABLE SUBROUTINE
;REG = A,R2
EPENABLE:
MOV A,#00110000B ;OPCODE
SETB EEPCS ;CS=1
SETB EEPDI ;START BIT
LCALL CLOCK
MOV R2,#8 ;OPCODE,ADDRESS
EPEN2: RLC A
MOV EEPDI,C
LCALL CLOCK
DJNZ R2,EPEN2
RET
; *** Initial UART ***
InitUART:
MOV SCON,#01010010B ;Set SCON Serial Control Mode 1: 8-bit UART (Timer-Based).
MOV TMOD,#00100000B ;Set Mode 2 8-bit Auto-Reload
MOV TH1,#0FDH ;Set Baud Rate 9600
SETB TR1 ;Enable Timer 1
RET
; ********** SBYTE SUB **********
;SEND BYTE
;IN = A
;REG = NO
SBYTE: JNB TI,SBYTE ;Wait For Sending done
CLR TI
MOV SBUF,A
RET
; ********** RBYTE SUB **********
;OUT = A
;REG = A
RBYTE: JNB RI,RBYTE ;Wait For Receive already
CLR RI
MOV A,SBUF
RET
; *** Send line feed ***
LineFeed:
MOV A,#0Dh
LCALL SBYTE
feed: MOV A,#0Ah
LCALL SBYTE
RET
; ********** SBYTEH SUB **********
; SEND 2 BYTE HEX FROM A
; IN = A
; REG = A,R2,R3
SBYTEH: LCALL HTOA
MOV A,R2
LCALL SBYTE
MOV A,R3
LCALL SBYTE
RET
; ********** HTOA SUB **********
; CONVERT HEX TO ASCII
; IN = A
; OUT = R2,R3
; REG = A,R2,R3
HTOA: PUSH ACC
SWAP A
LCALL HTOAS
MOV R2,A
POP ACC
LCALL HTOAS
MOV R3,A
RET
HTOAS: ANL A,#0FH
CJNE A,#0AH,$+3
JNC HTOAS1
ORL A,#30H
RET
HTOAS1: SUBB A,#9
ORL A,#40H
RET
; *** Send String in Program Memory ***
;Input DPTR
SendSROM:
CLR A
MOVC A,@A+DPTR ;load char
JZ EndStr ;yes end
LCALL SBYTE ;send 1 byte
INC DPTR ;point to next char
SJMP SendSROM ;load next char
EndStr: RET
; *** String LEN ***
;IN R0
;OUT A
Strlen: MOV R2,#0
StrLNx: MOV A,@R0
XRL A,#0
JZ StrLEX
INC R0
INC R2
SJMP StrLNx
StrLEX: MOV A,R2
RET
;*** Dump EEPROM ***
;IN REGADR ADDRESS
;
DumpE:
MOV DPTR,#Header
LCALL SendSROM
MOV REGADR,#00
MOV R2,REGADR ;Get Address from REGADR
MOV R7,#08H ;line = 8
;Header
DumpEa:
MOV R6,#08H ;Reload
MOV A,REGADR ;Send Dump Header:
LCALL SBYTEH
MOV A,#':'
LCALL SBYTE
MOV A,#' '
LCALL SBYTE
DumpE2:
MOV R2,REGADR
LCALL EPREAD ;Read to R3,R4
MOV A,R3
LCALL SBYTEH
MOV A,#' '
LCALL SBYTE
MOV A,R4
LCALL SBYTEH
MOV A,#' '
LCALL SBYTE
INC REGADR
DJNZ R6,DumpE2
LCALL LineFeed
DJNZ R7,DumpEa
LCALL LineFeed
RET
Hello: DB 0DH,"*** EEPROM 93C46 ***",0DH,0AH,00
Header: DB 0DH,"93C46 16 Bit Adress (00H-3FH)",0DH,0AH,00
ErrMsg1: DB 0Dh,0Ah,'Invalid Command',00
ErrMsg2: DB 0Dh,0Ah,'buffer full',0Dh,0Ah,00
ErrMsg3: DB 0Dh,0Ah,'Lenght Error',0Dh,0Ah,00
Abortx: DB 0Dh,0Ah,'*** Abort ***',0Dh,0Ah,00
EraAll: DB 0Dh,0Ah,'ERASE ALL',0Dh,0Ah,00
Command1: DB 'w ',00
Command2: DB 'r ',00
Command3: DB 'x',00
END