📄 serial-eeprom-example.asm
字号:
;a 93CS46 serial EEPROM connected to port 1
;when done accessing, cs and di should be left low
;and sk should be left high. pe and pre should be
;left low, but that really isn't as important
;when data is output on the do pin, di must be low
cs bit p1.0 ;0x90 ; p1.0 - CS - Chip Select
sk bit p1.1 ;0x91 ; p1.1 - SK - Clock
di bit p1.2 ;0x92 ; p1.2 - DI - Data Input
do bit p1.3 ;0x93 ; p1.3 - DO - Data Output
pe bit p1.4 ;0x94 ; p1.4 - PE - Program Enable
pre bit p1.5 ;0x95 ; p1.5 - PRE - Protect Reg. En.
;********************************************************
; some initial setup
;********************************************************
stack equ 30h
baud_const equ 253 ;19200 baud w/ 11.0592 MHz cyrstal
setb pe
setb pre
clr di
setb do
clr cs
setb sk
;********************************************************
; The user interface
;********************************************************
main:
mov dptr, #menu_mesg
lcall pstr
sjmp main_loop
menu_mesg: db 13,10
db " r = read eeprom",13,10
db " e = edit eeprom memory",13,10
db 13,10,0
main_loop:
lcall cin
cjne a, #'r', main2
mov dptr, #readmesg
lcall pstr
ljmp readit
readmesg: db "read eeprom",13,10,0
main2: cjne a, #'e', main3
mov dptr, #editmesg
lcall pstr
ljmp editit
editmesg: db "edit eeprom memory",13,10,0
main3:
sjmp main_loop
readit:
mov r0, #0
readback:
mov a, r0
anl a, #00000111b
jnz readbk2
lcall newline
mov a, r0
lcall phex
mov a, #':'
lcall cout
mov a, #' '
lcall cout
readbk2:
lcall read
mov a, r2
lcall phex
mov a, r3
lcall phex
mov a, #' '
lcall cout
inc r0
cjne r0, #64, readback
lcall newline
lcall wen
lcall pren
mov r0, #0
lcall prwrite
lcall wds
ljmp main_loop
editit:
mov dptr, #locmesg
lcall pstr
lcall ghex8
anl a, #00111111b
push acc
lcall newline
mov dptr, #valmesg
lcall pstr
lcall ghex16
mov a, r3
push acc
mov a, r2
push acc
lcall newline
lcall wen ;turn on write enable mode
lcall pren ;enable the protect register
lcall prclear ;turn off write protection
pop acc
mov r3, a
pop acc
mov r2, a
pop acc
mov r0, a
lcall write ;write test two bytes
lcall wds
mov dptr, #wrote1
lcall pstr
mov a, r2
lcall phex
mov a, r3
lcall phex
mov dptr, #wrote2
lcall pstr
mov a, r0
lcall phex
lcall newline
ljmp main_loop
wrote1: db "wrote ", 0
wrote2: db " to ",0
locmesg: db "Word location (0-63): ",0
valmesg: db "16 bit value to write: ",0
;********************************************************
; built-in UART subroutines
;********************************************************
cin: jnb ri, cin
clr ri
mov a, sbuf
ret
cout: jnb ti, cout
mov sbuf, a
clr ti
ret
newline:push acc
mov a, #13
acall cout
mov a, #10
acall cout
pop acc
ret
phex:
phex8:
push acc
swap a
anl a, #15
add a, #246
jnc phex_b
add a, #7
phex_b: add a, #58
acall cout
pop acc
phex1: push acc
anl a, #15
add a, #246
jnc phex_c
add a, #7
phex_c: add a, #58
acall cout
pop acc
ret
space:
mov a, #' '
acall cout
ret
PSTR: ;print string
PUSH ACC
PSTR1: CLR A
MOVC A,@A+DPTR
JZ PSTR2
mov c, acc.7
anl a, #01111111b
acall cout
Jc pstr2
inc dptr
SJMP PSTR1
PSTR2: POP ACC
RET
;carry set if esc pressed
;psw.5 set if return pressed w/ no input
ghex16:
mov r2, #0 ;start out with 0
mov r3, #0
mov r4, #4 ;number of digits left
clr psw.5
ghex16c:
lcall cin
lcall upper
cjne a, #27, ghex16d
setb c ;handle esc key
ret
ghex16d:cjne a, #8, ghex16f
sjmp ghex16k
ghex16f:cjne a, #127, ghex16g ;handle backspace
ghex16k:cjne r4, #4, ghex16e ;have they entered anything yet?
sjmp ghex16c
ghex16e:lcall cout
acall ghex16y
inc r4
sjmp ghex16c
ghex16g:cjne a, #13, ghex16i ;return key
cjne r4, #4, ghex16h
setb psw.5
ghex16h:clr c
ret
ghex16i:mov r5, a ;keep copy of original keystroke
acall asc2hex
jc ghex16c
xch a, r5
lcall cout
mov a, r5
push acc
acall ghex16x
pop acc
add a, r2
mov r2, a
clr a
addc a, r3
mov r3, a
djnz r4, ghex16c
clr c
ret
ghex16x: ;multiply r3-r2 by 16 (shift left by 4)
mov a, r3
swap a
anl a, #11110000b
mov r3, a
mov a, r2
swap a
anl a, #00001111b
orl a, r3
mov r3, a
mov a, r2
swap a
anl a, #11110000b
mov r2, a
ret
ghex16y: ;divide r3-r2 by 16 (shift right by 4)
mov a, r2
swap a
anl a, #00001111b
mov r2, a
mov a, r3
swap a
anl a, #11110000b
orl a, r2
mov r2, a
mov a, r3
swap a
anl a, #00001111b
mov r3, a
ret
asc2hex: ;carry set if invalid input
clr c
push b
subb a, #'0'
mov b, a
subb a, #10
jc a2h1
mov a, b
subb a, #7
mov b, a
a2h1: mov a, b
clr c
anl a, #11110000b ;just in case
jz a2h2
setb c
a2h2: mov a, b
pop b
ret
;get 2 digit hex number from serial port
; c = set if ESC pressed, clear otherwise
; psw.5 = set if return w/ no input, clear otherwise
ghex:
ghex8: clr psw.5
ghex8c:
acall cin ;get first digit
acall upper
cjne a, #27, ghex8f
ghex8d: setb c
clr a
ret
ghex8f: cjne a, #13, ghex8h
setb psw.5
clr c
clr a
ret
ghex8h: mov r2, a
acall asc2hex
jc ghex8c
xch a, r2 ;r2 will hold hex value of 1st digit
acall cout
ghex8j:
acall cin ;get second digit
acall upper
cjne a, #27, ghex8k
sjmp ghex8d
ghex8k: cjne a, #13, ghex8m
mov a, r2
clr c
ret
ghex8m: cjne a, #8, ghex8p
ghex8n: acall cout
sjmp ghex8c
ghex8p: cjne a, #21, ghex8q
sjmp ghex8n
ghex8q: mov r3, a
acall asc2hex
jc ghex8j
xch a, r3
acall cout
mov a, r2
swap a
orl a, r3
clr c
ret
upper: ;converts the ascii code in Acc to uppercase, if it is lowercase
push acc
clr c
subb a, #97
jc upper2 ;is it a lowercase character
subb a, #26
jnc upper2
pop acc
add a, #224 ;convert to uppercase
ret
upper2: pop acc ;don't change anything
ret
poweron:
MOV SP, #stack
clr psw.3
clr psw.4
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -