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

📄 i2c24xx.asm

📁 I2C程序
💻 ASM
字号:
;=============================================================================
;软件模拟I2C总线对24XX01/02/04/08/16/32/64系列串行EEPROM进行读写程序
;说明:24XX01的页操作缓冲区是8字节,24XX02/04/08/16的页操作缓冲区是16字节
;     24XX32/64的页操作缓冲区是32字节
;=============================================================================
SCL			BIT		P1.0		;24系列串行EEPROM的时序控制端
SDA			BIT		P1.1		;24系列串行EEPROM的数据控制端
WP			BIT		P1.2		;24系列串行EEPROM的数据写操作使能控制端
;
EEPROM_ACK_LABL		BIT		MAIN_LABL0.0	;24系列串行EEPROM写应答标志位,“0”表示正确应答
RCV_RUN_LABL		BIT		MAIN_LABL0.1	;24系列串行EEPROM读请求标志位,“0”表示允许读数据
I2C_24XX_TYPE_LABL	BIT		MAIN_LABL0.2	;24系列串行EEPROM的器件类型标志位,“0”表示为24XX01/02/04/08/16,“1”表示为24XX32/64
;
I2C_24XX_SLAVE_ADDR	EQU		10100000B	;24系列串行EEPROM的器件从设备当前地址
;
;=============================================================================
; 延时子程序
;=============================================================================
DELAY5US:	MOV	R5,#3
		DJNZ	R5,$
		RET
;=============================================================================
;发送I2C起始位程序
;=============================================================================
START_I2C:	SETB	SDA				;发送起始条件的数据信号
		NOP
		SETB	SCL				;发送起始条件的时钟信号
		CALL	DELAY5US
		CLR	SDA				;发送起始信号
		CALL	DELAY5US
		CLR	SCL				;钳住I2C总线准备发送或接收数据
		RET
;=============================================================================
;发送I2C停止位程序
;=============================================================================
STOP_I2C:	CLR	SDA				;发送停止条件的数据信号
		NOP
		SETB	SCL				;发送停止条件的时钟信号
		CALL	DELAY5US
		SETB	SDA				;发送I2C总线停止信号
		CALL	DELAY5US
		RET
;
;=============================================================================
;发送一个字节数据或地址给被控器(24XX01/02/04/08/16/32/64系列串行EEPROM)程序
;入口:待发送的数据在ACC中(被控制器的地址当前已指定)
;出口:标志位EEPROM_ACK_LABL=0表示发送数据正常,EEPROM_ACK_LABL=1表示发送数据失败、被控器无应答或损坏
;=============================================================================
SENT_BYTE:	MOV	R7,#08H				;要传送的数据长度为8位
SENT_BYTE_01:	RLC	A				;要发送的数据左移,发送位入C
		JC	SENT_BYTE_02			;发送位为“1”转发送数据位“1”
		CLR	SDA				;发送数据位“0”
		JMP	SENT_BYTE_03			;转发送数据位
SENT_BYTE_02:	SETB	SDA				;发送数据位“1”
		NOP
SENT_BYTE_03:	NOP
		SETB	SCL				;置时钟线为高通知被控器开始接收数据位
		CALL	DELAY5US
		CLR	SCL				;钳住总线准备接收下一个数据位
		DJNZ	R7,SENT_BYTE_01			;8位没发送完继续发送
		CLR	EEPROM_ACK_LABL			;预先清发送数据状态标志
		MOV	R6,#6
SENT_BYTE_04:	NOP
		NOP
		SETB	SDA				;8位发送完后释放数据线准备收应答位
		NOP
		NOP
		SETB	SCL				;开始接收应答信号
		NOP
		NOP
		JNB	SDA, SENT_BYTE_END		;判断是否接收到应答信号正常转SENT_BYTE_END
		DJNZ	R6,SENT_BYTE_04
		SETB	EEPROM_ACK_LABL			;未收到应答置位错误标志
SENT_BYTE_END:	NOP
		CLR	SCL				;发送结束钳住总线准备下一步发送或接收数据或进行其它处理
		RET
;
;=============================================================================
;从被控制器(24XX01/02/04/08/16/32/64系列串行EEPROM)读取一个字节数据程序
;入口:RCV_RUN_LABL为是否允许后续再次读取数据标志位(被控制器的地址当前已指定)
;出口:读取的数据存放在ACC中
;=============================================================================
RCV_BYTE:	SETB	SDA				;置数据线为输入方式
		MOV	R7,#08H				;要传送的数据长度为8位
RCV_BYTE_01:	NOP
		CLR	SCL				;置时钟线为低准备接收数据位
		CALL	DELAY5US
		SETB	SCL				;置时钟线为高使数据线上数据有效
		CALL	DELAY5US
		CLR	C				;准备将接收的数据位放入ACC中
		JNB	SDA,RCV_BYTE_02			;读数据位若为“0”则置C=0并转RCV_BYTE_02接收数据位
		SETB	C				;读数据位若为“1”则置C=1
RCV_BYTE_02:	RLC	A				;接收的数据位放入ACC中
		NOP
		NOP
		DJNZ	R7,RCV_BYTE_01			;8位没收完继续接收
		CLR	SCL				;8位接收完置时钟线和数据线为低准备发送应答或非应答信号
		NOP
		NOP
		NOP
		CLR	SDA
		JNB	RCV_RUN_LABL,RCV_BYTE_03	;判断是否需要继续接收字节数据若需要则转RCV_BYTE_03发送应答位
		SETB	SDA				;发送非应答信号
RCV_BYTE_03:	NOP					;以下程序发送应答位
		NOP
		SETB	SCL				;置时钟线为高使应答位有效
		CALL	DELAY5US
		CLR	SCL				;清时钟线钳住I2C总线以便继续接收字接数据或发送停止条件
		CLR	RCV_RUN_LABL			;清接收非应答标志
		NOP
		NOP
		CLR	SDA
		RET
;
;=============================================================================
;向被控制器(24XX01/02/04/08/16/32/64系列串行EEPROM)写入多个字节数据程序
;入口:DPTR为待写入的数据的首地址,R0为待写入数据的存储缓存区首地址,R2为待写入数据的字节数,
;     I2C_24XX_TYPE_LABL为当前24系列串行EEPROM的器件类型,“0”表示为24XX01/02/04/08/16,“1”表示为24XX32/64
;出口:数据写入正常,标志位EEPROM_ACK_LABL=0;否则EEPROM_ACK_LABL=1
;说明:24XX01的页操作缓冲区是8字节,24XX02/04/08/16的页操作缓冲区是16字节
;     24XX32/64的页操作缓冲区是32字节
;     一次此操作过程只能对本页内地址进行数据的写入且字节数不能超过该器件页缓冲区的字节数。
;=============================================================================
WR_24XX_DATA:	CLR	WP				;写数据使能允许
		CALL	START_I2C			;发送I2C 总线起始条件
		JB	I2C_24XX_TYPE_LABL,WR_24XX_DATA_01;判断当前24系列串行EEPROM的器件类型,“0”表示为24XX01/02/04/08/16,“1”表示为24XX32/64
		MOV	A,DPH				;待写入数据的高位地址
		ANL	A,#0FH				;屏蔽高位地址中的无效数据
		CLR	C				;确定写操作命令标志
		RLC	A
		ORL	A,#I2C_24XX_SLAVE_ADDR		;被控器总线地址,带写入数据的高位地址及写命令
		CALL	SENT_BYTE			;发送被控器总线地址及数据高位地址及命令
		JB	EEPROM_ACK_LABL,WR_24XX_DATA_END
		SJMP	WR_24XX_DATA_02
WR_24XX_DATA_01:MOV	A,#I2C_24XX_SLAVE_ADDR		;被控器总线地址
		CLR	C				;确定写操作命令标志
		MOV	ACC.0,C				;确定被控器总线地址及写命令
		CALL	SENT_BYTE			;发送被控器总线地址及命令
		JB	EEPROM_ACK_LABL,WR_24XX_DATA_END
		MOV	A,DPH				;待写入数据的高位地址
		CALL	SENT_BYTE			;发送待写入数据的高位地址
		JB	EEPROM_ACK_LABL,WR_24XX_DATA_END
WR_24XX_DATA_02:MOV	A,DPL				;待写入的数据首字节地址低位字节
		CALL	SENT_BYTE			;发送待写入数据的低位地址
		JB	EEPROM_ACK_LABL,WR_24XX_DATA_END
WR_24XX_DATA_03:MOV	A,@R0
		CALL	SENT_BYTE			;发送待写入的数据字节
		JB	EEPROM_ACK_LABL,WR_24XX_DATA_END
		INC	R0
		DJNZ	R2,WR_24XX_DATA_03
		CALL	STOP_I2C			;发送I2C 总线停止条件
		MOV	R7,#28H				;延时10ms,等待数据写完
		MOV	R6,#00H
WR_24XX_DATA_04:DJNZ	R6,WR_24XX_DATA_04
		DJNZ	R7,WR_24XX_DATA_04
WR_24XX_DATA_END:
		SETB	WP				;写数据使能禁止
		RET
;
;=============================================================================
;从被控制器(24XX01/02/04/08/16/32/64系列串行EEPROM)中读取多个字节数据程序
;入口:DPTR为预读取的数据的首地址,R2为需要读取数据的字节数 
;     I2C_24XX_TYPE_LABL为当前24系列串行EEPROM的器件类型,“0”表示为24XX01/02/04/08/16,“1”表示为24XX32/64
;出口:R0为读取的数据存储缓存区
;说明:24XX01的页操作缓冲区是8字节,24XX02/04/08/16的页操作缓冲区是16字节
;     24XX32/64的页操作缓冲区是32字节
;     一次此操作过程只能对本页内地址进行数据的读取且字节数不能超过该器件页缓冲区的字节数。
;=============================================================================
RD_24XX_DATA:	CALL	START_I2C			;发送I2C 总线起始条件
		JB	I2C_24XX_TYPE_LABL,RD_24XX_DATA_01;判断当前24系列串行EEPROM的器件类型,“0”表示为24XX01/02/04/08/16,“1”表示为24XX32/64
		MOV	A,DPH				;待写入数据的高位地址
		ANL	A,#0FH				;屏蔽高位地址中的无效数据
		CLR	C				;确定写操作命令标志
		RLC	A	
		ORL	A,#I2C_24XX_SLAVE_ADDR		;被控器总线地址,带写入数据的高位地址及写命令
		CALL	SENT_BYTE			;发送被控器总线地址及数据高位地址及命令
		JB	EEPROM_ACK_LABL,RD_24XX_DATA_END
		SJMP	RD_24XX_DATA_02
RD_24XX_DATA_01:MOV	A,#I2C_24XX_SLAVE_ADDR		;被控器总线地址
		CLR	C				;确定写操作命令标志
		MOV	ACC.0,C				;确定被控器总线地址及写命令
		CALL	SENT_BYTE			;发送被控器总线地址及命令
		JB	EEPROM_ACK_LABL,RD_24XX_DATA_END
		MOV	A,DPH				;待写入数据的高位地址
		CALL	SENT_BYTE			;发送待写入数据的高位地址
		JB	EEPROM_ACK_LABL,RD_24XX_DATA_END
RD_24XX_DATA_02:MOV	A,DPL				;待写入的数据首字节地址低位字节
		CALL	SENT_BYTE			;发送地址低位字节
		JB	EEPROM_ACK_LABL,RD_24XX_DATA_END
		CALL	START_I2C			;重复发送I2C 总线起始条件
		JB	I2C_24XX_TYPE_LABL,RD_24XX_DATA_03;判断当前24系列串行EEPROM的器件类型,“0”表示为24XX01/02/04/08/16,“1”表示为24XX32/64
		MOV	A,DPH				;待读取数据的高位地址
		ANL	A,#0FH				;屏蔽高位地址中的无效数据
		SETB	C				;确定读操作命令标志
		RLC	A
		ORL	A,#I2C_24XX_SLAVE_ADDR		;被控器总线地址,带写入数据的高位地址及写命令
		SJMP	RD_24XX_DATA_04
RD_24XX_DATA_03:MOV	A,#I2C_24XX_SLAVE_ADDR		;被控器总线地址
		SETB	C				;确定读操作命令标志
		MOV	ACC.0,C				;确定被控器总线地址及写命令
RD_24XX_DATA_04:CALL	SENT_BYTE			;发送被控器总线地址及命令
		JB	EEPROM_ACK_LABL,RD_24XX_DATA_END
		CLR	RCV_RUN_LABL			;预设置允许后续继续接收数据
RD_24XX_DATA_05:DJNZ	R2,RD_24XX_DATA_06
		SETB	RCV_RUN_LABL			;设置禁止后续继续接收数据
		CALL	RCV_BYTE			;接收数据	
		MOV	@R0,A
		INC	R0
		CALL	STOP_I2C			;发送I2C 总线停止条件
		SJMP	RD_24XX_DATA_END
RD_24XX_DATA_06:CALL	RCV_BYTE			;接收数据	
		MOV	@R0,A
		INC	R0
		SJMP	RD_24XX_DATA_05
RD_24XX_DATA_END:
		RET
;





⌨️ 快捷键说明

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