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 + -
显示快捷键?