ha-ddjkts3x.asm
来自「其中有一个读写算法,不麻烦多指教 我用时调试通过了的,如有需要者是一个好东东哟」· 汇编 代码 · 共 534 行
ASM
534 行
BIT_SDA BIT P1.0
BIT_SCL BIT P1.1
BIT_WP BIT P1.4
;*********************************************
;=========================================
;读24C256存储器子程序
;=========================================
READ_EPROM:
NOP
NOP
SETB P2.2
CLR REN
MOV SLA,#0A4H ;0A4是第一个FM256的写地址
MOV SUBAH, #00H
MOV SUBAL, #01H
MOV RG_232L, #01H
MOV RG_232H, #00H
clr bit_eprom1
LJMP READ_SENDNB
READ_EPROM1:
jb p2.1, read_eprom10
LCALL DELAY15MS
read_eprom10:
MOV SLA, #0A8H
MOV SUBAH, #00H
MOV SUBAL, #00H
MOV RG_232L, #00H
MOV RG_232H, #00H
READ_SENDNB:
MOV A,SLA
LCALL EP_START
LCALL WRBYTE
LCALL CACK
JNB ACK,RNBRESTART0
MOV A,SUBAH
LCALL WRBYTE
LCALL CACK
JNB ACK,RNBRESTART0
MOV A,SUBAL
LCALL WRBYTE
LCALL CACK
JNB ACK,RNBRESTART0
MOV A, SLA
SETB ACC.0
LCALL EP_START
LCALL WRBYTE ;
LCALL CACK
JNB ACK,RNBRESTART0
ljmp readnb
RNBRESTART0:
ljmp RNBRESTART
READNB:
LCALL RDBYTE
MOV A,R2
MOV SBUF,A
HERE2:
JNB TI,HERE2
CLR TI
clr P2.5
INC RG_232L
inc rg_sjzh
inc rg_zq_jsq
MOV A,RG_232L
CJNE A,#00H,RR_AGAIN
INC RG_232H
MOV A, RG_232H
CJNE A,#7fH,RR_AGAIN
JB BIT_EPROM1, SEND_OK
SETB BIT_EPROM1
LJMP READ_EPROM1
RR_AGAIN:
mov a, rg_sjzh
cjne a, #10h, rr_again_a
mov rg_sjzh, #00h
mov a, rg_read_g1
jnz rr_again_a4
jb bit_jsbz, rr_again_a3
mov a, rg_read_g2
jz rr_again_a0
dec rg_read_g1
setb bit_jsbz
ljmp rr_again_a
rr_again_a4:
dec rg_read_g1
ljmp rr_again_a
rr_again_a3:
mov a, rg_read_g2
jz rr_again_a0
dec rg_read_g2
ljmp rr_again_a
rr_again_a0:
mov a, rg_read_g3
jz send_ok
dec rg_read_g1
dec rg_read_g3
ljmp rr_again_a
rr_again_a:
mov a, rg_zq_jsq
cjne a, #80h, rr_again_a1
mov rg_zq_jsq, #00h
CLR TI
LCALL MACK
ljmp rr_again_a2
rr_again_a1:
CLR TI
ljmp rr_again_a2
rr_again_a2:
LJMP READNB
SEND_OK:
clr bit_jsbz
CLR BIT_EPROM1
LCALL MNACK
LCALL STOP
MOV A, #01H
MOV R0, #SUBAL_B
MOV @R0, A
CLR A
MOV R0, #SUBAH_B
MOV @R0, A
MOV SLA, #0A4H
CLR p1.4
LCALL WRITE_RA
SETB p1.4
OUTREADNBYTE:
mov rg_zq_jsq, #00h
RET
RNBRESTART:
LCALL STOP
SETB BIT_ZSJBAD
LJMP OUTREADNBYTE
;==========================================
;启动I2C总线子程序
;==========================================
EP_START:
SETB SDA
NOP
SETB SCL ;起始条件建立时间大于4.7us
NOP
NOP
NOP
NOP
NOP
CLR SDA
NOP ;起始条件锁定时大于4us
NOP
NOP
NOP
NOP
CLR SCL ;钳住总线,准备发数据
NOP
RET
;***************************************
;结束总线子程序
;***************************************
STOP:
CLR SDA
NOP
SETB SCL ;发送结束条件的时钟信号
NOP ;结束总线时间大于4us
NOP
NOP
NOP
NOP
SETB SDA ;结束总线
NOP ;保证一个终止信号和起始信号的空闲时间大于4.7us
NOP
NOP
NOP
RET
;*************************************
;发送应答信号子程序
;*************************************
MACK:
CLR SDA ;将SDA置0
NOP
NOP
SETB SCL
NOP ;保持数据时间,即SCL为高时间大于4.7us
NOP
NOP
NOP
NOP
CLR SCL
NOP
NOP
RET
;*************************************
;发送非应答信号
;*************************************
MNACK:
SETB SDA ;将SDA置1
NOP
NOP
SETB SCL
NOP
NOP ;保持数据时间,即SCL为高时间大于4.7us
NOP
NOP
NOP
CLR SCL
NOP
NOP
RET
;*********************************
; 检查应答位子程序
;*********************************
CACK:
SETB SDA
NOP
NOP
SETB SCL
CLR ACK
NOP
NOP
MOV C,SDA
JC CEND
SETB ACK ;判断应答位
CEND:
NOP
CLR SCL
NOP
RET
;***********************************
;发送字节子程序
;***********************************
WRBYTE:
MOV R7,#08H
WLP:
RLC A ;取数据位
JC WR1
SJMP WR00 ;判断数据位
WLP1:
DJNZ R7,WLP
NOP
RET
WR1:
SETB SDA ;发送1
NOP
NOP
SETB SCL
NOP
NOP
NOP
NOP
NOP
CLR SCL
SJMP WLP1
WR00:
CLR SDA ;发送0
NOP
SETB SCL
NOP
NOP
NOP
NOP
NOP
CLR SCL
SJMP WLP1
;***********************************
;读取字节子程序
;***********************************
RDBYTE: MOV R7,#08H
RLP: SETB SDA
NOP
SETB SCL ;时钟线为高,接收数据位
NOP
NOP
MOV C,SDA ;读取数据位
MOV A,R2
CLR SCL ;将SCL拉低,时间大于4.7us
RLC A ;进行数据位的处理
MOV R2,A
NOP
NOP
NOP
DJNZ R7,RLP ;未够8位,再来一次
RET
;==============================================
;写24C256子程序
;==============================================
WRITENR_SP:
LJMP READ_RAAG
READ_RAAGEND:
LJMP QUIT_SPADD
READ_RAAG:
MOV R7, #03H
READ_RAAG1:
MOV A, R7
JZ READ_RAAGEND
DEC R7
LCALL READ_RA ;调用读记录指针子程序
MOV R1, #SUBAH_B
MOV A, SUBAH
MOV @R1, A
INC R1
MOV A, SUBAL
MOV @R1, A
LCALL READ_RA ;调用读记录指针子程序
MOV R1, #SUBAH_B
MOV A,@R1
XRL A,SUBAH
JNZ READ_RAAG1 ;两次所读记录指针高8位不等则重读
MOV R1, #SUBAL_B
MOV A, @R1
XRL A,SUBAL
JNZ READ_RAAG1 ;两次所读记录指针低8位不等则重读
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
READ_RAAG2:
MOV A,SUBAL
CJNE A,#00H,W_AGAIN ;低位未满,还可记录
MOV A,SUBAH
CJNE A,#7FH,W_AGAIN ;高位未满,还可记录
MOV R1, #SUB_SLA
MOV A, @R1
GOOD3:
CJNE A, #0A8H, GOOD4
LJMP GOOD5
GOOD4:
CJNE A, #0A9H, GOOD2
LJMP GOOD5
GOOD2:
SETB BIT_EPROM
MOV SUBAH, #00H
MOV SUBAL, #00H
LJMP W_AGAIN
GOOD5:
CLR BIT_EPROM
MOV SUBAH, #00H
MOV SUBAL, #01H
LJMP W_AGAIN
W_AGAIN1:
MOV SLA, #0A8H
LJMP W_AGAIN0
W_AGAIN:
JB BIT_EPROM, W_AGAIN1
MOV SLA,#0A4H ;
W_AGAIN0:
LCALL WRITE1BYTE ;写入1字节
clr p2.5
MOV A,SUBAL
CLR C ;
ADD A,#01H ;记录指针加1
MOV SUBAL,A
JZ H_ADD1 ;若低位未能加满,则不做处理
LJMP NC_SUBAH ;
H_ADD1:
INC SUBAH ;若低位已加满,产生进位,高位加1
mov a, subah
cjne a, #7fh, nc_subah
jb bit_eprom, good5
SETB BIT_EPROM
MOV SUBAH, #00H
MOV SUBAL, #00H
NC_SUBAH:
INC R0 ;指向下一个字节
DJNZ R5,W_AGAIN ;未写完1条记录
LJMP R_AP
R_AP:
MOV R5, #03H
MOV R1, #SUBAH_B
MOV A, SUBAH
MOV @R1, A
INC R1
MOV A, SUBAL
MOV @R1, A
WRITE_ADD:
NOP
LCALL WRITE_RA ;调用写记录指针子程序
LCALL READ_RA ;调用读记录指针子程序
MOV R1, #SUBAH_B
MOV A, @R1
XRL A,SUBAH
JNZ RE_SP ;高位不等,重存地址
MOV R1, #SUBAL_B
MOV A, @R1
XRL A,SUBAL ;
JNZ RE_SP ;低位不等,重存地址
SETB BIT_EPADDR
LJMP QUIT_SPADD ;高低位都相等,地址正确,退出写记录子程序
RE_SP:
MOV A, R5
JZ QUIT_SPADD
DEC R5
LJMP WRITE_ADD
QUIT_SPADD:
RET
;========================================================
;读记录指针子程序
READ_RA:
MOV R4,#03H ;只读取3字节
MOV R1,#SUBL ;R1 IS POINTOR OF ADDRESS_H8
MOV SUBAL,#0F1H
MOV SUBAH,#7FH
LCALL READNBYTE_fm ;READ 09H
MOV R1, #SUBL
MOV A, @R1
MOV SUBAL, A
INC R1
MOV A, @R1
MOV SUBAH, A
RET
;====================================================
;写记录指针子程序
WRITE_RA:
MOV SUBAL,#0F1H
MOV SUBAH,#7FH
MOV R0, #SUBAL_B
MOV A, @R0
MOV WSB_fm, A ;
LCALL WRITE1BYTE_fm ;回存低8位
MOV SUBAL,#0F2H
MOV SUBAH,#7FH
MOV R0, #SUBAH_B
MOV A, @R0
MOV WSB_fm, A
LCALL WRITE1BYTE_fm ;回存高8位
MOV SUBAL,#0F3H
MOV SUBAH, #7FH
MOV WSB_FM, SLA
LCALL WRITE1BYTE_fm ;回存器件地址
RET
;=====================================================
;读记录指针子程序
READNBYTE_fm:
MOV SLA,#0A4H
MOV A,SLA
LCALL EP_START ;START SIGNAL
LCALL WRBYTE ;SEND SLAVE ADDRESS
LCALL CACK ;CHECK ACK SIGNAL
JNB ACK,R1RESTART_fm
MOV A,SUBAH ;SEND WORD ADDRESS OF
LCALL WRBYTE
LCALL CACK
JNB ACK,R1RESTART_fm
MOV A,SUBAL ;SEND WORD ADDRESS OF
LCALL WRBYTE
LCALL CACK
JNB ACK,R1RESTART_fm
MOV SLA,#0A5H ;SEND READ ADDRESS OF
MOV A,SLA ;
LCALL EP_START
LCALL WRBYTE ;SEND SLAVE ADDRESS
LCALL CACK ;CHECK ACK SIGNAL
JNB ACK,R1RESTART_fm
REALREAD_fm:
LCALL RDBYTE
MOV A,R2
MOV @R1,A
DJNZ R4,RfmAGAIN
LCALL STOP
READ_FM:
LJMP OUTREADNBYTE_fm
RfmAGAIN:
INC R1
LCALL MACK
LJMP REALREAD_fm
OUTREADNBYTE_fm:
NOP
RET
R1RESTART_fm:
LCALL STOP
LJMP OUTREADNBYTE_fm
;=======================================================================
WRITE1BYTE:
MOV A,SLA ;第一片CSI24WC64
LCALL EP_START ;START SIGNAL
LCALL WRBYTE ;SEND SLAVE ADDRESS
LCALL CACK ;CHECK ACK SIGNAL
JNB ACK,WRNBESTART
MOV A,SUBAH
LCALL WRBYTE
LCALL CACK
JNB ACK,WRNBESTART
MOV A,SUBAL
LCALL WRBYTE
LCALL CACK
JNB ACK,WRNBESTART
WRITENB:
MOV A,@R0 ;2003.11.6
LCALL WRBYTE
LCALL CACK
JNB ACK,WRNBESTART
LCALL STOP
OUTWRITENBYTE:
NOP
RET
WRNBESTART:
LCALL STOP
LJMP OUTWRITENBYTE
;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
WRITE1BYTE_fm:
MOV A,#0A4H ;FMC256
LCALL EP_START ;START SIGNAL
LCALL WRBYTE ;SEND SLAVE ADDRESS
LCALL CACK ;CHECK ACK SIGNAL
JNB ACK,WRNBESTART_fm
MOV A,SUBAH
LCALL WRBYTE
LCALL CACK
JNB ACK,WRNBESTART_fm
MOV A,SUBAL
LCALL WRBYTE
LCALL CACK
JNB ACK,WRNBESTART_fm
WRITENB_fm:
MOV A,WSB_fm ;2003.11.6
LCALL WRBYTE
LCALL CACK
JNB ACK,WRNBESTART_fm
LCALL STOP
OUTWRITENBYTE_fm:
NOP
RET
WRNBESTART_fm:
LCALL STOP
LJMP OUTWRITENBYTE_fm
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?