⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2c.asm

📁 这是利用CYPRESS CY7C63723汇编语言编写的读写AT24C512的程序
💻 ASM
字号:
	INCLUDE	"637XX.INC"

SET_WP:					EQU	02H     
CLR_WP:					EQU	FDH     
SET_SCL:				EQU	01H					;P10
CLR_SCL:				EQU	FEH     
SET_SDA:				EQU	01H					;P00
CLR_SDA:				EQU	FEH     

;**********************************************************
;FUNCTION:	I2CSTART
;INTPUT:	
;OUTPUT:	
;USEAGE:	
;CALL:		
;**********************************************************		
I2CSTART:
	CALL	SDA_HIGH
	CALL	SCL_HIGH
	CALL	SDA_LOW
	CALL	SCL_LOW
	RET

;**********************************************************
;FUNCTION:	I2CSTOP
;INTPUT:	
;OUTPUT:	
;USEAGE:	
;CALL:		
;**********************************************************		
I2CSTOP:
	CALL	SDA_LOW
	CALL	SCL_HIGH
	CALL	SDA_HIGH 
	CALL	DELAY_60
	CALL	SCL_LOW 
	RET   

;**********************************************************
;FUNCTION:	WAITACK
;INTPUT:	
;OUTPUT:	ACC=OK: ACK正确; ACC=NOK: ACK错误	
;USEAGE:	REC_TEMP	
;CALL:		
;**********************************************************		
WAITACK:
	CALL	SDA_HIGH
	CALL	SCL_HIGH
	IORD	PORT0		
	AND		A,SET_SDA
	JZ		ACK_OK
	MOV		A,NOK
	MOV		[REC_TEMP],A
	JMP		WAITACK_RET
ACK_OK:
	MOV		A,OK
	MOV		[REC_TEMP],A
WAITACK_RET:		
	CALL	SCL_LOW
	MOV		A,[REC_TEMP]
	OR		A,0
	RET

;**********************************************************
;FUNCTION:	SENDACK
;INTPUT:	
;OUTPUT:	
;USEAGE:	
;CALL:		
;**********************************************************	
SENDACK:
	CALL	SDA_LOW
	CALL	SCL_HIGH
	CALL	SCL_LOW
	CALL	SDA_HIGH	
	RET


;**********************************************************
;FUNCTION:	SENDNAK
;INTPUT:	
;OUTPUT:	
;USEAGE:	
;CALL:		
;**********************************************************	
SENDNAK:
	CALL	SDA_HIGH
	CALL	SCL_HIGH
	CALL	SCL_LOW
	CALL	SDA_LOW	
	RET

;**********************************************************
;FUNCTION:	I2CSENDBYTE
;INTPUT:	ACC:要发送的数据
;OUTPUT:	
;USEAGE:	R5
;CALL:		
;**********************************************************		
I2CSENDBYTE:
	RRC								;先往右移动一位,后续循环处理方便
	MOV		[SEND_TEMP],A
	MOV		A,8
	MOV		[R5],A
	
I2CSENDBYTE_LOOP:
	MOV		A,[SEND_TEMP]
	RLC		
	MOV		[SEND_TEMP],A
	AND		A,80H
	JNZ		SEND_HIGH_BIT
	CALL	SDA_LOW
	CALL	SCL_HIGH
	CALL	SCL_LOW	
	JMP		SEND_NXT_BIT

SEND_HIGH_BIT:
	CALL	SDA_HIGH
	CALL	SCL_HIGH
	CALL	SCL_LOW	

SEND_NXT_BIT:
	DEC		[R5]
	JNZ		I2CSENDBYTE_LOOP
	RET

;**********************************************************
;FUNCTION:	I2CRECEIVEBYTE,I2C读一个字节
;INTPUT:	none
;OUTPUT:	ACC	
;USEAGE:	
;CALL:		
;**********************************************************	
I2CRECEIVEBYTE:
	MOV		A,0
	MOV		[REC_TEMP],A
	CALL	SDA_HIGH
	MOV		A,8
	MOV		[R5],A

I2CRECEIVEBYTE_LOOP:	
	CALL	SCL_HIGH
	IORD	PORT0	
	AND		A,SET_SDA
	JNZ		REC_HIGH_BIT
	MOV		A,[REC_TEMP]
	ASL
	AND		A,FEH
	JMP		REC1
	
REC_HIGH_BIT:
	MOV		A,[REC_TEMP]
	ASL
	OR		A,1

REC1:
	MOV		[REC_TEMP],A
	CALL	SCL_LOW
	DEC		[R5]
	JNZ		I2CRECEIVEBYTE_LOOP
	MOV		A,[REC_TEMP]
	RET	

;**********************************************************			
INITI2C:
	CALL	WP_HIGH
	CALL	SCL_LOW					
	CALL	SDA_LOW
	RET

;**********************************************************
;FUNCTION:	READEEPROM:从EEPROM读若干个字节;
;INTPUT:	DPTR:	EEPROM 地址
;			R0: 	数据在RAM中的地址
;			R2:  	长度		
;OUTPUT:	NONE;  读出的数据在R0指定的RAM中
;USEAGE:	R0--R2,R5,REC_TEMP
;CALL:		

;FUNCTION:	READEEPROM_1BYTE:从EEPROM读1个字节
;INTPUT:	DPTR:	EEPROM 地址
;OUTPUT:	NONE;  读出的数据在ACC中
;USEAGE:	R1--R2,R5,REC_TEMP
;CALL:		
;**********************************************************		     
N_BYTE_FLAG:			EQU		FFH
READEEPROM:
	MOV		A,N_BYTE_FLAG
	MOV		[R1],A							;R1保存读若干字节的标志
	JMP		READEEPROM_ALL
READEEPROM_1BYTE:
	MOV		A,0
	MOV		[R1],A	
READEEPROM_ALL:	
	CALL	I2CSTART	
	MOV		A,A0H						
	CALL	I2CSENDBYTE						;SEND DEVICE ADDRESS
	CALL	WAITACK
	JNZ		I2CREADERROR

	MOV		A,[DPH]
	CALL	I2CSENDBYTE						;SEND ADDRESS HIGH
	CALL	WAITACK
	JNZ		I2CREADERROR
	MOV		A,[DPL]
	CALL	I2CSENDBYTE						;SEND ADDRESS LOW
	CALL	WAITACK
	JNZ		I2CREADERROR		

	CALL	I2CSTART
	MOV		A,A1H							;READ BIT=1									
	CALL	I2CSENDBYTE						;SEND DEVICE ADDRESS	
	CALL	WAITACK
	JNZ		I2CREADERROR

	MOV		A,[R1]
	CMP		A,N_BYTE_FLAG
	JNZ		READ_1BYTE

	MOV		X,[R0]
READEEPROM_LOOP:	
	CALL	I2CRECEIVEBYTE
	MOV		[X+0],A
	INC		X
	DEC		[R2]
	JZ		READEEPROM_NAK
	CALL	SENDACK
	JMP		READEEPROM_LOOP
	
READ_1BYTE:
	CALL	I2CRECEIVEBYTE
	MOV		[R2],A							;R2保存单字节读的结果
	
READEEPROM_NAK:
	CALL	SENDNAK
	CALL	I2CSTOP
	MOV		A,[R2]
	JMP		READEEPROM_RET
	
I2CREADERROR:
	CALL	I2CSTOP
READEEPROM_RET:
	RET

;**********************************************************
;FUNCTION:	WRITEEEPROM 往EEPROM中写若干字节
;INTPUT:	DPHDPL:EEPROM 地址
;			R0:  数据在RAM中的地址
;			R2:  长度		
;OUTPUT:	ACC=0:OK; ACC<>0: ERROR
;USEAGE:	R0--R3,R5,使用4级堆栈, R0不改变
;CALL:	
;NOTICE:	不能跨页,长度不能超过(32:AT24C64; 64: AT24C128/256; 128: AT24C512)
;			若写出错,堆栈不平衡	
;**********************************************************	        
WRITEEEPROM:
WR_N_BYTE:
	MOV		A,[DPH]
	PUSH	A
	MOV		A,[DPL]
	PUSH	A
	MOV		A,[R0]
	PUSH	A								;入口参数全部进栈
	MOV		A,[R2]
	PUSH	A

	CALL	WP_LOW
WRITEEEPROM_LOOP:	
	CALL	I2CSTART
	MOV		A,A0H								
	CALL	I2CSENDBYTE						;SEND DEVICE ADDRESS
	CALL	WAITACK
	JNZ		I2CWRITEERROR0
	MOV		A,[DPH]
	CALL	I2CSENDBYTE						;SEND ADDRESS HIGH
	CALL	WAITACK
	JNZ		I2CWRITEERROR0
	MOV		A,[DPL]
	CALL	I2CSENDBYTE						;SEND ADDRESS LOW
	CALL	WAITACK	
	JNZ		I2CWRITEERROR0

	MOV		A,[DPL]
	AND		A,(PAGESIZE-1)
	MOV		[R1],A
	MOV		A,PAGESIZE
	SUB		A,[R1]							
	MOV		[R1],A							;R1=当前地址到当前页末的字节数
	
	MOV		A,[R2]
	SUB		A,[R1]
	JC		LAST_PAGE						;剩余总长度<当前地址到当前页末的字节数,
	MOV		[R2],A							;R2=后若干页的长度,R1=当前页要写的字节数
	JMP		WRITE_PAGE

LAST_PAGE:
	MOV		A,[R2]
	MOV		[R1],A							;R1=当前页要写的长度
	MOV		A,0
	MOV		[R2],A							;R2(剩余长度)=0		

WRITE_PAGE:
	MOV		X,[R0]
WRITE_PAGE_LOOP:
	MOV		A,[X+0]
	CALL	I2CSENDBYTE						;写第一页
	CALL	WAITACK
	JNZ		I2CWRITEERROR0
	INC		X
	INC		[R0]							;RAM地址+1
	CALL	INC_DPTR						;EEPROM地址+1
	DEC		[R1]
	JNZ		WRITE_PAGE_LOOP	
	CALL	I2CSTOP

POLL_ACK:		
	CALL	I2CSTART						;查询是否写完
	MOV		A,A0H
	CALL	I2CSENDBYTE
	CALL	WAITACK
	JNZ		POLL_ACK

	MOV		A,[R2]
	OR		A,0
	JNZ		WRITEEEPROM_LOOP	

	POP		A
	MOV		[R3],A
	POP		A
	MOV		[R0],A
	POP		A
	MOV		[DPL],A
	POP		A
	MOV		[DPH],A

COMP_LOOP:	
	CALL	READEEPROM_1BYTE				;写后读  USE R1,R2
	MOV		X,[R0]
	CMP		A,[X+0]
	JNZ		I2CWRITEERROR
	INC		[R0]							;RAM的地址+1
	CALL	INC_DPTR						;EEPROM的地址+1
	DEC		[R3]
	JNZ		COMP_LOOP

	CALL	WP_HIGH
	MOV		A,OK
	JMP		WRITEEEPROM_RET

I2CWRITEERROR0:
	POP		A
	POP		A
	POP		A
	POP		A								;退栈,使栈平衡

I2CWRITEERROR:
	CALL	I2CSTOP
	CALL	WP_HIGH
	CALL	DELY_10MS
	MOV		A,NOK
WRITEEEPROM_RET:
	OR		A,0	
	RET	
	
;**********************************************************
;FUNCTION:	SCL_HIGH
;INTPUT:	
;OUTPUT:	
;USEAGE:	
;CALL:		
;**********************************************************		
SCL_HIGH:					;10		TIME=72/12=6US; T=12US
	IORD	PORT1			;5
	OR		A,SET_SCL		;4
	IOWR 	PORT1			;5
	IOWR	WATCHDOG		;5    此条指令必须执行,否则可能复位	
	RET						;8

;**********************************************************
;FUNCTION:	SCL_LOW
;INTPUT:	
;OUTPUT:	
;USEAGE:	
;CALL:		
;**********************************************************
SCL_LOW:
	IORD	PORT1			
	AND		A,CLR_SCL
	IOWR 	PORT1	
	IOWR	WATCHDOG		; [5]		
	RET			

;**********************************************************
;FUNCTION:	SDA_HIGH
;INTPUT:	
;OUTPUT:	
;USEAGE:	
;CALL:		
;**********************************************************	
SDA_HIGH:
	IORD	PORT0			
	OR		A,SET_SDA
	IOWR 	PORT0	
	IOWR	WATCHDOG		; [5]		
	RET		

;**********************************************************
;FUNCTION:	SDA_LOW
;INTPUT:	
;OUTPUT:	
;USEAGE:	
;CALL:		
;**********************************************************		
SDA_LOW:
	IORD	PORT0			
	AND		A,CLR_SDA
	IOWR 	PORT0
	IOWR	WATCHDOG		; [5]		
	RET					

;**********************************************************
;FUNCTION:	WP_HIGH
;INTPUT:	
;OUTPUT:	
;USEAGE:	
;CALL:		
;**********************************************************	
WP_HIGH:
	IORD	PORT1			
	OR		A,SET_WP
	IOWR 	PORT1
	CALL	DELAY_60	
	RET		

;**********************************************************
;FUNCTION:	SDA_LOW
;INTPUT:	
;OUTPUT:	
;USEAGE:	
;CALL:		
;**********************************************************		
WP_LOW:
	IORD	PORT1			
	AND		A,CLR_WP
	IOWR 	PORT1
	CALL	DELAY_60	
	RET		
	
;**********************************************************
;FUNCTION:	DPTR+1
;INTPUT:	NONE
;OUTPUT:	
;USEAGE:	
;CALL:		
;**********************************************************		
INC_DPTR:
	INC		[DPL]
	JNZ		INC_DPTR_RET
	INC		[DPH]
INC_DPTR_RET:
	RET				

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -